Используя любой метод классификации текстов, первоночально необходимо придумать способ перевода текстового документа в набор чисел. Ранее уже был рассмотрен метод на основе 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 и подходов на нейронных сетях, то можно его смело рекомендовать использовать в дополнение с другими алгоритмами для достижения максимальной точности классификации.