使用逻辑回归进行特征选择
Posted
技术标签:
【中文标题】使用逻辑回归进行特征选择【英文标题】:feature selection using logistic regression 【发布时间】:2016-01-25 23:51:11 【问题描述】:我正在使用逻辑回归执行特征选择(在具有 1,930,388 行和 88 个特征的数据集上)。如果我在保留数据上测试模型,准确率略高于 60%。响应变量是均匀分布的。我的问题是,如果模型的性能不好,我可以将它给出的特征视为实际的重要特征吗?还是应该尝试提高模型的准确性,尽管我的最终目标不是提高准确性,而只是获得重要特征
【问题讨论】:
你的特征选择器是什么? 【参考方案1】:sklearn 的 GridSearchCV 有一些非常简洁的方法可以为您提供最佳功能集。例如,考虑以下代码
pipeline = Pipeline([
('vect', TfidfVectorizer(stop_words='english',sublinear_tf=True)),
('clf', LogisticRegression())
])
parameters =
'vect__max_df': (0.25, 0.5, 0.6, 0.7, 1.0),
'vect__ngram_range': ((1, 1), (1, 2), (2,3), (1,3), (1,4), (1,5)),
'vect__use_idf': (True, False),
'clf__C': (0.1, 1, 10, 20, 30)
这里的参数数组包含我需要考虑的所有不同参数。注意 if vect__max_df 的使用。 max_df 是我的矢量化器使用的实际键,它是我的特征选择器。所以,
'vect__max_df': (0.25, 0.5, 0.6, 0.7, 1.0),
实际上指定我想为我的矢量化器尝试上述 5 个值。其他人也是如此。请注意我如何将矢量化器绑定到键“vect”,将分类器绑定到键“clf”。你能看到图案吗?继续前进
traindf = pd.read_json('../../data/train.json')
traindf['ingredients_clean_string'] = [' , '.join(z).strip() for z in traindf['ingredients']]
traindf['ingredients_string'] = [' '.join([WordNetLemmatizer().lemmatize(re.sub('[^A-Za-z]', ' ', line)) for line in lists]).strip() for lists in traindf['ingredients']]
X, y = traindf['ingredients_string'], traindf['cuisine'].as_matrix()
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7)
grid_search = GridSearchCV(pipeline, parameters, n_jobs=3, verbose=1, scoring='accuracy')
grid_search.fit(X_train, y_train)
print ('best score: %0.3f' % grid_search.best_score_)
print ('best parameters set:')
bestParameters = grid_search.best_estimator_.get_params()
for param_name in sorted(parameters.keys()):
print ('\t %s: %r' % (param_name, bestParameters[param_name]))
predictions = grid_search.predict(X_test)
print ('Accuracy:', accuracy_score(y_test, predictions))
print ('Confusion Matrix:', confusion_matrix(y_test, predictions))
print ('Classification Report:', classification_report(y_test, predictions))
请注意,bestParameters 数组将为我提供我在创建管道时指定的所有选项中最好的一组参数。
希望这会有所帮助。
编辑:获取所选功能列表
因此,一旦您拥有最佳参数集,就可以使用这些参数值创建矢量化器和分类器
vect = TfidfVectorizer('''use the best parameters here''')
然后你基本上再次训练这个矢量化器。在此过程中,矢量化器将从您的训练集中选择某些特征。
traindf = pd.read_json('../../data/train.json')
traindf['ingredients_clean_string'] = [' , '.join(z).strip() for z in traindf['ingredients']]
traindf['ingredients_string'] = [' '.join([WordNetLemmatizer().lemmatize(re.sub('[^A-Za-z]', ' ', line)) for line in lists]).strip() for lists in traindf['ingredients']]
X, y = traindf['ingredients_string'], traindf['cuisine'].as_matrix()
X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.7)
termDocMatrix = vect.fit_transform(X_train, y_train)
现在,termDocMatrix 具有所有选定的特征。此外,您可以使用矢量化器来获取特征名称。假设您想获得前 100 个功能。你的比较指标是卡方分数
getKbest = SelectKBest(chi2, k = 100)
现在只是
print(np.asarray(vect.get_feature_names())[getKbest.get_support()])
应该为您提供前 100 个功能。试试这个。
【讨论】:
感谢GridSearch的详细解释。但这并不能回答我的问题。我的问题是,如果我使用任何算法进行特征选择,我是否应该非常关注模型的准确性?例如,sk learn 特征选择方法 (scikit-learn.org/stable/modules/feature_selection.html) 将随机森林、逻辑回归等列为标准方法。如何在两种基于模型的特征选择方法之间进行选择?根据准确率选择? 准确率是一个很好的衡量标准,但您还应该查看其他参数,例如 ROC 曲线、精度、召回率和 f 度量。根据您要解决的问题,这些参数中的一个或多个可能很重要。这就是为什么它有助于创建管道,以便您可以比较不同的模型。准确性是最直接的。顺便问一下,您要解决哪个问题?你的用例是什么? 另外,当您说“最终目标不是提高准确性,而只是获得重要特征”时,您实际上是在寻找性能最佳模型选择的特征吗?即你想找出表现最好的模型正在关注的“事物”吗? 这是我的用例:我的响应变量是二进制的。我的特征是数字的(它们是某些产品特征,属性值是用户使用这些属性的次数)我想找到那些影响响应变量为 1 的特征。我不打算将用户分类为未来为 1 或 0。我只对模型返回的重要特征进行分类。 我还没有尝试实施您的建议,但快速的观察告诉我,所有这些都与文本分析有关。我的不是文本分析问题以上是关于使用逻辑回归进行特征选择的主要内容,如果未能解决你的问题,请参考以下文章
详解逻辑回归与评分卡-逻辑回归中的特征工程菜菜的sklearn课堂笔记