特征工程(五)特征选择(3)—基于模型的特征选择
·
1、SelectKBest和自然语言处理
import pandas as pd
# 读取推文数据集
tweets = pd.read_csv('../data/twitter_sentiment.csv', encoding='latin1')
tweets.head()

# 从sklearn中导入网格搜索模块
from sklearn.model_selection import GridSearchCV
# 创建一个函数,用来评估模型
def get_best_model_and_accuracy(model, params, X, y):
grid = GridSearchCV(model, # 要搜索的模型
params, # 要尝试的参数
error_score=0.0 # 如果报错,结果为0
)
# 拟合模型和参数
grid.fit(X, y)
# 经典的性能指标
print('最佳的准确率为:{}'.format(grid.best_score_))
# 得到最佳准确率的最佳参数
print('得到最佳准确率的最佳参数:{}'.format(grid.best_params_))
# 拟合的平均时间
print('拟合的平均时间:{} 秒'.format(round(grid.cv_results_['mean_fit_time'].mean(), 3)))
# 预测的平均时间
print('预测的平均时间:{} 秒'.format(round(grid.cv_results_['mean_score_time'].mean(), 3)))
# 获取X和y
tweets_X = tweets['SentimentText']
tweets_y = tweets['Sentiment']
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.pipeline import Pipeline
# 导入朴素贝叶斯
from sklearn.naive_bayes import MultinomialNB
vect = CountVectorizer()
text_pipe = Pipeline(
[
('vect', vect),
('nb', MultinomialNB())
]
)
text_pipe_params = {
'vect__ngram_range':[(1, 2)],
'vect__max_features':[5000, 10000],# 设置特征构建器可以记忆的最多特征数量
'vect__min_df':[0.0, 0.1, 0.2, 0.3],# 词项在语料库出现频率的下限
'vect__max_df':[0.7, 0.8, 0.9, 1.0]# 词项在语料库出现频率的上限
}
get_best_model_and_accuracy(text_pipe, text_pipe_params, tweets_X, tweets_y)
# 没有使用FeatureUnion来组合TfidfVectorizer+CountVectorizer得到的评分高

# 使用SelectKBest和CountVectorizer试试
from sklearn.feature_selection import SelectKBest
vect = CountVectorizer(ngram_range=(1, 2))
select_pipeline = Pipeline([
('vect', vect),
('select_k', SelectKBest()),
('nb', MultinomialNB())
])
select_pipeline_params = {
'select_k__k':[1000, 5000]
}
get_best_model_and_accuracy(select_pipeline, select_pipeline_params, tweets_X, tweets_y)
# SelectKBest对文本的效果不好,而且拟合和预测的时间都比较长,这是因为统计单变量方法在大量特征上表现不好

2、特征选择指标——针对基于树的模型
'''
特征选择指标——针对基于树的模型
拟合决策树时候,决策树会从根节点开始,在每个节点贪婪地选择最优分割,优化节点纯净度指标。
默认scikit-learn选择基尼系数进行优化。每次分割时候,模型会记录每个分割对整体优化目标的帮助。这些指标对特征重要性有作用。
'''
# 利用pandas读取信用卡逾期数据集
credit_card_default = pd.read_csv("../data/credit_card_default.csv")
# 构建特征矩阵和响应变量
X = credit_card_default.drop('default payment next month', axis=1)
y = credit_card_default['default payment next month']
from sklearn.tree import DecisionTreeClassifier
d_tree = DecisionTreeClassifier()
d_tree.fit(X, y)
# 拟合后,可以用feature_importances_展示特征对于拟合树的重要性
importances = pd.DataFrame(
{
'importances':d_tree.feature_importances_,
'特征':X.columns
}
).sort_values('importances', ascending=False)
importances.head()
# 第2、第3和第5个特征,在进行统计测试前没有显示出重要性,意味着这种特征选择方法可能会带来一些新的结果

'''
之前的SelectKBest,是基于排序函数(例如ANOVA的p值)取前k个特征
SelectFromModel使用机器学习模型内部的指标来评估特征的重要性
最大的不同:
SelectFromModel和SelectKBest相比,不使用k,而是使用阈值,代表重要性的最低限度。
'''
from sklearn.feature_selection import SelectFromModel
# 实例化一个类,按照决策树分类器的内部指标排序重要性,选择特征
select_from_model = SelectFromModel(DecisionTreeClassifier(),threshold=0.05)
# 拟合数据,观察数据选择后的子集
selected_X = select_from_model.fit_transform(X, y)
selected_X.shape
# 之前相关性选择器和ANOVA的准确率为0.8206
# 现在在流水线应用此功能
tree_pipe_params = {
'd_tree__max_depth':[1, 3, 5, 7],
'select__threshold':[0.01, 0.05, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 'mean', 'median', '2.*mean'],
'select__estimator__max_depth':[None,1, 3, 5, 7]
}
# mean表示选择比均值更重要的特征
# median表示选择比中位数更重要的特征
# 2.*mean表示选择比均值重要两倍的特征
tree_pipe = Pipeline([
('select', SelectFromModel(DecisionTreeClassifier())),
('d_tree', d_tree)
])
get_best_model_and_accuracy(tree_pipe, tree_pipe_params, X, y)
# 发现没有比原来更好

# 查看树选择了那些特征
tree_pipe.set_params(**
{
'd_tree__max_depth':2,
'select__threshold':0.01,
'select__estimator__max_depth':None
}
)
# 拟合数据
tree_pipe.steps[0][1].fit(X, y)
# 列出选择的列
X.columns[tree_pipe.steps[0][1].get_support()]
# 选择了两个特征外所有其他特征,和什么都不选的树性能没区别

3、特征选择指标——线性模型
'''
特征选择指标——线性模型
SelectFromModel可以处理包括feature_importances_或者coef_属性的机器学习方法模型。
基于树的模型会暴露前者,线性模型会暴露后者。
拟合后,线性模型会将一个系数放在特征的斜率前面,SelectFromModel会认为这个系数等同于重要性,并根据拟合时的系数选择特征。
'''
from sklearn.linear_model import LogisticRegression
# 使用正则化后的逻辑回归进行选择
lr_selector = SelectFromModel(LogisticRegression())
lr_reg_pipe = Pipeline([
('lr_selector', lr_selector),
('d_tree', d_tree),
])
lr_reg_pipe_params = {
'd_tree__max_depth':[1, 3, 5, 7],
'lr_selector__threshold':[0.01, 0.05, 0.1, 'mean', 'median', '2.*mean'],
'lr_selector__estimator__penalty':['l1', 'l2']
}
get_best_model_and_accuracy(lr_reg_pipe, lr_reg_pipe_params, X, y)
# 比之前稍好,速度也快

# 设置最佳参数
lr_reg_pipe.set_params(**
{
'd_tree__max_depth':5,
'lr_selector__threshold':'median',
'lr_selector__estimator__penalty':'l2'
}
)
# 拟合数据
lr_reg_pipe.steps[0][1].fit(X, y)
# 列出选择的列
X.columns[lr_reg_pipe.steps[0][1].get_support()]
# 基于逻辑回归的选择器选了大部分的PAY_X特征,也发现了性别、教育和年龄等,可以帮助预测。

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)