2017-03-28 54 views
0

我有仇恨言论集containining一些10K标志着鸣叫:它看起来像这样Python的Sklearn NGRAM精度降低为NGRAM长度增加

分享Tweet |类
大家好|没有攻势
你丑陋的muppet |进攻而不是仇恨言论
You **** jew |仇恨言论

现在我试图从SKLearn库python中使用MultinomialNB分类器,并且继承我的代码。

import pandas as pd 
import numpy as np 
from sklearn.feature_extraction.text import CountVectorizer 
from sklearn.naive_bayes import MultinomialNB 

data = pd.read_excel('myfile', encoding = "utf-8") 
data = data.sample(frac=1) 
training_base = 0; 
training_bounds = 10000; 
test_base = training_bounds+1; 
test_bounds = 12000; 
tweets_train = data['tweet'][training_base:training_bounds] 
tweets_test = data['tweet'][test_base:test_bounds] 
class_train = data['class'][training_base:training_bounds] 
class_test = data['class'][test_base:test_bounds] 
vectorizer = CountVectorizer(analyzer='word', ngram_range=(1,1)) 
train_counts = vectorizer.fit_transform(tweets_train.values) 

classifier = MultinomialNB() 
train_targets = class_train.values 
classifier.fit(train_counts, train_targets) 
example_counts = vectorizer.transform(tweets_test.values); 
predictions = classifier.predict(example_counts) 
accuracy = np.mean(predictions == class_test.values) 
print(accuracy) 

的准确性使用ngram_range(1,1)时为约75%,但如我去(2,2)到(8,8)从它75,72,67..55%降低。为什么是这样?我错过了什么?

回答

4

您使问题变得越来越稀疏,从测试集中的训练集中找到确切的8个单词序列可能会非常困难,从而导致精度更差。

我推荐混合不同的单词n-gram长度(这就是为什么有两个参数),例如。 (1,3)对于非常短的推文似乎是一个合理的选择。此外,字符n-gram中可能会隐藏一些隐藏的信息,这些信息自然会编码更多的语言特征 - 您可以将它们添加到特征空间中。

+1

伟大的答案,我会试试看,并回来的结果! – samson

1

基于the scikit-learn documentation for CountVectorizerngram_range(1,1)意味着你只使用1克(单字),ngram_range(2,2)意味着你将只用2克(双字),依此类推,每ngram_range(x,x)

仅使用2克,特别是仅使用3克,4克等的问题是即使您有足够的单个单词的例子以获得良好的1克准确性,您可能没有足够的每2克的例子,并且随着你越来越大,变得更加棘手。

您是否尝试过增加第二个数字?所以去ngram_range(1,2)看看是否有1克和2克有帮助。