特征选择和特征降维

1 目录结构


特征选择

特征降维

sklearn中的特征选择和降维方法的使用

针对于titanic数据集做特征选择与降维



2. 特征选择 https://scikit-learn.org/stable/modules/feature_selection.html#feature-selection

何时开始做特征选择呢?

当数据预处理完成后,我们需要选择有意义的特征输入机器学习的算法和模型进行训练。通常来说,从两个方面考虑来选择特征:

特征是否发散:如果一个特征不发散,例如方差接近于0,也就是说样本在这个特征上基本上没有差异,这个特征对于样本的区分并没有什么用。

特征与目标的相关性:这点比较显见,与目标相关性高的特征,应当优选选择。除方差法外,接下来我要介绍的都是从相关性来考虑的。

分为三种:

1、过滤法: 不用考虑后续学习器,按照发散性或者相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,选择特征。

2、包装法:需考虑后续学习器,根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征。

3、嵌入法:是过滤法与包装法方法的结合。先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。

过滤法(filter)

方差选择法

使用方差选择法,先要计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征。使用feature_selection库的VarianceThreshold类来选择特征的代码如下:

from sklearn.datasets import load_iris
iris = load_iris()##数据
from sklearn.feature_selection import VarianceThreshold#导入方差阈值
#方差选择法,返回值为特征选择后的数据
#参数threshold为方差的阈值
x1 = VarianceThreshold(threshold=3).fit_transform(iris.data)
x1.shape

单变量做特征

单变量特征选择能够对每一个特征进行测试,衡量该特征和目标变量之间的关系,根据得分扔掉不好的特征。对于回归和分类问题可以采用卡方检验等方式对特征进行测试。

方法简单,易于运行,易于理解,通常对于理解数据有较好的效果(但对特征优化、提高泛化能力来说不一定有效);这种方法有许多改进的版本、变种。

1708277760920.png

卡方检验适用于分类问题
检验特征对标签的相关性,选择其中K个与标签最相关的特征。使用feature_selection库SelectKBest类结合卡方检验来选择特征的代码如下:(这个就是自变量与因变量的相关性的取值,注意k的取值)

from sklearn.feature_selection import SelectKBest##选择最好的几个特征
from sklearn.feature_selection import chi2#卡方检验

#选择K个最好的特征,返回选择特征后的数据
x2 = SelectKBest(chi2, k=1).fit_transform(iris.data,iris.target)

除此之外针对于过滤法还有皮尔狲系数、距离相关系数

包装法(wrapper)

包装法主要思想是:根据目标函数(通常是预测效果评分),每次选择若干特征,或者排除若干特征

递归特征消除法

递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。使用feature_selection库的RFE类来选择特征的代码如下:

from sklearn.feature_selection import RFE#递归特征消除法
from sklearn.linear_model import LogisticRegression

#递归特征消除法,返回特征选择后的数据
#参数estimator为基模型
#参数n_features_to_select为选择的特征个数
x3 = RFE(estimator=LogisticRegression(), n_features_to_select=3).fit_transform(iris.data,iris.target)

Embedded

嵌入法主要思想是:使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。类似于Filter方法,但是是通过训练来确定特征的优劣。其实是讲在确定模型的过程中,挑选出那些对模型的训练有重要意义的属性。

基于惩罚项的特征选择法

使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维。使用feature_selection库的SelectFromModel类结合带L1惩罚项的逻辑回归模型,来选择特征的代码如下:

from sklearn.feature_selection import SelectFromModel##基模型选择器
from sklearn.linear_model import LogisticRegression

#带L1惩罚项的逻辑回归作为基模型的特征选择
x4 = SelectFromModel(LogisticRegression(penalty="l1", C=0.1)).fit_transform(iris.data,iris.target)
# x4
from sklearn.svm import LinearSVC
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel
iris = load_iris()
X, y = iris.data, iris.target
X.shape
lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X,y)#先训练好,然后再来选特征
model = SelectFromModel(lsvc, prefit=True)
X_new = model.transform(X)
X_new.shape

L1惩罚项降维的原理在于保留多个对目标值具有同等相关性的特征中的一个,所以没选到的特征不代表不重要。故可结合L2惩罚项来优化

基于树模型的特征选择法

树模型中GBDT可用来作为基模型进行特征选择,使用feature_selection库的SelectFromModel类结合GBDT模型,来选择特征的代码如下:

from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier#导入GBDT算法

#GBDT作为基模型的特征选择
x5 = SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)
# x5
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectFromModel
iris = load_iris()
X, y = iris.data, iris.target
clf = RandomForestClassifier()
clf = clf.fit(X, y)
clf.feature_importances_ # 显示每一个特征的重要性指标,越大说明越重要,可以看出,第三第四两个特
# 征比较重要
# SelectFromModel(RandomForestClassifier()).fit_transform(X,y)###和特征重要性一样的

针对于boston房价画一个基于随机森林算法的特征重要性图

##导入相应的包
from sklearn.ensemble import RandomForestRegressor
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_boston
boston = load_boston()##
##数据的划分
x, y = boston.data, boston.target
feature_name = np.array(["%d %s"%(b,a) for a,b in zip(boston.feature_names,range(len(boston.feature_names)))])
##模型的训练
rf = RandomForestRegressor(n_estimators=100, random_state=101).fit(x,y)
importance = np.mean([tree.feature_importances_ for tree in rf.estimators_], axis=0)
std = np.std([ tree.feature_importances_ for tree in rf.estimators_],axis=0)

indices = np.argsort(importance)#返回由小到大的数据之前的索引
range_ = range(len(importance))
##画图
plt.figure()
plt.title("random forset importance")
plt.barh(range_, importance[indices],color='r',xerr=std[indices],alpha=1,align='center')
plt.yticks(range(len(importance)),feature_name[indices])
plt.ylim([-1,len(importance)])
plt.xlim([0.0,0.65])
plt.show()
image.png

降维 https://scikit-learn.org/stable/modules/decomposition.html#pca

PCA

LDA

当特征选择完成后,可以直接训练模型了,但是可能由于特征矩阵过大,导致计算量大,训练时间长的问题,因此降低特征矩阵维度也是必不可少的。常见的降维方法除了以上提到的基于L1惩罚项的模型以外,另外还有主成分分析法(PCA)和线性判别分析(LDA),线性判别分析本身也是一个分类模型。PCA和LDA有很多的相似点,其本质是要将原始的样本映射到维度更低的样本空间中,但是PCA和LDA的映射目标不一样:PCA是为了让映射后的样本具有最大的发散性;而LDA是为了让映射后的样本有最好的分类性能。所以说PCA是一种无监督的降维方法,而LDA是一种有监督的降维方法。

PCA的理解
设有m条n维数据。

1)将原始数据按列组成n行m列矩阵X

2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值

3)求出协方差矩阵

4)求出协方差矩阵的特征值及对应的特征向量

5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P

6)即为降维到k维后的数据</font>

使用decomposition库的PCA类选择特征的代码如下:

from sklearn.decomposition import PCA
#主成分分析法,返回降维后的数据
#参数n_components为主成分数目,你要保留的维度
PCA(n_components=3).fit_transform(iris.data)
from sklearn.decomposition import PCA,KernelPCA
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris_data = load_iris()
category = pd.Categorical(iris_data.target) # 将标签进行量化,就是说本来都是字符串啊,但是最后计算的
# 时候都需要量化成1,2,3类等
pca_2c = PCA(n_components=2) # 使用PCA降到2维
#pca_2c = KernelPCA(n_components=2)
x_pca_2c = pca_2c.fit_transform(iris_data.data)
print(x_pca_2c.shape)
plt.scatter(x_pca_2c[:,0],x_pca_2c[:,1],c=category.codes)##x,y,类别不一致的颜色
plt.show()
image.png

线性判别分析(LDA)有监督的降维方法

1708625466045.png
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
#线性判别分析法,返回降维后的数据
#参数n_components为降维后的维数
LDA(n_components=2).fit_transform(iris.data, iris.target)##最大的不同
##LDA相较于pca是有监督的,但不能用于回归分析
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
iris_data = load_iris()
category = pd.Categorical(iris_data.target) # 将标签进行量化,就是说本来都是字符串啊,但是最后计算的
##时候都需要量化成1,2,3类等
lda_2c = LDA(n_components=2)
x_pca_2c = lda_2c.fit_transform(iris_data.data,iris_data.target)
x_pca_2c.shape
plt.scatter(x_pca_2c[:,0],x_pca_2c[:,1],c=category.codes)
plt.show()
image.png

针对于titanic数据集做特征选择与降维

import pandas as pd
import numpy as np

def read_dataset(fname):
#     指定第一列作为行索引
    data = pd.read_csv(fname, index_col=0)
#     丢弃无用数据
    data.drop(['Name', 'Ticket', 'Cabin'], axis=1, inplace=True)
#     处理性别数据
    lables = data['Sex'].unique().tolist()#变成列表的意思
    data['Sex'] = [*map(lambda x: lables.index(x) , data['Sex'])]
#     处理登船港口数据## sklearn里面的labelencoder
    lables = data['Embarked'].unique().tolist()
    data['Embarked'] = data['Embarked'].apply(lambda n: lables.index(n))
#     处理缺失数据填充0
    data = data.fillna(0)
    return data
train = read_dataset("data/train.csv")
import warnings
warnings.filterwarnings("ignore")#过滤掉警告的意思

先划分数据集 特征和标签

1708625647002.png
1708625696895.jpg
1708625732470.png
1708625788683.png
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,125评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,293评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,054评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,077评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,096评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,062评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,988评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,817评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,266评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,486评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,646评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,375评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,974评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,621评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,796评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,642评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,538评论 2 352

推荐阅读更多精彩内容