【ML学习笔记】特征工程到底是什么?

学习思路主要参考这篇文章http://www.cnblogs.com/jasonfreak/p/5448385.html,侵删

只是花了半天的时间把文章中的程序重新敲了一遍,程序不长,遇到的一些问题和想法都记在了注释里,下面直接上代码。



#特征工程的基本步骤
#需要安装numpy、scipy、sklearn这三个包
#下面的很多语句都没有改变任何变量的内容,如果要看结果,应当取其返回值
#由于不会造轮子,下面我们选择来当一个调包侠


##########################################一、导入数据###########################################
from sklearn.datasets import load_iris
#导入鸢尾花数据集,内置
iris = load_iris()
#输入特征4维,输出特征3维
#特征矩阵
iris.data
#目标向量
iris.target



##########################################二、数据预处理##########################################
########################无量纲化############################
#标准化:和平均值还有方差比
#而这里用到的fit_tranform就是一个贼牛逼的函数了,上天它比天还高,下海它比海更大,几乎每个预处理的步骤后面都有它,关于这个函数的解释看这里https://blog.csdn.net/weixin_38278334/article/details/82971752
from sklearn.preprocessing import StandardScaler
StandardScaler().fit_transform(iris.data)

#缩放化:和最大值还有最小值比
from sklearn.preprocessing import MinMaxScaler
MinMaxScaler().fit_transform(iris.data)

#归一化:按照特征矩阵的行处理数据,也就是将行转化为单位向量
from sklearn.preprocessing import Normalizer
Normalizer().fit_transform(iris.data)


####################对定量特征二值化########################
#设定阈值,非0即1
from sklearn.preprocessing import Binarizer
Binarizer(threshold=3).fit_transform(iris.data)


#####################对定性特征哑编码#######################
#这里的特征是定量特征,所以用目标值哑编码,其实是不需要的,就是看看这个函数
from sklearn.preprocessing import OneHotEncoder
OneHotEncoder().fit_transform(iris.target.reshape((-1,1)))


#######################缺失值计算###########################
#我们在这边手动造一个特征值,然后再补充它,因为原数据集没有缺失
from numpy import vstack,array,nan
from sklearn.preprocessing import Imputer
#缺失值计算,返回值为计算缺失值后的数据
#参数missing_value为缺失值的表示形式,默认为NaN
#参数strategy为缺失值填充方式,默认为mean(均值)
#vstack是numpy的内置方法,表示对两个数组竖着联合
Imputer().fit_transform(vstack((array([nan,nan,nan,nan]),iris.data)))


########################数据变换############################
#用于提高模型的复杂度,4个特征,度位2的多项式转换是15维的

#多项式转换
from sklearn.preprocessing import PolynomialFeatures
PolynomialFeatures().fit_transform(iris.data)

#对数转换
from numpy import log1p
from sklearn.preprocessing import FunctionTransformer
#自定义转换函数为对数函数的数据变换
#第一个参数是单变元函数
FunctionTransformer(log1p).fit_transform(iris.data)



#####################################三、特征选择################################
#通常,从两个方面考虑来选择特征
#特征是否发散,如果特征的方差很小,也就是大家在这个特征上都差不多,那么就不要它了
#特征与目标的相关性
#根据特征选择的形式又可以将特征方法分为过滤法、包装法、嵌入法三种

########################过滤法##########################
#按照发散性或相关性对各个特征进行评分,设定阈值或者待选择阈值的个数,选择特征

#方差选择法:返回值为特征选择后的数据,参数threshold为方差的阈值,阈值不同,返回的维数也不同(只返回大于阈值的那些维)
from sklearn.feature_selection import VarianceThreshold
VarianceThreshold(threshold=2).fit_transform(iris.data)

#相关系数法:计算各个特征对目标值的相关系数
from sklearn.feature_selection import SelectKBest
from scipy.stats import pearsonr
#选择k个最好的特征,返回选择特征后的数据
#Pearson相关系数可以反映两个向量之间的相似程度,这里用来衡量特征与类别之间的相关关系。最内层的lambda函数的输入是输入特征的一维,取转置(X.T)之后和目标向量求相关,pearsonr的返回值是二维的,我们只要第一维,所以转置后取零
#SelectKBest函数的两个参数分别为函数和选择特征的个数
SelectKBest(lambda X, Y: array(list(map(lambda x:pearsonr(x, Y), X.T))).T[0], k=2).fit_transform(iris.data,iris.target)

#卡方检验:经典的卡方检验是检验定性自变量对定性因变量的相关性
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
#这个和上一个的区别就是换了一个检验函数
SelectKBest(chi2,k=2).fit_transform(iris.data,iris.target)

#互信息法:计算x和y之间的互信息量
from sklearn.feature_selection import SelectKBest
from minepy import MINE
#这里还是使用python的内置模块,MINE可以用于计算互信息量,但MINE().mic()方法不接收参数,需要先执行别的方法,也就是说MINE的设计不是函数式的,定义mic方法将其为函数式的
def mic(x, y):
    m = MINE()
    m.compute_score(x, y)
    return m.mic()
#其他的跟上面都一样
SelectKBest(lambda X, Y: array(list(map(lambda x:mic(x, Y), X.T))).T, k=2).fit_transform(iris.data,iris.target)


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

#递归特征消除法:使用一个基模型进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练
from sklearn.feature_selection import RFE
from sklearn.linear_model import LogisticRegression
#这里选择逻辑斯蒂函数作为基函数,选择的特征数目为2
RFE(estimator = LogisticRegression(),n_features_to_select = 2).fit_transform(iris.data,iris.target)


#########################嵌入法#########################
#先使用某些机器学习的算法和模型进行训练,得到各个特征的权值系数,根据系数从大到小选择特征。类似于过滤器方法,但是是通过训练来确定特征的优劣

#基于惩罚项的特征选择法
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
#如前所述,需要一个基模型,这里使用带L1惩罚项的逻辑斯蒂回归作为基模型的特征选择
SelectFromModel(LogisticRegression(penalty = 'l1',C = 0.1)).fit_transform(iris.data,iris.target)

#基于树模型的特征选择法
from sklearn.feature_selection import SelectFromModel
from sklearn.ensemble import GradientBoostingClassifier
#这里跟上面的区别就是换一个基模型,用的主要函数都是一样的
SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data,iris.target)



#####################################四、降维################################
#常见的降维方法有主成分分析法(PCA)和线性判别分析(LDA),其本质是将最原始的样本映射到维度更低的样本空间中
#这里我们还是做调包侠
#插播一个问题:第三部分的特征选择也是减少特征的维数,它和降维有什么区别呢?答案看这里https://www.cnblogs.com/Yiutto/articles/5025891.html

#PCA:让映射的对象具有最大的发散性。对特征矩阵进行特征值或奇异值分解,在降低特征个数的前提下最大限度地保留原数据的信息,是一种无监督降维
from sklearn.decomposition import PCA
#n_components是特征数
PCA(n_components = 2).fit_transform(iris.data)

#LDA:让映射后的样本具有最好的分类性能。根据目标向量对特征矩阵中的行进行分类,选择这样的投影方式,使得类内方差最小,类间方差最大,是一种监督降维
from sklearn.lda import LDA
LDA(n_components = 2).fit_transform(iris.data,iris.target)



#总结:俗言道,数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限。由于本文只涉及特征工程的工作,代码就到此为止。特征工程主要包括数据预处理、特征提取、降维等。




还是从最上面那篇文章里,有张图感觉总结得很好

猜你喜欢

转载自blog.csdn.net/weixin_39655021/article/details/86559661
今日推荐