特征工程是将原始数据转换为更好地代表预测模型的潜在问题的特征的过程,从而提高对未知数据预测的准确性;
跨行业数据挖掘标准流程:
- 商业理解
- 数据理解
- 数据准备 → 特征工程(for数据挖掘)
- 构建模型
- 模型评估
- 模型发布
特征工程的目的:通过一系列的工程活动, 将这些信息使用更高效的编码方式(特征)表示;
特征工程的重要性:好数据(好特征)> 多数据 > 好算法 → 数据和特征决定了模型预测的上线,算法只是逼近这个上线而已;
好的特征:模型选择的特征数量少而精准;
一、特征提取
- 文本数据的特征提取(词袋模型,TF-IDF等);
- 图像数据的特征提取:RGB的值(像素+颜色);
- 用户行为特征(RFM);
- 通过特征提取能得到未经处理的特征;
二、特征处理
1、缺失值数据处理
- 不处理:决策树,随机森林;
- 删除:缺失比例比较高;
删除行:不要改变数据的分布;
删除列 - 填充:
根据经验填充;
从统计角度进行填充:连续型(均值,中位数,0),离散型(众数);
算法进行填充:随机森林;
2、无量纲化
a、标准化:前提特征服从正态分布;
from sklearn.datasets import load_iris
iris = load_iris()
iris.feature_names # 特征
iris.target # 标签
#标准化
from sklearn.preprocessing import StandardScaler
StandardScaler().fit_transform(iris.data)
b、区间缩放法:常见的是min-max缩放,返回值范围[0,1];
# 区间缩放
from sklearn.preprocessing import MinMaxScaler
MinMaxScaler().fit_transform(iris.data)
c、正则化:用来求相似性,求向量间的余弦值COSα,下面为L2正则化。
from sklearn.preprocessing import Normalizer
Normalizer(norm='l2').fit_transform(iris.data) # l2
Normalizer(norm='l1').fit_transform(iris.data) # l1
3、二值化
通过设定一个阈值,使得大于阈值的赋值为1,小于等于阈值的赋值为0;
from sklearn.preprocessing import Binarizer
Binarizer(threshold=3).fit_transform(iris.data) # 阈值设置为3,一个阈值对所有的特征
Binarizer(threshold=[5,3,1.5,0.2]).fit_transform(iris.data) # 不同的列用不同阈值二值化
4、编码
- LabelEncoder:序号编码,用每个数字代替每个值,对不连续的数字或文本进行编号;
- 哑编码:OneHotEncoder对数据进行哑编码;
# 线性编码
from sklearn.preprocessing import LabelEncoder
LabelEncoder().fit_transform(['a','c','b','d']) # 返回值:0,2,1,3 unicode编码顺序
# dataframe手动编码
import pandas as pd
df=pd.DataFrame([['a','青年'],['b','中年'],['c','老年']],columns=['X','Y'])
df['Y'].map({'青年':0,'中年':1,'老年':2})
# 哑变量
# get_dummies
import pandas as pd
list2=[['A', 'B', 'C'], ['B', 'C', 'A'], ['C', 'A', 'B']]
df1 = pd.DataFrame(list2)
pd.get_dummies(df1,prefix=['P1','P2','P3'])
pd.get_dummies(df1,prefix=['P1','P2','P3'],drop_first=True) # 丢掉第一列
# OneHotEncoder
from sklearn.preprocessing import OneHotEncoder
list2=[['A', 'B', 'C'], ['B', 'C', 'A'], ['C', 'A', 'B']]
OneHotEncoder(drop='first').fit_transform(list2)
OneHotEncoder(drop='first').fit_transform(list2).toarray()
5、数据变换
- 多项式特征变换(增维),目标是将特征两两组合起来,使得特征 和目标变量之间的的关系更接近线性,从而提高预测的效果;
- 多项式特征变换(增维),目标是将特征两两组合起来,使得特征 和目标变量之间的的关系更接近线性,从而提高预测的效果;
# 多项式转换
from sklearn.preprocessing import PolynomialFeatures
PolynomialFeatures(degree=2).fit_transform(iris.data).shape
# 表示去掉平方项,只留交叉项
PolynomialFeatures(degree=2,interaction_only=True).fit_transform(iris.data).shape
# 把偏置项去掉
PolynomialFeatures(degree=2,interaction_only=True,include_bias=False).fit_transform(iris.data).shape
6、降维
- 常见的降维方法有主成分分析法(PCA)和线性判别分析(LDA);
- PCA和LDA的映射目标不一样:PCA是为了让映射后的样本具有最大的发散性;LDA是为了让映射后的样本有最好的分类性能。PCA是无监督的降维方法,LDA是有监督的降维方法;
# PCA降维
from sklearn.decomposition import PCA
PCA(n_components=2).fit_transform(iris.data) # 降到2维
PCA(n_components=0.95).fit_transform(iris.data) # 保留多少的信息量
# lda降维,有监督
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
lda = LinearDiscriminantAnalysis(n_components=2)
lda.fit_transform(iris.data, iris.target)
三、特征选择
两个方面考虑选择特征:a、特征是否发散;b、特征与目标的相关性;
1、过滤法
a、Filter-1.方差选择法:先要计算各个特征的方差,然后根据阈值,选择方差大于阈值的特征;
import pandas as pd
import numpy as np
from sklearn.datasets import load_iris
from sklearn.feature_selection import VarianceThreshold
iris = load_iris()
iris_df = pd.DataFrame(iris.data,columns=iris.feature_names)
v=VarianceThreshold(threshold = 0.6) # 阈值
df1 = v.fit_transform(iris_df) # 没有列名
v.get_support() # 表示选择了哪些特征
select_feature = np.array(iris.feature_names)[v.get_support()] # 选择为true的特征
pd.DataFrame(df1,columns=select_feature)
b、 Filter-2.卡方检验法:检验自变量对因变量的相关性;
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
SelectKBest(chi2, k=3).fit_transform(iris.data, iris.target) # 选择三个特征
2、包装法
递归消除特征法:使用一个基模型来进行多轮训练,每轮训练后,根据模型的预测效果,消除若干特征,再基于新的特征集进行下一轮训练
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、嵌入法
a、基于惩罚项的特征选择法:
# 使用带惩罚项的基模型,除了筛选出特征外,同时也进行了降维
from sklearn.feature_selection import SelectFromModel
from sklearn.linear_model import LogisticRegression
# 带L2惩罚项的逻辑回归作为基模型的特征选择
SelectFromModel(LogisticRegression(penalty="l2", C=0.1,solver='liblinear')).fit_transform(iris.data, iris.target)
b、基于随机森林的特征选择:
# 嵌入法,随机森林进行特征的选择
from sklearn.ensemble import RandomForestClassifier
clf = RandomForestClassifier()
clf.fit(iris.data, iris.target)
importance = clf.feature_importances_ # 特征重要性
importance