Python: эффективная реализация векторов объектов - PullRequest
2 голосов
/ 13 апреля 2011

Я реализую векторы функций в виде битовых карт для документов в корпусе. У меня уже есть словарь для всего корпуса (в виде списка / набора) и список терминов в каждом документе.

Например, если словарь корпуса - ['a', 'b', 'c', 'd'], а термины в документе d1 - ['a', 'b', 'd', 'd'], вектор признаков для d1 должен быть [1, 1, 0, 2].

Чтобы сгенерировать вектор объектов, я бы перебрал словарь корпуса и проверил, есть ли каждый термин в списке терминов документа, а затем установил бит в правильной позиции в векторе объектов документа.

Какой самый эффективный способ реализовать это? Вот некоторые вещи, которые я рассмотрел:

  • Использование set сделало бы проверку членства в Vocab очень эффективной, но set s не имеет упорядочения, и биты векторов объектов должны быть в порядке отсортированного словаря корпусов.
  • Использование dict для словаря корпусов (сопоставление каждого члена словаря с произвольным значением, например 1) позволило бы выполнить итерацию по sorted(dict.keys()), чтобы я мог отслеживать индекс. Тем не менее, у меня было бы пространство на dict.values().
  • Использование sorted(list) было бы неэффективно для проверки членства.

Что бы предложил StackOverflow?

1 Ответ

2 голосов
/ 13 апреля 2011

Я думаю, что наиболее эффективный способ - циклически проходить термины каждого документа, получать положение термина в (отсортированном) корпусе и соответственно устанавливать бит.

Сортированный список терминов корпуса можно сохранитьв качестве словаря с term -> index отображением (в основном инвертированный индекс ).

Вы можете создать его так:

corpus = dict(((term, index) for index, term in enumerate(sorted(all_words))))

Для каждогодокумент, который вы должны создать список 0 как вектор объектов:

num_words = len(corpus)
fvs = [[0]*num_words for _ in docs]

Тогда построение векторов объектов будет:

for i, doc_terms in enumerate(docs):
    fv = fvs[i]
    for term in doc_terms:
        fv[corpus[term]] += 1

В заголовке нетпроверяя членство, вам просто нужно пройтись по всем условиям всех документов.


При всем этом, в зависимости от размера корпуса, вы должны взглянуть на numpy и scipy .Вероятно, у вас возникнут проблемы с памятью, и scipy предоставит специальные типы данных для разреженных матриц (вместо использования списка списков), которые могут сэкономить много памяти.
Вы можете использовать тот же подход, как показано выше, но вместо добавления чисел к элементам списка вы добавляете его к элементам матрицы (например, строки будут документами, а столбцы - терминами корпуса).

Вы также можете использовать некоторые матричные операции, предоставляемые numpy, если вы хотите применить локальные или глобальные весовые схемы.

Надеюсь, это поможет вам начать:)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...