选择用于对用户文本数据进行分类的sklearn管道

时间:2016-01-12 03:17:08

标签: python machine-learning scikit-learn feature-selection

我正在研究Python中的机器学习应用程序(使用sklearn模块),目前正在尝试决定执行推理的模型。问题的简要说明:

鉴于用户数据的许多实例,我试图根据相对关键字包含将它们分类为各种类别。它受到监督,因此我有许多已经分类的预分类数据实例。 (每个数据都在2到12个左右的单词之间。)

我目前正在尝试在两种潜在模式之间做出决定:

  1. CountVectorizer + Multinomial Naive Bayes 。使用sklearn的CountVectorizer获取整个训练数据的关键字计数。然后,使用Naive Bayes使用sklearn的MultinomialNB模型对数据进行分类。

  2. 在关键字计数+标准朴素贝叶斯上使用tf-idf术语加权。使用CountVectorizer获取训练数据的关键字计数矩阵,使用sklearn的TfidfTransformer将该数据转换为tf-idf加权,然后将其转储到标准Naive Bayes模型中。

  3. 我已经阅读了两种方法中使用的类的文档,两者似乎都很好地解决了我的问题。

    有没有明显的理由说明为什么使用标准Naive Bayes模型的tf-idf加权可能会比这类问题的多项Naive Bayes更好?这两种方法都有明显的问题吗?

2 个答案:

答案 0 :(得分:1)

Naive Bayes和MultinomialNB是相同的算法。你得到的差异来自于tfidf转换,它会惩罚你语料库中许多文档中出现的单词。

我的建议: 使用tfidf并调整TfidfVectorization的sublinear_tf,二进制参数和规范化参数以获取特征。

同时尝试scikit-learn中可用的所有类型的不同分类器,如果你正确调整正则化类型(惩罚值为18或l2)和正则化参数(alpha)的值,我怀疑它会给你更好的结果。

如果你正确地调整它们,我怀疑你可以使用SGDClassifier和' log'来获得更好的结果。损失(Logistic回归)或'铰链'损失(SVM)。

人们通常调整参数的方式是通过scikit-learn中的GridSearchCV类。

答案 1 :(得分:0)

我同意David的评论。你想要训练不同的模型,看看哪个是最好的。

import pandas as pd
import numpy as np

from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB, GaussianNB, BernoulliNB
from sklearn.pipeline import Pipeline
from sklearn.grid_search import GridSearchCV

from pprint import pprint

df = pd.DataFrame({'Keyword': ['buy widget', 'buy widgets', 'fiberglass widget',
                               'fiberglass widgets', 'how much are widget',
                               'how much are widgets', 'installing widget',
                               'installing widgets', 'vinyl widget', 'vinyl widgets',
                               'widget cost', 'widget estimate', 'widget install',
                               'widget installation', 'widget price', 'widget pricing',
                               'widgets cost', 'widgets estimate', 'widgets install',
                               'widgets installation', 'widgets price', 'widgets pricing',
                               'wood widget', 'wood widgets'],
                   'Label': ['Buy', 'Buy', 'Fiberglass', 'Fiberglass', 'Cost', 'Cost',
                             'Install', 'Install', 'Vinyl', 'Vinyl', 'Cost', 'Estimate',
                             'Install', 'Install', 'Cost', 'Cost', 'Cost', 'Estimate',
                             'Install', 'Install', 'Cost', 'Cost', 'Wood', 'Wood']},
                  columns=['Label', 'Keyword'])

X = df['Keyword']
y = df['Label']

##pipeline = Pipeline(steps=[
##  ('cvect', CountVectorizer()),
##  ('mnb', MultinomialNB())
##  ])

pipeline = Pipeline(steps=[
  ('tfidf', TfidfVectorizer()),
  ('bnb', BernoulliNB())
  ])

parameters = {'tfidf__ngram_range': [(1,1), (1,2)],
              'tfidf__stop_words': [None, 'english'],
              'tfidf__use_idf': [True, False],
              'bnb__alpha': [0.0, 0.5, 1.0],
              'bnb__binarize': [None, 0.2, 0.5, 0.7, 1.0],
              'bnb__fit_prior': [True, False]}

grid = GridSearchCV(pipeline, parameters, scoring='accuracy', cv=2, verbose=1)
grid.fit(X, y)

print('Best score:', grid.best_score_)
print('Best parameters:', pprint(grid.best_params_, indent=2))

# Here's how to predict (uncomment)
#pred = grid.predict(['buy wood widget', 'how much is a widget'])

#print(pred)