特征工程

it2022-05-05  181

文章目录

1.特征工程2.数据预处理2.1 无量纲化2.2 对定量特征二值化2.3 对定性特征哑编码2.4 缺失值计算2.5 数据变换 3.特征选择3.1 Filter3.2 Wrapper3.3 Embedded 4 降维4.1 主成分分析法(PCA)4.2 线性判别分析法(LDA)

1.特征工程

使用sklearn做单机特征工程 数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已 sklearn中的IRIS(鸢尾花)数据集来对特征处理

from sklearn.datasets import load_iris #导入IRIS数据集 iris = load_iris() #特征矩阵 iris.data #目标向量 iris.target

使用sklearn做单机特征工程

2.数据预处理

2.1 无量纲化

无量纲化方法

标准化 :前提是特征值服从正态分布,标准化后,其转换成标准正态分布区间缩放法 :利用了边界值信息,将特征的取值区间缩放到某个特点的范围,例如[0, 1]

2.1.1 标准化 标准化需要计算特征的均值和标准差,公式表达为: x ′ = x − X ‾ S x^{\prime}=\frac{x-\overline{X}}{S} x=SxX

from sklearn.preprocessing import StandardScaler #标准化,返回值为标准化后的数据 StandardScaler().fit_transform(iris.data)

2.1.2区间缩放法 利用两个最值进行缩放,公式表达为: x ′ = x − M i n M a x − M i n x^{\prime}=\frac{x-M i n}{M a x-M i n} x=MaxMinxMin

from sklearn.preprocessing import MinMaxScaler #区间缩放,返回值为缩放到[0, 1]区间的数据 MinMaxScaler().fit_transform(iris.data)

2.1.3 标准化与归一化的区别 标准化:依照特征矩阵的列处理数据,其通过求Z-score的方法,将样本的特征值转换到同一量纲下。 归一化:依照特征矩阵的行处理数据,其目的在于样本向量在点成运算或其他和函数计算相似性时,拥有同一的标准,即都转化为“单位向量”。规则为l2的归一化公式如下: x ′ = x ∑ j m x [ j ] 2 x^{\prime}=\frac{x}{\sqrt{\sum_{j}^{m} x[j]^{2}}} x=jmx[j]2 x

from sklearn.preprocessing import Normalizer #归一化,返回值为归一化后的数据 Normalizer().fit_transform(iris.data)

2.2 对定量特征二值化

定量特征二值化的核心在于设定一个阈值,大于阈值的赋值为1,小于等于阈值的赋值为0,公式表达如下: x ′ = { 1 , x >  threshold  0 , x ≤  threshold  x^{\prime}=\left\{\begin{array}{l}{1, x>\text { threshold }} \\ {0, x \leq \text { threshold }}\end{array}\right. x={1,x> threshold 0,x threshold 

from sklearn.preprocessing import Binarizer #二值化,阈值设置为3,返回值为二值化后的数据 Binarizer(threshold=3).fit_transform(iris.data)

2.3 对定性特征哑编码

由于IRIS数据集的特征皆为定量特征,故使用其目标值进行哑编码

from sklearn.preprocessing import OneHotEncoder #哑编码,对IRIS数据集的目标值,返回值为哑编码后的数据 OneHotEncoder().fit_transform(iris.target.reshape((-1,1)))

2.4 缺失值计算

由于IRIS数据集没有缺失值,故对数据集新增一个样本,4个特征均赋值为NaN,表示数据缺失

from numpy import vstack, array, nan from sklearn.preprocessing import Imputer #缺失值计算,返回值为计算缺失值后的数据 #参数missing_value为缺失值的表示形式,默认为NaN #参数strategy为缺失值填充方式,默认为mean(均值) Imputer().fit_transform(vstack((array([nan, nan, nan, nan]), iris.data)))

2.5 数据变换

数据变换有基于多项式的、基于指数函数的、基于对数函数的

from sklearn.preprocessing import PolynomialFeatures #多项式转换 #参数degree为度,默认值为2 PolynomialFeatures().fit_transform(iris.data) from numpy import log1p from sklearn.preprocessing import FunctionTransformer #自定义转换函数为对数函数的数据变换 #第一个参数是单变元函数 FunctionTransformer(log1p).fit_transform(iris.data)

3.特征选择

3.1 Filter

3.1.1 方差选择法 计算各个特征的方差 => 根据阈值,选择方差大于阈值的特征

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

3.1.2 相关系数法 计算各个特征对目标值的相关系数以及相关系数的P值 => SelectKBest类结合相关系数来选择特征的代码

from sklearn.feature_selection import SelectKBest from scipy.stats import pearsonr #选择K个最好的特征,返回选择特征后的数据 #第一个参数为计算评估特征是否好的函数,该函数输入特征矩阵和目标向量,输出二元组(评分,P值)的数组,数组第i项为第i个特征的评分和P值。在此定义为计算相关系数 #参数k为选择的特征个数 m = SelectKBest(lambda X,Y:np.array(list(map(lambda x:pearsonr(x, Y), X.T))).T[0], k=2).fit_transform(iris.data, iris.target)

3.1.3 卡方检验 检验定性自变量对定性因变量的相关性 假设自变量有N种取值,因变量有M种取值,考虑自变量等于i且因变量等于j的样本频数的观察值与期望的差距,构建统计量: χ 2 = ∑ ( A − E ) 2 E \chi^{2}=\sum \frac{(A-E)^{2}}{E} χ2=E(AE)2

from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 #选择K个最好的特征,返回选择特征后的数据 SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target)

3.1.4 互信息法 评价定性自变量对定性因变量的相关性 I ( X ; Y ) = ∑ x ∈ X ∑ y ∈ Y p ( x , y ) log ⁡ p ( x , y ) p ( x ) p ( y ) I(X ; Y)=\sum_{x \in X} \sum_{y \in Y} p(x, y) \log \frac{p(x, y)}{p(x) p(y)} I(X;Y)=xXyYp(x,y)logp(x)p(y)p(x,y)

from sklearn.feature_selection import SelectKBest from minepy import MINE #由于MINE的设计不是函数式的,定义mic方法将其为函数式的, #返回一个二元组,二元组的第2项设置成固定的P值0.5 def mic(x, y): m = MINE() m.compute_score(x, y) return (m.mic(), 0.5) #选择K个最好的特征,返回特征选择后的数据 m = SelectKBest(lambda X,Y:np.array(list(map(lambda x:mic(x, Y), X.T))).T[0], k=2).fit_transform(iris.data, iris.target)

3.2 Wrapper

3.2.1 递归特征消除法 递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,消除若干权值系数的特征,再基于新的特征集进行下一轮训练。

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

3.3 Embedded

3.3.1 基于惩罚项的特征选择法 使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维

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)

可结合L2惩罚项来优化。具体操作为:若一个特征在L1中的权值为1,选择在L2中权值差别不大且在L1中权值为0的特征构成同类集合,将这一集合中的特征平分L1中的权值,故需要构建一个新的逻辑回归模型:

from sklearn.linear_model import LogisticRegression class LR(LogisticRegression): def __init__(self, threshold=0.01, dual=False, tol=1e-4, C=1.0, fit_intercept=True, intercept_scaling=1, class_weight=None, random_state=None, solver='liblinear', max_iter=100, multi_class='ovr', verbose=0, warm_start=False, n_jobs=1): #权值相近的阈值 self.threshold = threshold LogisticRegression.__init__(self, penalty='l1', dual=dual, tol=tol, C=C, fit_intercept=fit_intercept, intercept_scaling=intercept_scaling, class_weight=class_weight, random_state=random_state, solver=solver, max_iter=max_iter, multi_class=multi_class, verbose=verbose, warm_start=warm_start, n_jobs=n_jobs) #使用同样的参数创建L2逻辑回归 self.l2 = LogisticRegression(penalty='l2', dual=dual, tol=tol, C=C, fit_intercept=fit_intercept, intercept_scaling=intercept_scaling, class_weight = class_weight, random_state=random_state, solver=solver, max_iter=max_iter, multi_class=multi_class, verbose=verbose, warm_start=warm_start, n_jobs=n_jobs) def fit(self, X, y, sample_weight=None): #训练L1逻辑回归 super(LR, self).fit(X, y, sample_weight=sample_weight) self.coef_old_ = self.coef_.copy() #训练L2逻辑回归 self.l2.fit(X, y, sample_weight=sample_weight) cntOfRow, cntOfCol = self.coef_.shape #权值系数矩阵的行数对应目标值的种类数目 for i in range(cntOfRow): for j in range(cntOfCol): coef = self.coef_[i][j] #L1逻辑回归的权值系数不为0 if coef != 0: idx = [j] #对应在L2逻辑回归中的权值系数 coef1 = self.l2.coef_[i][j] for k in range(cntOfCol): coef2 = self.l2.coef_[i][k] #在L2逻辑回归中,权值系数之差小于设定的阈值,且在L1中对应的权值为0 if abs(coef1-coef2) < self.threshold and j != k and self.coef_[i][k] == 0: idx.append(k) #计算这一类特征的权值系数均值 mean = coef / len(idx) self.coef_[i][idx] = mean return self

结合带L1以及L2惩罚项的逻辑回归模型来选择特征:

from sklearn.feature_selection import SelectFromModel #带L1和L2惩罚项的逻辑回归作为基模型的特征选择 #参数threshold为权值系数之差的阈值 SelectFromModel(LR(threshold=0.5, C=0.1)).fit_transform(iris.data, iris.target)

3.3.2 基于树模型的特征选择法  树模型中GBDT也可用来作为基模型进行特征选择

from sklearn.feature_selection import SelectFromModel from sklearn.ensemble import GradientBoostingClassifier #GBDT作为树模型的特征选择 SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data, iris.target)

4 降维

4.1 主成分分析法(PCA)

from sklearn.decomposition import PCA #主成分分析法,返回降维后的数据 #参数n_components为主成分数目 PCA(n_components=2).fit_transform(iris.data)

4.2 线性判别分析法(LDA)

from sklearn.lda import LDA #线性判别分析法,返回降维后的数据 #参数n_components为降维后的维数 LDA(n_components=2).fit_transform(iris.data, iris.target)

最新回复(0)