Doc2Vec的管道和GridSearch

时间:2018-05-10 17:52:22

标签: scikit-learn pipeline gensim grid-search

我目前有以下脚本,有助于找到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. 如何在GridSearch工作流/管道中添加RandomForest分类器(或其他)?
  3. 如何将火车/测试数据拆分添加到上面的代码中,因为当前脚本只训练整个数据集?

1 个答案:

答案 0 :(得分:2)

1)init()允许您定义您希望类在初始化时采用的参数(相当于java中的构造函数)。

请查看以下问题以获取更多详细信息:

2)为什么要添加RandomForestClassifier以及它的输入是什么?

看看你的其他两个问题,你想在这里将RandomForestClassifier的输出与LogisticRegression进行比较吗?如果是这样,你在this question of yours做得很好。

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)
相关问题