Python 所有的预处理都会降低准确性
我正在用逻辑回归模型进行网格搜索交叉验证。我首先有我的默认模型,然后是一个应该预处理数据的模型。这些数据是随机的文本文档,分为4类。我的预处理器似乎恶化了我的准确性和f1成绩,即使我只是让它返回数据,如下所示。gridsearch在通过此预处理后拾取的正则化参数C不应该做任何事情Python 所有的预处理都会降低准确性,python,scikit-learn,countvectorizer,Python,Scikit Learn,Countvectorizer,我正在用逻辑回归模型进行网格搜索交叉验证。我首先有我的默认模型,然后是一个应该预处理数据的模型。这些数据是随机的文本文档,分为4类。我的预处理器似乎恶化了我的准确性和f1成绩,即使我只是让它返回数据,如下所示。gridsearch在通过此预处理后拾取的正则化参数C不应该做任何事情 Cs = {'C' : [0.0001, 0.001, 0.01, 0.1, 0.5, 1.0, 2.0, 10.0]} gs_clf_LR = GridSearchCV(LogisticRegression(pena
Cs = {'C' : [0.0001, 0.001, 0.01, 0.1, 0.5, 1.0, 2.0, 10.0]}
gs_clf_LR = GridSearchCV(LogisticRegression(penalty='l2'), Cs, refit=True)
gs_clf_LR.fit(transformed_train_data, train_labels)
preds = gs_clf_LR.predict(transformed_dev_data)
#print gs_clf_LR.score(transformed_dev_data, dev_labels)
print gs_clf_LR.best_params_
print 'With optimal C, accuracy score is: ', gs_clf_LR.best_score_
print 'f1 score: ', metrics.f1_score(dev_labels, preds, average='weighted')
print metrics.classification_report(dev_labels, preds)
print
def better_preprocessor(string):
#return re.sub(r'^[A-Z]', '^[a-z]', string)
#return re.sub(r'(ing)$', '', string)
#return re.sub(r'(es)$', '', string)
#return re.sub(r's$', '', string)
#return re.sub(r'(ed)$', '', string)
return string
vec = CountVectorizer(preprocessor=better_preprocessor)
transformed_preprocessed_train_data = vec.fit_transform(train_data)
transformed_preprocessed_dev_data = vec.transform(dev_data)
gs_clf_LR.fit(transformed_preprocessed_train_data, train_labels)
preds_pp = gs_clf_LR.predict(transformed_preprocessed_dev_data)
#print gs_clf_LR.score(transformed_preprocessed_dev_data, dev_labels)
print gs_clf_LR.best_params_
print 'With optimal C, accuracy score is: ', gs_clf_LR.best_score_
print 'f1 score: ', metrics.f1_score(dev_labels, preds_pp, average='weighted')
print metrics.classification_report(dev_labels, preds_pp)
通过一些真正的预处理,例如我注释掉的正则表达式行,我也看到了我的精确度和f1分数的下降(似乎有道理,但我正在去掉复数,并被告知这会提高我的分数)。你是否从你的数据中分离出一个随机生成的测试集,它存在于交叉验证之外,要在上测试这两个模型?准确度降低可能是由于减少了对数据的过度拟合而导致更大的泛化。您是否从数据中分离出一个随机生成的测试集(存在于交叉验证之外),以测试这两个模型?准确度降低可能是由于减少了对数据的过度拟合而导致更大的泛化。问题是预处理基本上什么都不做,因为预处理是在标记化之前CountVectorizer中发生的。这意味着您可以通过函数获取完整的文本,并且不会触发末尾带有
$
的正则表达式
这是将矢量器与您的更好的预处理相匹配的结果:
In [16]: data = ['How are you guys doing? Fine! We are very satisfied']
In [17]: vec.fit(data)
Out[17]:
CountVectorizer(analyzer='word', binary=False, decode_error='strict',
dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
lowercase=True, max_df=1.0, max_features=None, min_df=1,
ngram_range=(1, 1),
preprocessor=<function better_preprocessor at 0x000002DB839FF048>,
stop_words=None, strip_accents=None,
token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, vocabulary=None)
In [18]: vec.get_feature_names()
Out[18]: ['Fine', 'We', 'are', 'doing', 'guys', 'ow', 'satisfied', 'very', 'you']
In[16]:data=['你们好吗?很好!我们非常满意']
[17]中的向量拟合(数据)
出[17]:
计数器矢量器(analyzer='word',binary=False,decode_error='strict',
数据类型=,编码='utf-8',输入='content',
小写=真,最大值为1.0,最大值为无,最小值为1,
ngram_范围=(1,1),
预处理器=,
停止单词=无,去除口音=无,
标记\u模式='(?u)\\b\\w\\w+\\b',标记器=无,词汇表=无)
在[18]:vec.get\u feature\u names()中
出[18]:[“很好”,“我们”,“正在”,“正在做”,“伙计们”,“现在”,“满意”,“非常”,“你”]
这意味着您必须用函数覆盖分析器
步骤,而不是预处理器
。比较:
分析器:无论
特征应由单词或字符n-grams组成。选项“char\u wb”
仅从单词边界内的文本创建字符n-gram。如果
callable被传递,用于提取特征序列
原始的、未处理的输入
预处理器:可调用或无
(默认)覆盖预处理(字符串转换)阶段
同时保留标记化和n-grams生成步骤
但是,您必须在函数中处理标记化,但是您可以使用默认的”(?u)\\b\\w\\w+\\b'
,因此这并不难。无论如何,我认为您的方法并不可靠,我建议使用NLTK中的SnowballStemmer
之类的方法,而不是这些正则表达式。问题是您的预处理基本上什么都不做,因为预处理是在标记化之前CountVectorizer中发生的事情。这意味着您可以通过函数获取完整的文本,并且不会触发末尾带有$
的正则表达式
这是将矢量器与您的更好的预处理相匹配的结果:
In [16]: data = ['How are you guys doing? Fine! We are very satisfied']
In [17]: vec.fit(data)
Out[17]:
CountVectorizer(analyzer='word', binary=False, decode_error='strict',
dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
lowercase=True, max_df=1.0, max_features=None, min_df=1,
ngram_range=(1, 1),
preprocessor=<function better_preprocessor at 0x000002DB839FF048>,
stop_words=None, strip_accents=None,
token_pattern='(?u)\\b\\w\\w+\\b', tokenizer=None, vocabulary=None)
In [18]: vec.get_feature_names()
Out[18]: ['Fine', 'We', 'are', 'doing', 'guys', 'ow', 'satisfied', 'very', 'you']
In[16]:data=['你们好吗?很好!我们非常满意']
[17]中的向量拟合(数据)
出[17]:
计数器矢量器(analyzer='word',binary=False,decode_error='strict',
数据类型=,编码='utf-8',输入='content',
小写=真,最大值为1.0,最大值为无,最小值为1,
ngram_范围=(1,1),
预处理器=,
停止单词=无,去除口音=无,
标记\u模式='(?u)\\b\\w\\w+\\b',标记器=无,词汇表=无)
在[18]:vec.get\u feature\u names()中
出[18]:[“很好”,“我们”,“正在”,“正在做”,“伙计们”,“现在”,“满意”,“非常”,“你”]
这意味着您必须用函数覆盖分析器
步骤,而不是预处理器
。比较:
分析器:无论
特征应由单词或字符n-grams组成。选项“char\u wb”
仅从单词边界内的文本创建字符n-gram。如果
callable被传递,用于提取特征序列
原始的、未处理的输入
预处理器:可调用或无
(默认)覆盖预处理(字符串转换)阶段
同时保留标记化和n-grams生成步骤
但是,您必须在函数中处理标记化,但是您可以使用默认的”(?u)\\b\\w\\w+\\b'
,因此这并不难。无论如何,我认为您的方法并不可靠,我建议使用NLTK中的SnowballStemmer
之类的东西,而不是这些正则表达式。这将是转换的开发数据,然后是转换的预处理开发数据变量。我应该只预处理列车数据而不是测试数据吗?那将是转换的_dev_数据,然后是转换的_预处理的_dev_数据变量。我应该只预处理列车数据而不是测试数据吗?