《 数据挖掘的一般流程 》
一、 业务理解
1 业务背景
-
1. 数据说明 2. 核心特征 3. 可调参数 4. 采集时间
2 业务目标
-
1. 目标结果
3 数据概览
-
1. 数据量纲 2. 参数类别 3. 数据属性 4. 数据描述
4 评估指标
-
1. 回归:mse 2. 分类:F1 score
5 业务模型
-
1. 分类模型:决策树、随机森林 2. 回归模型:线性回归
二、数据探索
1 理论知识
1 变量识别
-
1. 输入变量、输出变量 2. 数据类型 3. 连续变量、类别变量、离散变量
2 变量分析
-
1. 单变量分析 连续变量: 集中趋势:Mean、Median、Mode、Min、Max 分散度量:Range、Quartile、IQR、Variance、Standard Deviation、Skewness and Kurtosis 可视化:Histogram(直方图)、BoxPlot(箱型图) 类别变量: 可视化:柱形图 2. 双变量分析 连续型与连续型:绘制散点图、计算相关性(皮尔逊相关系数) 类别型与类别型:双向表、卡方检验 类别型与连续型:小提琴图(seaborn中violinplot()函数) # 相关系数 import numpy as np X = np.array([65, 72, 78, 65, 72, 70, 65, 68]) Y = np.array([72, 69, 79, 69, 84, 75, 60, 73]) np.corrcoef(X, Y) # 卡方检验 from sklearn.datasets import load_iris from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 iris = load_iris() X, y = iris.data, iris.target chiValues = chi2(X, y) X_new = SelectKBest(chi2, k=2).fit_transform(X, y)
3 缺失值处理
-
1. 缺失值的产生和分类 完全随机丢失:抛硬币 随机丢失:女性年龄缺失率 不可预测因子导致的缺失:抛弃导致病人不适的诊断方法 取决于自身的缺失:收入低不愿意透露 2. 处理方法 删除:成列删除、成对删除 填充:均值、众数、中位数 模型预测填充:将数据集分为两部分,没有缺失的做训练集,缺失的做测试集
4 异常值处理
-
1. 产生的原因和影响 数据输入误差 测量误差 实验误差 人为故意误差 数据处理误差 采样误差 2. 异常值检测 可视化:箱线图(IQR:[-1.5*IQR-1.5*IQR])、直方图、散点图。 3. 异常值处理 删除:直接drop 转换:如对数转换会减轻由极值引起的变化 填充:分自然形成或人为,预测、均值、。。。 区别对待:大量缺失值,异常值为一组,非异常值为一组,分别建模。
5 变量转换
-
1. 目的 非正态分布转换为正态分布,满足模型要求 2. 方法 缩放比例、标准化 非线性转换成线性:对数变换 是倾斜分布对称:对数变换、取平方根或立方根 变量分组:收入分类低中高 onehot编码
6 新变量生成
-
1. 目的 产生的新变量与目标有更强的相关性 2. 方法 创建派生变量 创建哑变量
7 正态分布转换
-
# 选择何种方法来将非正态分布数据集转化为正态分布,需要根据数据集的特点、转换方法的优缺点、转换结果的准确性等方面进行综合考虑。一般来说,以下几种方法比较常用: 1. Box-Cox 变换:Box-Cox 变换是一种广泛应用的数据转换方法,可以将许多非正态分布转化为正态分布。Box-Cox 变换的优点是可以处理许多类型的非正态分布数据,转换后的结果比较稳定。缺点是当数据中存在负数或者零时,Box-Cox 变换无法使用。 2. Yeo-Johnson 变换:Yeo-Johnson 变换是对 Box-Cox 变换的改进,可以处理包括负数在内的任意数据集。Yeo-Johnson 变换的优点是可以处理更多类型的数据,转换结果比 Box-Cox 更稳定。缺点是计算复杂度较高,需要更长的计算时间。 3. 分位数转换:分位数转换是一种简单的数据转换方法,可以将数据分布转化为接近于正态分布的分布。分位数转换的优点是计算简单,容易理解。缺点是可能会丢失部分数据的信息。 4. 对数转换:对数转换是一种常见的数据转换方法,可以将数据分布转化为接近于正态分布的分布。对数转换的优点是计算简单,容易理解,适用于对数关系比较明显的数据。缺点是可能会丢失部分数据的信息,不能处理数据中存在负数或零的情况。 # 因此,选择何种方法需要根据数据集的特点和具体应用场景进行综合考虑,不能一概而论。在实际应用中,可以尝试多种方法进行比较,选择效果最好的方法来进行数据转换。
2 实际代码
1 查看基本信息:
-
# 查看基本信息 data.info() # 样本数、变量数、变量类型、缺失值数、内存占用 data.describe() # 行计数、均值、方差、最小值、最大值、百分位数 data.head() # 数据形式
2 箱型图
-
# 箱型图,检测异常值 colunms = train_data.columns.tolist()[:39] # 获取所有列名 fig=plt.figure(figsize=(80,60),dpi=75) # 设置画布大小 for i in range(38): plt.subplot(7,8,i+1) # 7行8列的第i+1个图 bp=sns.boxplot(train_data[colunms[i]],orient="v",width=0.5) # 箱形图 plt.ylabel(colunms[i],fontsize=16) # y轴标签 plt.show() # 存在许多偏离较大的异常值,可以考虑移除
3 异常值绘图
-
# 异常值绘图 通过岭回归找出异常值
4 直方图与Q-Q图
-
# 直方图和Q-Q图,检测非偏正态分布 trainc_cols=6 train_rows=len(train_data.columns) plt.figure(figsize=(4*trainc_cols,4*train_rows)) i=0 for col in train_data.columns: i+=1 ax=plt.subplot(train_rows,trainc_cols,i) sns.distplot(train_data[col],fit=stats.norm) i+=1 ax=plt.subplot(train_rows,trainc_cols,i+trainc_cols) res=stats.probplot(train_data[col],plot=plt) plt.tight_layout() plt.show() # 很多特征变量分布不是正态分布,需要进行转换
5 KDE核密度估计图
-
# KDE分布图,检测偏度和峰度 dist_cols=6 dist_rows=len(test_data.columns) # 训练集与测试集对比,采用测试集的列数 plt.figure(figsize=(4*dist_cols,4*dist_rows)) i=1 for col in test_data.columns: ax=plt.subplot(dist_rows,dist_cols,i) ax=sns.kdeplot(train_data[col],color='Red',shade=True) ax=sns.kdeplot(test_data[col],color='Blue',shade=True) ax.set_xlabel(col) ax.set_ylabel('Frequency') ax=ax.legend(['train','test']) i+=1 plt.show() # V5、V9、V11、V17、V22、V28在训练集与测试集当中分布不一致,这会导致模型的泛化性能下降,需要删除此类特征
6 特征与Target回归关系
-
# 线性回归关系图,检测特征与标签的线性关系 fcols = 6 frows = len(test_data.columns) plt.figure(figsize=(4*fcols,4*frows)) i=0 for col in test_data.columns: i+=1 ax=plt.subplot(frows,fcols,i) sns.regplot(x=col,y='target',data=train_data,ax=ax,scatter_kws={'marker':'.','s':3,'alpha':0.3},line_kws={'color':'k'}) plt.xlabel(col) plt.ylabel("target") i+=1 ax=plt.subplot(frows,fcols,i) sns.distplot(train_data['target'].dropna()) plt.xlabel('col') """ 这行代码使用seaborn模块的regplot函数绘制了一个以x=col和y='target'为自变量和因变量的散点图,并在散点图上拟合了一条线性回归线。具体解释如下: x=col表示将该行代码所在的列col作为自变量。 y='target'表示将'target'作为因变量。 data=train_data表示使用train_data中的数据进行绘图。 ax=ax表示将该子图添加到ax对象中,以便在多个子图中进行排列。 scatter_kws={'marker':'.', 's':3, 'alpha':0.3}表示设置散点图的样式参数。其中,marker表示散点图的标记,这里使用小圆点'.';s表示标记的大小,这里设置为3;alpha表示标记的透明度,这里设置为0.3。 line_kws={'color':'k'}表示设置拟合直线的样式参数。其中,color表示直线的颜色,这里设置为黑色'k'。 综上所述,该行代码绘制了一个以col为自变量,'target'为因变量的散点图,并在图像上拟合了一条线性回归线,同时设置了散点图和拟合直线的样式参数。 """
7 特征与变量相关系数
-
# 剔除分布不一致的相关变量后,计算剩余特征与target之间的相关系数 # 相关系数主要用于判断线性相关,对于目标target如果存在更复杂的函数形式的影响,可以用树模型的特征重要性选择 pd.set_option('display.max_columns', 10) pd.set_option('display.max_rows', 10) data_train1 = train_data.drop(['V5', 'V9', 'V11', 'V17', 'V22', 'V28'], axis=1) train_corr = data_train1.corr() train_corr # 相关系数热力图 ax = plt.subplots(figsize=(20, 16))#调整画布大小 ax = sns.heatmap(train_corr, vmax=.8, square=True, annot=True)#画热力图 annot=True 显示系数 # K个最相关特征 k = 10 cols = train_corr.nlargest(k, 'target')['target'].index # nlargest()表示取出最大的k个数值,index表示取出对应的索引 cm = np.corrcoef(train_data[cols].values.T) # 计算这k个特征变量之间的相关系数 hm = plt.subplots(figsize=(10, 10)) # 调整画布大小 hm = sns.heatmap(train_data[cols].corr(),annot=True,square=True) # 画热力图 plt.show() ## 寻找与target相关系数大于0.5的特征变量 threshold = 0.5 corrmat = train_data.corr() # 重新计算全部特征变量之间的相关系数 top_corr_features=corrmat.index[abs(corrmat["target"])>threshold] # abs()表示取绝对值 plt.figure(figsize=(10,10)) g=sns.heatmap(train_data[top_corr_features].corr(),annot=True,cmap="RdYlGn") # 画出相关系数大于0.5的特征变量之间的热力图 #用相关系数阈值移除相关特征 threshold = 0.5 corr_matrix = data_train.corr().abs() # 计算相关系数的绝对值 drop_col = corr_matrix[corr_matrix["target"]<threshold].index # 找出相关系数小于阈值的特征变量 data_train.drop(drop_col, axis=1, inplace=True) # 删除相关系数小于阈值的特征变量
8 Box-Cox变换
-
# 由于线性回归是基于正态分布的,在进行统计分析时,需要将数据转换成使其符合正态分布。 # Box-Cox变换能使得线性回归满足线性、正态性、独立性、以及方差齐性同时又不丢失信息。 # Box-Cox前需要做归一化 # 合并训练集与测试集 drop_columns = ['V5','V9','V11','V17','V22','V28'] # 合并训练和测试数据集 train_x = train_data.drop(['target'], axis=1) #data_all=pd.concat([train_data,test_data],axis=0,ignore_index=True) data_all = pd.concat([train_x,test_data]) data_all.drop(drop_columns,axis=1,inplace=True) # 对合并后的每列进行归一化 cols_numeric=list(data_all.columns) def scale_minmax(col): return (col-col.min())/(col.max()-col.min()) data_all[cols_numeric] = data_all[cols_numeric].apply(scale_minmax,axis=0) data_all[cols_numeric].describe() # 分别归一化,建立在测试集与训练集分布一致的情况下,能加快速度 train_data_process = train_data[cols_numeric] train_data_process = train_data_process[cols_numeric].apply(scale_minmax,axis=0) test_data_process = test_data[cols_numeric] test_data_process = test_data_process[cols_numeric].apply(scale_minmax,axis=0) # Box-Cox变换分析 cols_numeric_left = cols_numeric[0:13] cols_numeric_right = cols_numeric[13:] train_data_process = pd.concat([train_data_process, train_data['target']], axis=1)# 将target加入训练集(已经归一化的训练集) fcols = 6 frows = len(cols_numeric_left) plt.figure(figsize=(4 * fcols, 4 * frows)) i = 0 for var in cols_numeric_left: dat = train_data_process[[var, 'target']].dropna() i += 1 plt.subplot(frows, fcols, i) sns.distplot(dat[var], fit=stats.norm) plt.title(var + ' Original') plt.xlabel('') i += 1 plt.subplot(frows, fcols, i) _ = stats.probplot(dat[var], plot=plt) plt.title('skew=' + '{:.4f}'.format(stats.skew(dat[var]))) plt.xlabel('') plt.ylabel('') i += 1 plt.subplot(frows, fcols, i) plt.plot(dat[var], dat['target'], '.', alpha=0.5) plt.title('corr=' + '{:.2f}'.format(np.corrcoef(dat[var], dat['target'])[0][1])) i += 1 plt.subplot(frows, fcols, i) trans_var, lambda_var = stats.boxcox(dat[var].dropna() + 1) trans_var = scale_minmax(trans_var) # 应用boxcox变换后继续归一化,方便对比 sns.distplot(trans_var, fit=stats.norm) plt.title(var + ' Tramsformed') plt.xlabel('') i += 1 plt.subplot(frows, fcols, i) _ = stats.probplot(trans_var, plot=plt) plt.title('skew=' + '{:.4f}'.format(stats.skew(trans_var))) plt.xlabel('') plt.ylabel('') i += 1 plt.subplot(frows, fcols, i) plt.plot(trans_var, dat['target'], '.', alpha=0.5) plt.title('corr=' + '{:.2f}'.format(np.corrcoef(trans_var, dat['target'])[0][1]))
9 Yeo-Johnson 变换
-
# Yeo-Johnson 变换的代码可以使用 Python 中的 scipy.stats 库中的 yeojohnson 函数实现,示例如下: import numpy as np from scipy.stats import yeojohnson # 创建一个非正态分布的数据集 data = np.random.exponential(size=1000) # 对数据进行 Yeo-Johnson 变换 data_transformed, _ = yeojohnson(data) # 查看转换后的数据分布 import matplotlib.pyplot as plt plt.hist(data_transformed, bins=50) plt.show() # 在上面的示例中,使用 np.random.exponential 函数生成一个非正态分布的数据集。然后使用 yeojohnson 函数对数据进行 Yeo-Johnson 变换,得到转换后的数据集 data_transformed。最后使用 matplotlib 库中的 hist 函数绘制转换后的数据分布直方图,以查看转换效果。 # 需要注意的是,yeojohnson 函数返回的第二个参数是一个变换的指数,可以用于将新数据转换回原始数据空间。如果不需要将新数据转换回原始数据空间,可以将其忽略。
三、特征工程
1 理论知识
1 特征工程理念
-
1. 组成:特征使用、特征获取、特征处理、特征选择、特征监控 2. 说明:数据和特征决定了机器学习的上线,模型和算法只是逼近这个上限。 3. 特性:特征越好,灵活性越强,构建的模型越简单、模型的性能越出色 4. 处理逻辑:首先去掉无用特征、接着去掉冗余特征(如共线特征),并利用存在的特征、转换特征、内容中的特征以及其他数据源生成新特征,然后对特征进行转换(数值化、类别转换、归一化),最后对特征进行处理(异常值、最大值、最小值、缺失值),以符合模型使用。 5. 流程包括:数据预处理、特征处理、特征选择。
2 数据预处理
-
1. 特征采集:采集业务相关数据,对预测结果有帮助数据 2. 数据清洗: 简单属性判定:身高3m的人、一个人每月购买10w元的美发卡 组合或统计属性判定:宣称地址在美国,但消费账单都是中国 补齐可对应的缺省值:将不可信的样本丢掉,不用缺省值极多的字段 3. 数据采样 随机采样:容易不均匀 分层采样:更常用 正样本 > 负样本:量都大的情况:采用下采样。 正样本 > 负样本:量不大的情况:上采样、修改损失函数设置样本权重。
3 特征处理
-
# 特征处理的方法包括标准化、区间缩放法、归一化、定量特征二值化、定性特征哑编码、缺失值处理与数据转换。 # 归一化与标准化的使用场景 · 如果对输出结果范围有要求,则用归一化。 · 如果数据较为稳定,不存在极端的最大值或最小值,则用归一化。 · 如果数据存在异常值和较多噪声,则用标准化,这样可以通过中心化间接避免异常值与极端值的影响。 · 支持向量机、K近邻、主成分分析等模型都必须要进行归一化或者标准化。 1. 标准化 from sklearn.preprocessing import StandardScaler from sklearn.datasets import load_iris iris = load_iris() #标准化,返回值为标准化后的数据 StandardScaler().fit_transform(iris.data) 2. 区间缩放法 from sklearn.preprocessing import MinMaxScaler #区间缩放,返回值为缩放到[0, 1]区间的数据 MinMaxScaler().fit_transform(iris.data) 3. 归一化 from sklearn.preprocessing import Normalizer #归一化,返回值为归一化后的数据 Normalizer().fit_transform(iris.data) 4. 定量特征二值化 from sklearn.preprocessing import Binarizer #二值化,阈值设置为3,返回值为二值化后的数据 Binarizer(threshold=3).fit_transform(iris.data) 5. 定性特征哑变量 from sklearn.preprocessing import OneHotEncoder #哑编码,对IRIS数据集的目标值,返回值为哑编码后的数据 OneHotEncoder(categories='auto').fit_transform(iris.target.reshape((-1,1))) 6. 缺失值处理 from numpy import vstack, array, nan from sklearn.impute import SimpleImputer #缺失值计算,返回值为计算缺失值后的数据 #参数missing_value为缺失值的表示形式,默认为NaN #参数strategy为缺失值填充方式,默认为mean(均值) SimpleImputer().fit_transform(vstack((array([nan, nan, nan, nan]), iris.data))) 7. 数据转换 #多项式转换 #参数degree为度,默认值为2 from sklearn.preprocessing import PolynomialFeatures PolynomialFeatures().fit_transform(iris.data) #对数变换 from numpy import log1p from sklearn.preprocessing import FunctionTransformer #自定义转换函数为对数函数的数据变换 #第一个参数是单变元函数 FunctionTransformer(log1p, validate=False).fit_transform(iris.data)
4 特征选择
-
# 特征选择的方法有:过滤法(Filter)、包装法(Wrapper)和嵌入法(Embedded) · 过滤法:按照发散性或者相关性对各个特征进行评分,通过设定阈值或者选择个数来选择特征。 :思路:特征变量与目标变量之间的关系 :方法:相关系数、卡方检验、信息增益、互信息 · 包装法:根据目标函数(通常是预测效果评分)每次选择若干特征,或者排除若干特征。 :思路:通过目标函数(AUC/MSE)决定是否加入一个变量 :方法:迭代(产生特征子集、评价)--->完全搜索、启发搜索、随机搜索(遗传算法和模拟退火算法) · 嵌入法:使用机器学习的某些算法和模型进行训练,得到各个特征的权值系数,并根据系数从大到小选择特征。通过训练确定特征优劣。 :思路:学习器自身自动选择特征 :方法:正则化(L1,L2)、决策树(熵、信息增益)、深度学习 # 特征选择 1. 方差选择法 from sklearn.feature_selection import VarianceThreshold from sklearn.datasets import load_iris iris = load_iris() #方差选择法,返回值为特征选择后的数据 #参数threshold为方差的阈值 VarianceThreshold(threshold=3).fit_transform(iris.data) 2. 相关系数法 import numpy as np from sklearn.datasets import load_iris iris = load_iris() from array import array from sklearn.feature_selection import SelectKBest from scipy.stats import pearsonr #选择K个最好的特征,返回选择特征后的数据 #第一个参数为计算评估特征是否好的函数,该函数输入特征矩阵和目标向量,输出二元组(评分,P值)的数组,数组第i项为第i个特征的评分和P值。在此定义为计算相关系数 #参数k为选择的特征个数 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. 卡方检验 from sklearn.datasets import load_iris iris = load_iris() from sklearn.feature_selection import SelectKBest from sklearn.feature_selection import chi2 #选择K个最好的特征,返回选择特征后的数据 SelectKBest(chi2, k=2).fit_transform(iris.data, iris.target) 4. 互信息法 import numpy as np 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个最好的特征,返回特征选择后的数据 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) 5. RFE(递归特征消除法) from sklearn.feature_selection import RFE from sklearn.linear_model import LogisticRegression #递归特征消除法,返回特征选择后的数据 #参数estimator为基模型 #参数n_features_to_select为选择的特征个数 RFE(estimator=LogisticRegression(multi_class='auto',solver='lbfgs',max_iter=500),n_features_to_select=2).fit_transform(iris.data, iris.target) 6. 基于L1/L2惩罚项的特征选择法 from sklearn.feature_selection import SelectFromModel from sklearn.linear_model import LogisticRegression #带L1惩罚项的逻辑回归作为基模型的特征选择 SelectFromModel(LogisticRegression(penalty='l2', C=0.1, solver='lbfgs',multi_class='auto')).fit_transform( iris.data, iris.target) 7. 基于树模型的特征选择法 from sklearn.feature_selection import SelectFromModel from sklearn.ensemble import GradientBoostingClassifier # GBDT作为基模型的特征选择 SelectFromModel(GradientBoostingClassifier()).fit_transform(iris.data,iris.target) 8. 主成分分析法 from sklearn.decomposition import PCA #主成分分析法,返回降维后的数据 #参数n_components为主成分数目 PCA(n_components=2).fit_transform(iris.data) 9. 线性判别分析法 from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA #线性判别分析法,返回降维后的数据 #参数n_components为降维后的维数 LDA(n_components=2).fit_transform(iris.data, iris.target)
5 多重共线性分析
-
# 多重共线性是指在多元线性回归模型中,自变量之间存在高度相关性的情况。多重共线性可能会对回归系数的稳定性、精确性和解释性产生影响,从而影响模型的质量和可解释性。下面介绍一些常用的多重共线性分析方法: 1. 相关系数:通过计算自变量之间的相关系数,可以初步判断自变量之间是否存在高度相关性。如果某些自变量之间的相关系数较高,可能存在多重共线性的问题。 2. 方差膨胀因子(VIF):方差膨胀因子是一种衡量多重共线性的方法,它反映了每个自变量在多元线性回归模型中的方差相对于没有多重共线性时方差的增加程度。通常认为,如果某个自变量的 VIF 值大于 10,就存在多重共线性的问题。 3. 特征值分解:特征值分解是一种数学方法,可以将多元线性回归模型中的自变量之间的相关性转化为特征值矩阵。通过计算特征值,可以判断自变量之间是否存在多重共线性问题。 4. 岭回归:岭回归是一种通过引入正则化项来解决多重共线性问题的方法。岭回归可以通过调整正则化参数的值,控制回归系数的大小,从而减少多重共线性对模型的影响。 5. 偏最小二乘回归:偏最小二乘法(Partial Least Squares,简称 PLS)是一种经典的多元统计分析方法,可以在应对多重共线性的同时,同时进行特征提取和预测建模。PLS 通过将自变量和因变量分别投影到新的低维空间中,从而降低自变量之间的相关性,提高预测模型的预测精度。PLS 可以被看作是一种同时进行多重共线性分析和建模的方法。在实际应用中,PLS 可以作为一种特征提取和建模方法,用于处理高维数据、多重共线性和预测问题,例如化学工业、生物医学、金融等领域。 需要注意的是,PLS 方法的稳定性和可解释性可能会受到多种因素的影响,例如选择的模型参数、采样方法、数据质量等。因此,在使用 PLS 方法时,需要进行充分的数据预处理、模型选择和交叉验证,以确保模型的稳定性和可解释性。
2 实际代码
1 异常值剔除
-
import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns from scipy import stats import warnings warnings.filterwarnings("ignore") %matplotlib inline train_data_file = "./zhengqi_train.txt" test_data_file = "./zhengqi_test.txt" train_data = pd.read_csv(train_data_file, sep='\t', encoding='utf-8') test_data = pd.read_csv(test_data_file, sep='\t', encoding='utf-8') plt.figure(figsize=(18, 10)) plt.boxplot(x=train_data.values,labels=train_data.columns) plt.hlines([-7.5, 7.5], 0, 40, colors='r') plt.show() pd.set_option('display.max_columns',6) train_data = train_data[train_data['V9']>-7.5] # 删除异常值 test_data = test_data[test_data['V9']>-7.5] display(train_data.describe()) display(test_data.describe())
2 归一化
-
from sklearn import preprocessing features_columns = [col for col in train_data.columns if col not in ['target']] min_max_scaler = preprocessing.MinMaxScaler() min_max_scaler = min_max_scaler.fit(train_data[features_columns]) train_data_scaler = min_max_scaler.transform(train_data[features_columns]) test_data_scaler = min_max_scaler.transform(test_data[features_columns]) train_data_scaler = pd.DataFrame(train_data_scaler) train_data_scaler.columns = features_columns test_data_scaler = pd.DataFrame(test_data_scaler) test_data_scaler.columns = features_columns train_data_scaler['target'] = train_data['target'] display(train_data_scaler.describe()) display(test_data_scaler.describe())
3 可视化分布(核密度估计)
-
drop_col = 6 drop_row = 1 plt.figure(figsize=(5 * drop_col, 5 * drop_row)) for i, col in enumerate(["V5", "V9", "V11", "V17", "V22", "V28"]): ax = plt.subplot(drop_row, drop_col, i + 1) ax = sns.kdeplot(train_data_scaler[col], color="Red", shade=True) ax = sns.kdeplot(test_data_scaler[col], color="Blue", shade=True) ax.set_xlabel(col) ax.set_ylabel("Frequency") ax = ax.legend(["train", "test"]) plt.show()
4 可视化特征相关性(斯皮尔曼相关系数)
-
plt.figure(figsize=(20, 16)) column = train_data_scaler.columns.tolist() mcorr = train_data_scaler[column].corr(method="spearman") mask = np.zeros_like(mcorr, dtype=np.bool) mask[np.triu_indices_from(mask)] = True cmap = sns.diverging_palette(220, 10, as_cmap=True) g = sns.heatmap(mcorr, mask=mask, cmap=cmap, square=True, annot=True, fmt='0.2f') plt.show() # 特征相关性初筛 mcorr=mcorr.abs() numerical_corr=mcorr[mcorr['target']>0.1]['target'] print(numerical_corr.sort_values(ascending=False))
5 多重共线性分析
-
from statsmodels.stats.outliers_influence import variance_inflation_factor # 多重共线性方差膨胀因子 #多重共线性 new_numerical=['V0', 'V2', 'V3', 'V4', 'V5', 'V6', 'V10','V11', 'V13', 'V15', 'V16', 'V18', 'V19', 'V20', 'V22','V24','V30', 'V31', 'V37'] X=np.matrix(train_data_scaler[new_numerical]) VIF_list=[variance_inflation_factor(X, i) for i in range(X.shape[1])] VIF_list pd.set_option('display.max_columns',6)
6 PCA降维筛选
-
# 阈值筛选 pca = PCA(n_components=0.95) new_train_pca_16 = pca.fit_transform(train_data_scaler.iloc[:,0:-1]) new_test_pca_16 = pca.transform(test_data_scaler) new_train_pca_16 = pd.DataFrame(new_train_pca_16) new_test_pca_16 = pd.DataFrame(new_test_pca_16) new_train_pca_16['target'] = train_data_scaler['target'] new_train_pca_16.describe() # 特征数目筛选 pca = PCA(n_components=16) new_train_pca_16 = pca.fit_transform(train_data_scaler.iloc[:,0:-1]) new_test_pca_16 = pca.transform(test_data_scaler) new_train_pca_16 = pd.DataFrame(new_train_pca_16) new_test_pca_16 = pd.DataFrame(new_test_pca_16) new_train_pca_16['target'] = train_data_scaler['target'] new_train_pca_16.describe()