在Python中,我应用了SelectPercentile(来自sklearn),以便仅使用最相关的功能并训练SVM分类器。
我想提一下,我只有一个语料库,所以我必须在这个语料库上执行cross_validation
使用SelectPercentile
选择功能后,当我使用cross_validation
时,我得分过高,我认为我做错了,但我无法弄清楚是什么。我认为X_all矩阵有重复的行或重复的列,但它没有。
我不明白为什么会得到这个结果。任何人都可以让我了解幕后发生的事情以及我做错了什么?
实施
#仅提取数据集中的单词
#使用Pandas创建数据框
数据框具有以下结构:
- 数据:仅包含没有任何停用词的单词
- 性别:1或0
vectorizer = TfidfVectorizer(lowercase=False, min_df=1)
X_all = vectorizer.fit_transform(dataframe.data)
y_all = dataframe.gender
selector = SelectPercentile(f_classif, percentile=10)
selector.fit(X_all, y_all)
X_all = selector.transform(X_all)
classifier = svm.SVC()
param_grid = [
{'C': [1, 10, 100, 1000], 'kernel': ['linear']},
{'C': [1, 10, 100, 1000], 'gamma': [0.001, 0.0001], 'kernel': ['rbf']},
]
gs = GridSearchCV(classifier, param_grid, cv=5, n_jobs=4)
gs.fit(X_all.toarray(), y_all)
sorted(gs.grid_scores_, key=lambda x: x.mean_validation_score, reverse=True)
print gs.best_score_
print gs.best_params_
使用所有 150个样本获得的分数:
不 SelectPercentile:0.756(9704个功能)
百分位= 90:0.822(8733个特征)
百分位= 70:0.947(6792个特征)
百分位= 50:0.973(4852个特征)
百分位= 30:0.967(2911个特征)
百分位= 10:0.970(971个特征)
百分位= 3:0.910(292个特征)
百分位= 1:0.820(98个特征)
另一方面,我尝试了另一种方法,然后将我拥有的150个样本分成火车并进行如下测试:
features_train, features_test, target_train, target_test = train_test_split(X_all, y_all, test_size=0.20, random_state=0)
selector = SelectPercentile(f_classif, percentile=10)
selector.fit(features_train, target_train)
features_train = selector.transform(features_train).toarray()
features_test = selector.transform(features_test).toarray()
classifier = svm.SVC().fit(features_train, target_train)
print("Training score: {0:.1f}%".format(classifier.score(features_test, target_test) * 100))
使用这种方法,我收到警告:
“/ usr / local / lib / python2.7 / dist-packages / sklearn / feature_selection / univariate_selection.py:113:UserWarning:Features [0 0 0 ...,0 0 0]是常量.UserWarning)”
所有结果都是常数,无论百分位数是多少(10,30,50,... 99): 44.3%
答案 0 :(得分:0)
我认为您不应该使用所有数据(SelectPercentile
)执行功能选择(X_all
)。通过这样做,您在交叉验证中进行测试的数据“泄漏”到您的模型中。因此,您的功能选择类型可以看到测试集中的数据,并告诉您的分类器与训练集和测试集中的标签相关的功能子集。
您应该使用Pipeline
将FS链接到您的分类器并执行交叉验证以进行模型评估。
但我认为使用单变量特征选择后跟SVM的方法可能会被SVD-SVM管道用于文本分类问题。查看this answer示例脚本。