单变量统计
方差分析
在单变量统计中,我们计算每个特征和目标值之间的关系是否存在统计显著性,然后选择具有最高置信度的特征。对于分类问题,这也被称为方差分析(analysis of variance,ANOVA)。
这些测试的一个关键性质就是它们是单变量的(univariate),即它们只单独考虑每个特征。因此,如果一个特征只有在与另一个特征合并时才具有信息量,那么这个特征将被舍弃。
单变量测试的计算速度通常很快,并且不需要构建模型。另一方面,它们完全独立于你可能想要在特征选择之后应用的模型。
注意:不需要构建模型,利用纯理论的数学思维去构建出来
想要在 scikit-learn 中使用单变量特征选择,你需要选择一项测试——对分类问题通常是 f_classif(默认值),对回归问题通常是 f_regression——然后基于测试中确定的 p 值来选择一种舍弃特征的方法。所有舍弃参数的方法都使用阈值来舍弃所有 p 值过大的特征(意味着它们不可能与目标值相关)。计算阈值的方法各有不同,最简单的是 SelectKBest和 SelectPercentile,前者选择固定数量的 k 个特征,后者选择固定百分比的特征。
代码实现
from sklearn.feature_selection import SelectPercentile select=SelectPercentile(percentile=50) #选取50%的特征 select.fit(X_train,y_train) X_train_selected=select.transform(X_train) print(X_train.shape) print(X_train_selected.shape)
案例分析
import numpy as np from sklearn.datasets import load_breast_cancer from sklearn.feature_selection import SelectPercentile #SelectPercentile选择百分比,SelectKBest选择个数 from sklearn.model_selection import train_test_split #使用sklearn自带的数据集 cancer=load_breast_cancer() #向数据中添加噪声特征,前30个特征来自原数据集,后50个是噪声 rng=np.random.RandomState(42) #构造噪声特征 noise=rng.normal(size=(len(cancer.data),50)) X_w_noise=np.hstack([cancer.data,noise]) #分割数据集用于测试和训练 X_train,X_test,y_train,y_test=train_test_split(X_w_noise,cancer.target,random_state=0,test_size=.5) #特征选取 select=SelectPercentile(percentile=50) #选取50%的特征 select.fit(X_train,y_train) X_train_selected=select.transform(X_train) print(X_train.shape) print(X_train_selected.shape)
import pandas as pd import numpy as np # 分类常用的 from sklearn.feature_selection import SelectKBest,f_classif,chi2,mutual_info_classif # 分别是卡方检验,计算非负特征和类之间的卡方统计 chi # 样本方差F值,f_classif # 离散类别交互信息, mutual_info_classif # 回归常用的 from sklearn.feature_selection import f_regression,mutual_info_regression
很明显的就发现特征变化了,而且是50%,还可以看看那些特征被选取
#查看哪些特征被选中 mask=select.get_support() print(mask) import matplotlib.pyplot as plt plt.matshow(mask.reshape(1,-1),cmap='gray_r') plt.xlabel('sample index') plt.show()
这一类的特征选取方法比较的直接,也就是说直接保留多少占比的特征数量,在某些时候的模型训练中,我们需要根据特征的权重进行自定义的筛选。
SelectKBest特征选取
这类选取方法和相关系数选取比较的相似,可以通过这些对象的得分,选取重要的数据列
selector= SelectKBest(score_func= chi2,k=len(X.columns)) selector.fit(X,y) score=-np.log10(selector.pvalues_) # print(score) score_index=np.argsort(score)[::-1] for i in range(len(score)): print("%0.2f %s"%(score[score_index[i]],X.columns[score_index[i]]))
上述的数值大小代表着特征的重要性(下面有一个完整的代码实例)
from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 from sklearn.datasets import load_iris import pandas as pd from sklearn.preprocessing import MinMaxScaler from scipy.stats import chi2_contingency import numpy as np model = SelectKBest(chi2, k=8)#选择k个最佳特征 X_new = model.fit_transform(X, y) #feature_data是特征数据,label_data是标签数据,该函数可以选择出k个特征 print("model shape: ",X_new.shape) scores = model.scores_ print('model scores:', scores) # 得分越高,特征越重要 p_values = model.pvalues_ print('model p-values', p_values) # p-values 越小,置信度越高,特征越重要 # 按重要性排序,选出最重要的 k 个 indices = np.argsort(scores)[::-1] k_best_features = list(X.columns.values[indices[0:8]]) print('k best features are:\n ',k_best_features) print(k_best_features)
简而言之,使用SelectKBest选取,可以调整里面的参数值,最终确定最重要的几个特征