Pipeline и GridSearch для Doc2Vec - PullRequest
0 голосов
/ 10 мая 2018

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

Данные

Пример данных (data.csv) можно скачать здесь: https://pastebin.com/takYp6T8 Обратите внимание, что данные имеют структуру, которая должна составлять идеальный классификатор с точностью до 1,0.

Сценарий

import sys
import os
from time import time
from operator import itemgetter
import pickle
import pandas as pd
import numpy as np
from argparse import ArgumentParser

from gensim.models.doc2vec import Doc2Vec
from gensim.models import Doc2Vec
import gensim.models.doc2vec
from gensim.models import KeyedVectors
from gensim.models.doc2vec import TaggedDocument, Doc2Vec

from sklearn.base import BaseEstimator
from gensim import corpora

from sklearn.linear_model import LogisticRegression
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import GridSearchCV
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
from sklearn.metrics import classification_report


dataset = pd.read_csv("data.csv")

class Doc2VecModel(BaseEstimator):

    def __init__(self, dm=1, size=1, window=1):
        self.d2v_model = None
        self.size = size
        self.window = window
        self.dm = dm

    def fit(self, raw_documents, y=None):
        # Initialize model
        self.d2v_model = Doc2Vec(size=self.size, window=self.window, dm=self.dm, iter=5, alpha=0.025, min_alpha=0.001)
        # Tag docs
        tagged_documents = []
        for index, row in raw_documents.iteritems():
            tag = '{}_{}'.format("type", index)
            tokens = row.split()
            tagged_documents.append(TaggedDocument(words=tokens, tags=[tag]))
        # Build vocabulary
        self.d2v_model.build_vocab(tagged_documents)
        # Train model
        self.d2v_model.train(tagged_documents, total_examples=len(tagged_documents), epochs=self.d2v_model.iter)
        return self

    def transform(self, raw_documents):
        X = []
        for index, row in raw_documents.iteritems():
            X.append(self.d2v_model.infer_vector(row))
        X = pd.DataFrame(X, index=raw_documents.index)
        return X

    def fit_transform(self, raw_documents, y=None):
        self.fit(raw_documents)
        return self.transform(raw_documents)


param_grid = {'doc2vec__window': [2, 3],
              'doc2vec__dm': [0,1],
              'doc2vec__size': [100,200],
              'logreg__C': [0.1, 1],
}

pipe_log = Pipeline([('doc2vec', Doc2VecModel()), ('log', LogisticRegression())])

log_grid = GridSearchCV(pipe_log, 
                        param_grid=param_grid,
                        scoring="accuracy",
                        verbose=3,
                        n_jobs=1)

fitted = log_grid.fit(dataset["posts"], dataset["type"])

# Best parameters
print("Best Parameters: {}\n".format(log_grid.best_params_))
print("Best accuracy: {}\n".format(log_grid.best_score_))
print("Finished.")

У меня есть следующие вопросы относительно моего сценария (яобъедините их здесь, чтобы избежать трех сообщений с одним и тем же фрагментом кода):

  1. Какова цель def __init__(self, dm=1, size=1, window=1):?Могу ли я как-нибудь удалить эту часть (попытался безуспешно)?
  2. Как добавить RandomForest классификатор (или другие) в рабочий процесс / конвейер GridSearch?
  3. Как можно обучить /тестовое разделение данных добавлено в приведенный выше код, так как текущий скрипт работает только с полным набором данных?

1 Ответ

0 голосов
/ 11 мая 2018

1) init() позволяет вам определить параметры, которые ваш класс должен принимать при инициализации (эквивалентно contructor в java).

Пожалуйста, посмотрите на эти вопросы для более подробной информации:

2) Почему вы хотите добавить RandomForestClassifier и каков будет его ввод?

Глядя на два других вопроса, хотите ли вы сравнить выходные данные RandomForestClassifier с LogisticRegression здесь?Если да, то у вас все хорошо в этом вопросе .

3) Вы импортировали train_test_split, просто используйте его.

X_train, X_test, y_train, y_test = train_test_split(dataset["posts"], dataset["type"])

fitted = log_grid.fit(X_train, y_train)
...