特征工程(五)特征选择(3)—基于模型的特征选择

1、SelectKBest和自然语言处理

import pandas as pd

# 读取推文数据集
tweets = pd.read_csv('../data/twitter_sentiment.csv', encoding='latin1')

tweets.head()

特征工程(五)特征选择(3)—基于模型的特征选择_第1张图片

# 从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个特征,在进行统计测试前没有显示出重要性,意味着这种特征选择方法可能会带来一些新的结果

特征工程(五)特征选择(3)—基于模型的特征选择_第2张图片

'''
之前的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)—基于模型的特征选择_第3张图片

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特征,也发现了性别、教育和年龄等,可以帮助预测。

在这里插入图片描述

你可能感兴趣的:(#,特征工程,python,sklearn)