特征筛选实践-------过滤法

前言

在机器学习项目的数据集中,特征间的高相关、特征与标签的低相关或不相关、特征本身的信息量以及特征数量等因素都会对模型的效果产生影响,特征筛选的目的是保留对预测有贡献的特征,删除冗余或无用特征。特征选择方法分为三大类,分别为过滤法(Filter)、包裹法(Wrapper)、嵌入法(Embedding);本文仅研究过滤法,过滤法由可以分为两种,直接使用某个标准对每个特征分别打分,然后根据打分直接用阈值过滤特征;和衡量每个特征与响应变量之间的关系,再根据得分扔掉不好的特征。

本文基于实践流程的思路,分三个步骤对数据集进行筛选,其中每一步都基于前一步的结果进行。

第一步:根据特征自身统计特性筛选

是一个特征的初筛,目的是剔除信息量过小的特征。其中连续型特征通过方差来筛选,方差过小的特征过于平稳,对模型预测的贡献度微乎其微;类别型特征通过异众比率来筛选,剔除绝大多数值都属于同一类别的特征。表中阈值仅供参考。

数据类型筛选方法阈值
连续性数据方差大于0.01
类别型数据异众比率大于0.05

第二步:根据特征与标签的相关性筛选

数据集中的特征都是为预测标签而存在,因此特征与标签的相关性就很重要,也可以作为特征筛选的一种方法。根据数据类型的不同,可以将特征与标签的相关性检验分为四种方法,见下表,其中阈值仅供参考:

数据一类型数据二类型计算方法衡量指标选择阈值
连续型连续型皮尔森相关系数r大于|0.3|
连续型二分类独立样本t检验p小于0.05
连续型多分类单因素方差分析p小于0.05
类别型类别型卡方检验p小于0.05

第二步:根据特征与标签的相关性筛选

1 分类数据VS分类数据:卡方检验

当我们要检验的变量都是分类变量时,我们可以用列联表结合卡方检验来分析分类变量间的相关性。列联表形如:

体重<=50kg体重>50kg
年龄<=151020
年龄>153040

其中数值表示对应行列分类下的频数,如数值“10”代表年龄<=15且体重<=50kg的人数。

卡方检验的思想在于比较期望频数和实际频数的吻合程度,实际频数就是上边表格里的数字,而期望频数则是指行列变量相互独立的时候期望的频数。

接下来我们用上表演示一下如何生成期望频数:

                                                                                                                                         

                                                             原表

                                                             每个单元格所在的行之和乘以列之和

                                                             每个单元格除以列联表中总频数100,得到期望频率

现在我们有了实际频数(第一张表)和期望频率(最后一张表),接下来就可以进行卡方检验了;卡方检验的原假设是期望频数等于实际频数,即二者相互独立,备择假设是期望频数不等于实际频数,即二者相关;卡方的计算公式为:

                                                                             X^{2}=\sum \left (True frequency -Expected frequency \right )^{2}/Expected frequency

其中Turefrequency是真实频率,Expectedfrequency是期望频率;现在我们计算得到一个卡方值,那怎么来衡量这个值到底是接受原假设(即两变量相互独立)、还是拒绝原假设(两变量相关)呢?这就需要一个阈值:自由度,当卡方值大于自由度对应的阈值(阈值通过自由度表差得),我们认为拒绝原假设;当卡方值小于自由度对应的阈值,我们认为接受原假设。自由度=(行数-1)*(列数-1)。

自由度/概率0.950.90.80.70.50.30.20.10.050.010.001
10.0040.020.060.150.461.071.642.713.846.6410.83
20.10.210.450.711.392.413.224.65.999.2113.82
30.350.581.011.422.373.664.646.257.8211.3416.27
40.711.061.652.23.364.885.997.789.4913.2818.47
51.141.612.3434.356.067.299.2411.0715.0920.52
61.632.23.073.835.357.238.5610.6412.5916.8122.46
72.172.833.824.676.358.389.812.0214.0718.4824.32
82.733.494.595.537.349.5211.0313.3615.5120.0926.12
93.324.175.386.398.3410.6612.2414.6816.9221.6727.88
103.944.866.187.279.3411.7813.4415.9918.3123.2119.59

卡方检验对数据量有一定的要求,一般认为卡方检验其单元格最小频数应大于1,且至少应有4/5的单元格频数大于5,此时使用卡方检验才是有意义的。

####卡方检验
def chi_square(col1,col2):
    """
    卡方检验函数
    :param col1: series,一列分类数据,用作列联表的行
    :param col2: series,一列分类数据,用作列联表的列
    :return: 输出接受原假设的概率值
    """
    cross_table =pd.crosstab(index=col1, columns=col2, margins=False)  ##对两列生成列联表
    kf = chi2_contingency(cross_table)
    p_value = kf[1]  #p值
    return p_value

2 数值数据VS数值数据:皮尔逊相关系数

 使用皮尔森相关系数只能检验数据的线性相关性,当数据不是线性相关时,皮尔森相关系数没有意义,可以通过散点图直观的判断数据直接的关系。皮尔森相关系数的取值范围为-1--1,0表示无线性相关性,当皮尔森系数为正时,数值越大正线性相关性越强,当皮尔森系数为负时,数值越小,负线性相关性越强。下面是相关系数公式:上半部分表示x,y的协方差,下半部分表示x,y的标准差。

                                                                                          \rho =\frac{cov\left ( x,y \right )}{\sigma x\sigma y}

####两个变量间的皮尔森相关系数矩阵与p值
def Biva_Pearson(col1,col2):
    """
    两个变量的相关系数矩阵与p值
    :param col1: 变量1,seris或list
    :param col2: 变量2,seris或list
    :return:
    """
    coef_matrix = np.corrcoef(col1, col2) ##相关性矩阵
    (_, P_value) = ss.pearsonr(col1, col2) ##相关系数和p值
    # Cor_coef = col1.corr(col2) ##相关系数
    return coef_matrix,P_value
####多变量间的皮尔森相关系数矩阵和p值
def Mult_Pearson(df):
    """
    多变量间的相关性矩阵、p值
    :param df:
    :return:
    """
    coef_matrix = df.corr() 
    P_value_list = []
    for i in df.columns.tolist()[:-1]:
        (_, P_value) = ss.pearsonr(df[i],df[df.columns.tolist()[-1]]) 
        P_value_list.append(P_value)
    return coef_matrix,P_value_list
####画多变量散点图矩阵
def Scatter_plot_maxtrix(df,hue=None):
    """
    绘制多维散点图矩阵
    :param df: 绘图数据,dataframe
    :param hue: 按哪列进行分类,默认是none
    :return:
    """
    sns.set(style="ticks", color_codes=True) ##画图设置
    sns.pairplot(df , hue =hue) #散点图按hue列的分布矩阵
    plt.show()
####画热力图
def Ther_diagram(df):
    """
    画热力图矩阵
    :param df:输入绘图数据,dataframe
    :return:
    """
    sns.set(style="ticks", color_codes=True) ##画图设置
    figure, ax = plt.subplots(figsize=Cor_analysis.figsize)
    sns.heatmap(df.corr(), square=True, annot=True, ax=ax)
    plt.show()

3 二分类数据与数值数据:独立样本t检验

独立样本t检验,衡量二分类数据中,两个类别下连续型数据均值的差异是否显著,当差异显著时,认为二分类数据对连续型数据有影响,否则没有。


def t_test(name_x,name_y,df):
    """
    独立样本t检验,二值类别变量与连续型变量间的相关性,原假设是两类别对应的值均值相等,即两列相关独立不相关,
    :param name_x:dataframe中一个列名,二值变量
    :param name_y:dataframe中一个列名,连续型变量
    :param df:数据集dataframe
    :return: p_t:t检验的p值,当p <0.05时拒绝原假设,即两变量相关
    """
    from scipy.stats import ttest_ind, levene
    namex_list = df[name_x].tolist()
    namey_list = df[name_y].tolist()
    type_one = [];type_two = []
    for i in range(len(namex_list)):
        if namex_list[i] == list(set(df[name_x].tolist()))[0]:
            type_one.append(namey_list[i])
        else:
            type_two.append(namey_list[i])
    # 方差齐性检验 当检验结果为p>0.05所以,可以认为方差是相等的。
    p_s = levene(type_one, type_two)
    # print("方差齐性检验:",p_s,p_s[1])
    if p_s[1] >0.05:  ##当方差齐
        # 独立样本T检验,默认方差齐性 当p值>0.05, 接受原假设, 认为两台机床的加工精度无显著差异。
        p_t = ttest_ind(type_one, type_two)
    else: ###当方差不齐
        ###如果方差不齐性,则equal_var=False
        p_t = ttest_ind(type_one, type_two, equal_var=False) 
    return p_t[1]

4 多分类数据与数值数据:单因素方差分析

与独立样本t检验思想类似,验证每个类别下连续型数据均值的显著差异

def covariance(name_x,name_y,df):
    """
    单因素方差分析,类别型变量与连续型变量关系分析
    :param name_x:dataframe中一个类别型变量的列名
    :param name_y:dataframe中一个连续型变量的列名
    :param df:数据集dataframe
    :return:
            p:p值,拒绝原假设(自变量对因变量没有显著影响,即两个变量相互独立)的最小显著性水平
            f: F值,组间误差均方MSA除组内误差均方MSE,自由度F(K-1,N-K),其中k是类别变量的类别数,N是样本量
    """
    from statsmodels.formula.api import ols
    from statsmodels.stats.anova import anova_lm
    formula = '{} ~ {}'.format(name_x, name_y)
    model = ols(formula, df).fit()
    anovat = anova_lm(model)
    # f = anovat["F"][name_y]
    p = anovat["PR(>F)"][name_y]
    # df1 = len(df[name_x].drop_duplicates().tolist())-1 ##F值分子自由度
    # print("df1:",df1)
    # df2 = len(df[name_x].tolist())-df1+1   #F值分母自由度
    return p

第二步:根据特征与特征的相关性筛选(多重共线性)

待补充

参考文献

用 Python 对数据进行相关性分析用 Python 对数据进行相关性分析

sql联表分类统计_分类变量的相关性:五分钟掌握卡方检验「详细解析,附代码」...sql联表分类统计_分类变量的相关性:五分钟掌握卡方检验「详细解析,附代码」..._weixin_39736606的博客-CSDN博客

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值