数据挖掘笔记(4)-特征选择

特征选择的优点:
(1)在数据预处理之后进行特征选择,挑选重要的特征建立模型可以模型的准确率,增加模型的泛华能力。
(2)减少建立模型和模型工作时的时间消耗。
(3)增强对特征和特征值的理解。
参考博客:
https://blog.csdn.net/kebu12345678/article/details/78437118

常用的特征选择的方法

1.去掉低方差的特征
这是最简单的特征选择方法。如果特征的取值是离散的,用该方法可以去掉低方差的特征,比如某个特征的取值90%都是一样或者完全一样,那这个特征对于预测结果起到的作用甚小。
例子:

from sklearn.feature_selection import VarianceThreshold
x = [[1, 0, 2, 1, 2, 3, 2],
     [0, 1, 2, 2, 2, 4, 2],
     [2, 0, 0, 1, 2, 3, 4],
     [1, 1, 1, 2, 2, 4, 2],
     [0, 0, 0, 4, 2, 4, 3],
     [0, 1, 0, 1, 2, 4, 6],
     [1, 0, 1, 0, 2, 3, 4],
     [0, 0, 1, 1, 2, 4, 1],
     [0, 1, 1, 1, 2, 4, 0],
     [1, 1, 0, 0, 2, 4, 1]]
# vt = VarianceThreshold(threshold=0.)
# threshold为给定的方差阈值默认为0.将方差小于该阈值的特征移除。
vt = VarianceThreshold()
x = vt.fit_transfrom(x)
print(x)
# .variances_可以得到每个特征方差
print(model.variances_)
结果:
[[1 0 2 1 3 2]
 [0 1 2 2 4 2]
 [2 0 0 1 3 4]
 [1 1 1 2 4 2]
 [0 0 0 4 4 3]
 [0 1 0 1 4 6]
 [1 0 1 0 3 4]
 [0 0 1 1 4 1]
 [0 1 1 1 4 0]
 [1 1 0 0 4 1]]
[0.44 0.25 0.56 1.21 0.   0.21 2.85]

该特征选择方法可以作为特征选择的第一步,然后在采用其它更加有效的特征选择方法。
2. 单变量特征选择
对于每一个特征进行测试,衡量每个特征和因变量(结果)之间的关系并进行打分。根据得分情况筛选重要的特征。
2.1 卡方检验/F检验
官方文档
卡方检验:
对于分类问题可选用卡方检验进行测试,卡方检验可以衡量每个非负特征和类别标签之间的关系。

 from sklearn.datasets import load_iris
>>> from sklearn.feature_selection import SelectKBest
>>> from sklearn.feature_selection import chi2
>>> iris = load_iris()
>>> X, y = iris.data, iris.target
>>> X.shape
(150, 4)
>>> X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
>>> X_new.shape
(150, 2)
# print(model.scores_)可以查看得分
# print(model.pvalues_)可以查看p值

F检验:
f_regression是单变量线性回归测试,用线性模型来测试每个特征和因变量之间的关系。
例子:

# -*- coding:utf-8 -*-
from sklearn.feature_selection import SelectKBest, f_regression
# x的前4列满足该表达式y = a+2b+c+3d
x = [[1, 0, 2, 1, 2, 3, 2],
     [0, 1, 2, 2, 2, 4, 2],
     [2, 0, 0, 1, 2, 3, 4],
     [1, 1, 1, 2, 2, 4, 2],
     [0, 0, 0, 4, 2, 4, 3],
     [0, 1, 0, 1, 2, 4, 6],
     [1, 0, 1, 0, 2, 3, 4],
     [0, 0, 1, 1, 1, 4, 1],
     [0, 1, 1, 1, 2, 4, 0],
     [1, 1, 0, 0, 2, 4, 1]]
y = [6, 10, 5, 10, 12, 5, 2, 4, 6, 3]
# F检验特征选择
model = SelectKBest(f_regression, k=4)
model.fit(x, y)
print(model.transform(x))
# p的值越大,得分越小,该自变量和因变量的关联越小
print('pvalues_: \n', model.pvalues_)
print('scores_: \n', model.scores_)
结果为:
[[1 1 2 3]
 [0 2 2 4]
 [2 1 2 3]
 [1 2 2 4]
 [0 4 2 4]
 [0 1 2 4]
 [1 0 2 3]
 [0 1 1 4]
 [0 1 2 4]
 [1 0 2 4]]
pvalues_: 
 [3.55923125e-01 6.59556525e-01 6.71828059e-01 8.76032784e-05
 4.95493819e-01 2.37956163e-01 8.15175135e-01]
scores_: 
 [ 0.95983394  0.20920502  0.19328859 52.63908046  0.50987952  1.62663551
  0.05836576]

2.2皮尔森(Pearson)相关系数
通过计算每个特征和结果的相关系数来分析它们之间的关系。
原理:此文末尾
弊端:只能分析特征和结果之间的线性关系,如果存在非线性关系其相关系数可能为0。

import numpy as np
from scipy.stats import pearsonr
# pearson相关系数
x = np.random.uniform(-1, 1, 100000)
print('pearson_coefficient: \n', pearsonr(x, x**2))
结果为:
pearson_coefficient: 
 (0.0010892961291752092, 0.7304992616759635)
#(相关系数,P值)
#可见相关系数很低,p-value的值很高

2.3互信息(Mutual Information)与最大信息系数(Maximal Information Coefficient)
参考博客:
互信息到最大信息系数
最大信息系数的计算步骤
互信息MI:
在这里插入图片描述
x,y是两个随机变量,p(x, y)是联合概率密度。
互信息的弊端:没有实现归一化。

最大信息系数MIC:
联合概率密度p(x, y)怎么来求:要求两个随机变量的联合概率密度是很难的,现有一个思想:将x,y绘制成散点图,然后将这个散点图划分成若干个区域,用每个区域内的样本数量比上样本总数代替该区域的联合概率。[具体实现请参考上面的博客]
所以互信息可以近似为下式:
在这里插入图片描述
进行归一化得到MIC:
在这里插入图片描述
前面有一个限制条件,就是|X||Y|<B,也就是说,所有的方格格总数不能大于B。很遗憾,作者说,B取数据总量的0.6或者0.55次方。
MIC可以用来衡量两个变量之间的线性和非线性的关系。在数据集比较庞大时,MIC的值比较准确,MIC的值越大代表关系越深,MIC的最大值为1。
例子:

# MIC最大信息系数
x = np.linspace(-100, 100, 10000)
# print(x)
y1 = x**2+2*x-10
y2 = np.sin(x)-np.cos(x)
y3 = np.log2(np.abs(x))
# alpha为(0,1]或者>=4的数。
# 如果alpha取(0,1]之间的数,那么B等于max(n^alpha,4),n为样本总数
# 如果alpha取>=4的数,在alpha小于样本数量n时B=alpha,在alpha大于样本数量n时B=n,所以B=min(alpha,n)
# c定义每个分区的块数多于多少个,默认值为15,意味着算法以15*x个块开始。
mine = MINE(alpha=0.6, c=15)
mine.compute_score(x, y1)
print('MIC1: \n', mine.mic())
mine.compute_score(x, y2)
print('MIC2: \n', mine.mic())
mine.compute_score(x, y3)
print('MIC3: \n', mine.mic())
# pearson相关系数
print('p1: \n', pearsonr(x, y1))
print('p2: \n', pearsonr(x, y2))
print('p3: \n', pearsonr(x, y3))
结果为:
MIC1: 
 1.0000000000000009
MIC2: 
 1.0000000000000002
MIC3: 
 1.0000000000000009
p1: 
 (0.03869695521094821, 0.0001085404386170752)
p2: 
 (-0.015107890106580745, 0.13086837910943744)
p3: 
 (1.0488329251751482e-16, 1.0)

可见对于各种曲线,pearson相关系数几乎为0要么很小,而最大信息系数MIC都为1效果很好。

2.4距离相关系数
参考博客:距离相关系数
如果变量x和变量y的pearson相关系数为0那只能证明它们之间不存在线性关系不能证明它们独立,如果它们之间的距离相关系数也为0,那么它们就是独立的。
例子:

from scipy.spatial.distance import pdist, squareform
import numpy as np
from numbapro import jit, float32
def distcorr(X, Y):
    """ Compute the distance correlation function
    
    >>> a = [1,2,3,4,5]
    >>> b = np.array([1,2,9,4,4])
    >>> distcorr(a, b)
    0.762676242417
    """
    X = np.atleast_1d(X)
    Y = np.atleast_1d(Y)
    if np.prod(X.shape) == len(X):
        X = X[:, None]
    if np.prod(Y.shape) == len(Y):
        Y = Y[:, None]
    X = np.atleast_2d(X)
    Y = np.atleast_2d(Y)
    n = X.shape[0]
    if Y.shape[0] != X.shape[0]:
        raise ValueError('Number of samples must match')
    a = squareform(pdist(X))
    b = squareform(pdist(Y))
    A = a - a.mean(axis=0)[None, :] - a.mean(axis=1)[:, None] + a.mean()
    B = b - b.mean(axis=0)[None, :] - b.mean(axis=1)[:, None] + b.mean()
    
    dcov2_xy = (A * B).sum()/float(n * n)
    dcov2_xx = (A * A).sum()/float(n * n)
    dcov2_yy = (B * B).sum()/float(n * n)
    dcor = np.sqrt(dcov2_xy)/np.sqrt(np.sqrt(dcov2_xx) * np.sqrt(dcov2_yy))
    return dcor
x = np.linspace(-100, 100, 100)
y = np.log2(np.abs(x))
print('p: \n', pearsonr(x, y))
print(‘dcorr: \n’, distcorr(x, y))
结果
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值