Архив метки: Doc2vec

Классификация текстов методом Doc2vec в python

Используя любой метод классификации текстов, первоночально необходимо придумать способ перевода текстового документа в набор чисел. Ранее уже был рассмотрен метод на основе TF-IDF, в этот раз рассмотрим метод DOC2VEC. Из названия сразу понятно, что метод переводит документ в вектор, причём делается это просто. Сразу приведу код:

# определим датасет
some_texts = [
   'текст номер один',
   'Текст следуюйщих под номером два',
   'третий набор слов',
   'что-то ещё для полноценного дата-сета',
   'пример текстового документа'
]

from gensim.models.doc2vec import Doc2Vec, TaggedDocument
documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(some_texts)]

model = Doc2Vec(documents, vector_size=5, workers=4, epochs=3)

Обучение, в данном примере (взятом из документации), происходит сразу при создании объекта. (Мне это показалось немного странным, после sklearn с методами fit и transform).
Некоторые основные параметры:
vector_size — какой конечный размер будет у вектора. Тонкий параметр, который придётся подбирать. Чем больше выборка и длиннее каждый документ — тем имеет смысл ставить параметр больше, порядка 100-300. Для небольших текстов и датасетов может хватить размерности 5-10.
epoch — кол-во эпох на обучении. Тоже потребует настройки, обычно 10-20

workers — сколько ядер хотите задействовать на обучении. (Узнать кол-во: from multiprocessing import cpu_count)
Стоит также отметить, что начальные веса для документов берутся случайно, и в дальнейшем происходит утряска-оптимизация весов. Поэтому после каждого обучения результирующий вектор для одного и того же документа будет разным.

Полезные методы Doc2Vec

# сохранение модели для дальнейшего использования
model.save("my_doc2vec_model")
# загрузка модели
model = Doc2Vec.load("my_doc2vec_model")
# нахождение наиболее похожего документа
vector_to_search = model.infer_vector(["ищем", "похожий", "текст"])
# три наиболее похожих
similar_documents = model.docvecs.most_similar([vector_to_search], topn=3)
for s in similar_documents:
    print(some_texts[s[0]])

И так, модель Doc2vec обучена, теперь можно любой документ перевести в вектор и обучить вашим любимым классификатором. Давайте для пример возьмем RandomForest

from sklearn.ensemble import RandomForestClassifier

clf = RandomForestClassifier()
clf.fit([model.infer_vector([x.words]) for x in documents], [1, 1, 1, 0, 0])
 
res = clf.predict([model.infer_vector(['текст', 'номер', 'три'])])
print(res)  # [1]

По своему опыту могу сказать, что doc2vec несколько капризная штука и по настоящему хорошо работать этот метод мне не удалось заставить. Особенно неприятно удивили результаты с находением наиболее похожих документов в датасете. Однако, т.к. это другой подход, отличный от классического bag of words, tf-idf а также от LDA и подходов на нейронных сетях, то можно его смело рекомендовать использовать в дополнение с другими алгоритмами для достижения максимальной точности классификации.