Используйте Gensim для оценки функций в каждом документе. Также проблема с памятью Python

Я использую GENSIM для корпуса из 50000 документов вместе со словарем, содержащим около 4000 функций. У меня также есть модель LSI, уже подготовленная для того же самого.

Теперь я хочу найти наиболее подходящие функции для каждого из добавленных документов. Чтобы найти лучшие функции в конкретном документе, я запускаю модуль сходства gensim для каждой функции во всех документах. Это дает нам оценку для каждой функции, которую мы хотим использовать позже. Но, как вы можете себе представить, это дорогостоящий процесс, поскольку нам нужно перебрать более 50 000 индексов и выполнить 4 000 итераций подобия для каждого.

Мне нужен лучший способ сделать это, так как в моей системе заканчивается 8 ГБ памяти примерно на 1000 итераций. На самом деле нет причин для увеличения памяти, поскольку я перераспределяю ее только во время итераций. Удивительно, но память начинает расти только после примерно 200 итераций.

  1. Почему проблема с памятью? Как это решить?
  2. Есть ли лучший способ найти функции с наивысшей оценкой в ​​конкретном документе (не в темах)?

Вот фрагмент кода, которому не хватает памяти:

dictionary = corpora.Dictionary.load('features-dict.dict')
corpus = corpora.MmCorpus('corpus.mm')
lsi = models.LsiModel.load('model.lsi')
corpus_lsi = lsi[corpus]
index = similarities.MatrixSimilarity(list(corpus_lsi))
newDict = dict()

for feature in dictionary.token2id.keys():
  vec_bow = dictionary.doc2bow([feature])
  vec_lsi = lsi[vec_bow]
  sims = index[vec_lsi]
  li = sorted(enumerate(sims * 100), key=lambda item: -item[1])

  for data in li:
    dict[data[0]] = (feature,data[1]) # Store feature and score for each document


# Do something with the dict created above

РЕДАКТИРОВАТЬ:

Проблема с памятью была решена с помощью профилировщика памяти. В этой петле было что-то еще, что заставило ее резко подняться.

Позвольте мне объяснить цель в деталях. Представьте, что мы имеем дело с различными рецептами (каждый рецепт — это документ), и каждый элемент в нашем словаре — это ингредиент. Найдите шесть таких рецептов ниже.

corpus = [[Olive Oil, Tomato, Brocolli, Oregano], [Garlic, Olive Oil, Bread, Cheese, Oregano], [Avocado, Beans, Cheese, Lime], [Jalepeneo, Lime, Tomato, Tortilla, Sour Cream], [Chili Sauce, Vinegar, Mushrooms, Rice], [Soy Sauce, Noodles, Brocolli, Ginger, Vinegar]]

Таких рецептов тысячи. Чего я пытаюсь добиться, так это присвоить вес от 0 до 100 каждому ингредиенту (где ингредиент с более высоким весом является наиболее важным или наиболее уникальным). Что было бы лучшим способом для достижения этого.


person zhanup    schedule 24.04.2014    source источник


Ответы (1)


Давайте разберем это:

  1. если я неправильно понял вашу цель, вы можете просто использовать левые единичные векторы из lsi.projection.u, чтобы получить свои веса:

    # create #features x #corpus 2D matrix of weights
    doc_feature_matrix = numpy.dot(lsi.projection.u, index.index.T)
    

    Строки этой матрицы должны быть «весами документов», которые вы ищете, одна строка для одной функции.

  2. вызов list() в вашем list(lsi[corpus]) делает ваш код очень неэффективным. Он в основном сериализует всю матрицу темы документа в ОЗУ. Отбросьте list() и используйте потоковую версию напрямую, она намного эффективнее использует память: index = MatrixSimilarity(lsi[corpus], num_features=lsi.num_topics).

  3. LSI обычно работает лучше, чем регулярный ввод. Рассмотрите возможность преобразования простых векторов мешков слов (= целых чисел) с помощью, например. TF-IDF или преобразование журнала энтропии перед его передачей в LSI.

person Radim    schedule 24.04.2014
comment
1. Вы правильно поняли цель (см. РЕДАКТИРОВАТЬ выше). На самом деле я хотел получить нормализованные веса от нуля до сотни, поэтому пошел по пути косинусного подобия и проигнорировал все те веса, которые меньше нуля. Я не уверен, как бы мы нормализовали doc_feature_matrix, который вы предложили выше. 2. Мой плохой. Эта часть была остатком от тестирования потокового корпуса. Удаленный. 3. Да, используется TF-IDF. Просто не упомянул в фрагменте выше. - person zhanup; 09.05.2014