Doc2vec за пределами руководства - PullRequest
3 голосов
/ 25 марта 2019

До сих пор я использовал doc2vec самым простым способом с ограниченным успехом.Я могу найти похожие документы, но часто получаю много ложных срабатываний.Моя основная цель - построить алгоритм классификации для требований пользователя.Это сделано для того, чтобы помочь с анализом требований пользователей и поиском.

Я знаю, что это не достаточно большой набор данных, поэтому я хотел бы помочь с несколькими вопросами:

  1. Какможно обучить одному набору документов и построить векторы на другом?
  2. Как мне настроить модель, выбрав правильное количество измерений для векторного пространства
  3. Как создатьИерархическая кластеризация для векторов слов, нужно ли делать это с одной моделью или мне следует создавать отдельные модели классификации слов и документов?
  4. У меня нет основополагающей правды, это неконтролируемое обучение при настройке, как мне измерятькачество результата?
  5. И, наконец, есть ли рекомендуемый онлайн-ресурс, который может охватывать некоторые из вышеперечисленных вопросов.

Я однажды звонил в поезд с 100 векторами в 2000 годудокументы, каждый из которых содержит около 100 слов, каждый документ имеет 22 столбца, помеченных как ячейкой, так и строкой.

def tag_dataframe(df, selected_cols):
    tagged_cells = []
    headers = list(df.columns.values)
    for index, row in df.iterrows():
        row_tag = 'row_' + str(index)
        for col_name in headers:
            if col_name in selected_cols:
                col_tag = 'col_' + col_name
                cell_tag = 'cell_' + str(index) + '_' + col_name
                cell_val = str(row[col_name])
                if cell_val == 'nan':
                    continue
                cleaned_text = clean_str(cell_val)
                if len(cleaned_text) == 0:
                    continue
                tagged_cells.append(
                    gensim.models.doc2vec.TaggedDocument(
                        cleaned_text,
                        [row_tag, cell_tag]))
    print('tagged rows')
    return tagged_cells

def load_or_build_vocab(model_path, tagged_cells):
    if os.path.exists(model_path):
        print('Loading vocab')
        d2vm = gensim.models.Doc2Vec.load(model_path)
    else:
        print('building vocab')
        d2vm = gensim.models.Doc2Vec(
            vector_size=100,
            min_count=0,
            alpha=0.025,
            min_alpha=0.001)
        d2vm.build_vocab(tagged_cells)
        print('    built')
        d2vm.save(model_path)
    return d2vm

def load_or_train_model(model_path, d2vm, tagged_cells):
    if os.path.exists(model_path):
        print('Loading Model')
        d2vm = gensim.models.Doc2Vec.load(model_path)
    else:
        print('Training Model')
        d2vm.train(
            tagged_cells,
            total_examples=len(tagged_cells),
            epochs=100)
        print('    trained')
        d2vm.save(model_path)
    return d2vm

Что я надеюсьreach - это набор векторов документов, которые помогут найти похожие пользовательские требования из произвольного текста и иерархической кластеризации для построения навигации по существующим требованиям.

1 Ответ

2 голосов
/ 25 марта 2019

Вам следует обратиться к doc2vec- ноутбукам Jupyter, поставляемым с gensim, в каталоге docs/notebooks (или для просмотра в сети ), чтобы найти больше примеров правильного использования. Просмотр существующих ответов SO по тегу doc2vec (и, возможно, особенно мои ответы ) также может дать вам представление об общих ошибках.)

Чтобы настроить модель в неконтролируемой обстановке, вам, по сути, нужен определенный повторяющийся оценочный балл для конкретного домена. Это может потребовать прохождения всей вашей кластеризации и конечного приложения, а затем рассчитывать его успех на определенные результаты, которые он «должен» дать для созданного вручную подмножества ваших данных.

Для сравнения, если вы посмотрите на оригинальную статью «Вектор абзаца», она использовала существующие партии из 10 лучших фрагментов результатов поиска из существующей поисковой системы в качестве учебных документов, но затем оценила любую модель по тому, насколько хорошо она поставлена. фрагменты, которые были в общей топ-10 ближе друг к другу, чем к случайным третьим документам. В последующем документе «Внедрение документов с векторами абзацев» обучались статьям Википедии или документам Arxiv и настраивали их модель на основе того, насколько хорошо полученная модель помещает документы в те же предварительно отобранные категории, которые существуют в этих системах.

Вы можете использовать любые алгоритмы кластеризации для векторов для каждого документа. Вывод Doc2Vec, как документ на вектор, может стать вводом нисходящих алгоритмов. (Я не уверен, что вы имеете в виду под «отдельными моделями классификации слов и документов». Вы описали только конечные потребности на уровне документов, вам могут вообще не понадобиться векторы слов ... хотя некоторые режимы Doc2Vec создадут такие векторы.)

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

Глядя на специфику ваших данных / кода, некоторые наблюдения:

  • непонятно, какие у вас несколько столбцов, или что они должны быть отдельными документами (в отличие от объединения в один документ). Просмотр некоторых полных строк может помочь прояснить суть ваших данных.
  • это крошечный набор данных - большинство опубликованных работ Doc2Vec работают с десятками тысяч и миллионами документов. Этот алгоритм лучше всего работает с большим количеством данных.
  • оригинальная работа дала каждому документу только один тег уникального идентификатора. В то время как gensim Doc2Vec поддерживает присвоение документам нескольких тегов, как вы сделали здесь, это лучше всего считать продвинутой техникой. По сути, это уменьшает то, что можно узнать из документа, через несколько тегов, что может ослабить результаты, особенно в небольших наборах данных.
  • 10-20 эпох обучения наиболее распространены в опубликованных работах, хотя больше может быть особенно полезно для небольших наборов данных. Также лучше установить эпохи при инициализации модели, так как это значение будет также использоваться по умолчанию для будущих операций infer_vector() (если только другое значение явно не передается туда).
  • структура ваших двух методов немного странная - сохранение неподготовленной модели, но затем, возможно, обучение и перезапись ее сразу? (Или вы просто пытаетесь повторно использовать сохраненную модель со встроенным словарем для нескольких тренировочных заездов с разными данными?)
  • Word2Vec и Doc2Vec часто лучше отбрасывают редкие слова (по умолчанию min_count=5 или больше, когда это практически возможно), чем пытаться их тренировать. Слова, которые появляются только один или несколько раз, часто носят характерный характер по сравнению с «истинным» значением этого слова в большом мире. Их сохранение делает модели более крупными, медленнее обучаемыми и с большей вероятностью отражает особенности данных, чем обобщаемые шаблоны.
...