модель классификации текста с использованием doc2vec и gensim - PullRequest
0 голосов
/ 02 октября 2019

Я делаю классификацию текста, используя gensim и doc2vec. Я использую два набора данных для тестирования этого, один из которых является набором данных обмена стека и набором данных Reddit. Я пытаюсь классифицировать сообщения из одного сайта subreddit / stackexchange по определенной теме, а затем использую сообщения из других не связанных между собой сайтов subreddit / stackexchange в качестве отрицательных примеров.

Я использую набор данных из 10 000 сообщений для обучениямодель и тестовый набор из 5 тысяч делятся на 50% положительных примеров и 50% отрицательных. Затем я использую функции infer_vector и most_s Similar, чтобы классифицировать запись как положительную или отрицательную. Перед обучением модели я предварительно обрабатываю данные, чтобы удалить любые слова, символы, ссылки и т. Д., Оставляя только самые важные слова для обучения модели. Ниже приведен код, используемый для обучения модели.

df = pd.read_csv("fulltrainingset.csv")

df.columns.values[0] = "A"

tagged_data = [TaggedDocument(words=word_tokenize(_d.lower()), tags=[str(i)]) for i, _d in enumerate(df["A"])]

epoch_list = [1,5,10,15,25,50,100,200,300,400]
size_list = [1,5,10,15,25,50,100,200,300]

for x in epoch_list:
    for y in size_list:

        vec_size = y
        max_epochs = x
        minimum_count = 1
        mode = 0
        window_ = 15
        negative_sampling = 5
        subsampling = 1e-5
        alpha = 0.025
        minalpha = 0.00025

        model = Doc2Vec(alpha=alpha, min_alpha=minalpha, vector_size=vec_size, dm=mode, min_count=minimum_count, window =window_, sample=subsampling ,hs =negative_sampling)
        model.build_vocab(tagged_data)

        for epoch in range(max_epochs):
            print('iteration {0}'.format(epoch))
            model.train(tagged_data,
                        total_examples=model.corpus_count,
                        epochs=model.epochs)#self.epochs
            model.alpha -= 0.0002
            model.min_alpha = model.alpha


        model.save(str(y)+"s_"+str(x)+"e.model")

Этот метод работает, и я могу получить от него результаты, но я хотел бы знать, есть ли другой способ обучения для достижения лучших результатов. В настоящее время я просто тренирую множество моделей с разными эпохами и векторами, а затем использую функции infer_vector и most_s Similar, чтобы увидеть, больше ли значение вектора, возвращаемое из записи most_s Similar, чем определенное число, но есть ли способ улучшить это в аспектетренировать модель?

Кроме того, чтобы добиться лучших результатов, я обучил другую модель таким же образом с большим набором данных (100 тыс. + записей). Когда я использовал эту модель на одном и том же наборе данных, она дала аналогичные, но худшие результаты, чем модели, обученные на меньших наборах данных. Я думал, что больше тренировочных данных улучшило бы результаты, не сделав их хуже, кто-нибудь знает причину этого?

Кроме того, для дальнейшего тестирования я создал новый, но больший набор тестов (15 тыс. Записей), который сделалдаже хуже, чем оригинальный набор тестов. Данные в этом наборе тестов, хотя и являются уникальными, относятся к тем же типам данных, которые использовались в исходном наборе тестов, но дают худшие результаты, что может быть причиной для этого?

df = pd.read_csv("all_sec_tweets.csv")

df.columns.values[0] = "A"

tagged_data = [TaggedDocument(words=word_tokenize(_d.lower()), tags=[str(i)]) for i, _d in enumerate(df["A"])]

epoch_list = [1,5,10,15,25,50,100]
size_list = [1,5,10,15,25,50,100]

for x in epoch_list:
    for y in size_list:

        vec_size = y
        max_epochs = x
        mode = 0
        window_ = 5
        subsampling = 1e-5

        model = Doc2Vec(vector_size=vec_size, dm=mode, window =window_, sample=subsampling,epochs=max_epochs)
        model.build_vocab(tagged_data)

        model.train(tagged_data,total_examples=model.corpus_count,epochs=model.epochs)

        model.save(str(y)+"s_"+str(x)+"e.model")

1 Ответ

0 голосов
/ 03 октября 2019

Звучит так, как будто вы тренируете отдельную модель Doc2Vec для решения каждого форума "in" / "out", а затем используете импровизированный набор операций infer_vector() / most_similar() для принятия решения.

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

(в этот момент вы также можете обучать более крупные модели, которые включают в себя маркированные обучающие примеры со всех форумов, и классификаторы, которые выбирают один из множества возможных классов.)

Отдельно, несколько вещейошибочны или неоптимальны в вашей Doc2Vec тренировке, включая:

  • Почти всегда ошибочно вызывать train() более одного раза в вашем собственном цикле или изменятьзначения по умолчанию alpha / min_alpha. Ваш текущий код фактически заставляет model.epochs (5) передавать данные для каждого вызова и часто уменьшает alpha в 0.0002 сотни раз (до бессмысленных отрицательных значений). Вызовите train() только один раз, с нужным номером epochs, со значениями по умолчанию alpha / min_alpha, и все будет сделано правильно. (И: не доверяйте ни одному онлайн-учебнику / примеру, предложившему вышеупомянутые циклические вызовы.)

  • Ваш hs=5 включит режим иерархического-softmax строго, но оставляетустановлен параметр по умолчанию negative=5 - поэтому ваша модель будет использовать (нестандартное и, вероятно, бесполезное и медленное) сочетание обучения с отрицательной выборкой и иерархической софтмакс. Лучше использовать какое-либо значение negative и hs=0 (для чистой отрицательной выборки), или negative=0, hs=1 (для чистой иерархической-softmax). Или просто придерживайтесь значения по умолчанию (negative=5, hs=0), если / пока все уже не работает, и вы не хотите углубляться в более глубокие оптимизации.

  • min_count=1 - редко лучший вариант: эти моделичасто извлекают пользу из отбрасывания редких слов.

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

...