包含几个大的模块:
1、异常值分析-绘制各个特征的箱线图
2、归一化
3、查看数据分布-绘制KDE分布图
4、计算特征相关性,以热力图形式可视化显示和多重共线性分析(计算方差膨胀系数)
5、特征降维:
(1)特征相关性的初筛,计算相关性系数并筛选大于0.1的特征变量
(2)利用PCA方法去除数据的多重共线性,并进行降维
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy import stats
import warnings
from sklearn.decomposition import PCA #主成分分析法
from sklearn.linear_model import Ridge
from sklearn.metrics import mean_squared_error
from sklearn import preprocessing
from statsmodels.stats.outliers_influence import variance_inflation_factor #多重共线性方差膨胀因子
warnings.filterwarnings("ignore")
pd.set_option('display.max_columns', 6)
# 读取数据
train_data_file = ".//data//zhengqi_train.txt"
test_data_file = ".//data//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')
print("训练集数据信息:")
# 查看训练集数据信息
print(train_data.shape)
# 查看训练集数据字段
# print(train_data.head(3))
###################################################
# 异常值分析
# 绘制各个特征的箱线图
plt.figure(figsize=(18, 10))
plt.boxplot(x=train_data.values, labels=train_data.columns)
'''
plt.hlines(y, xmin, xmax, colors='k', linestyles='solid', label='', data=None)
其中,参数含义如下:
y:线的y轴坐标
xmin:线段的起始x轴坐标
xmax:线段的终止x轴坐标
colors:线段颜色,默认为黑色
linestyles:线段样式,可选实线、虚线、点线等,有多种样式
label:线段标签,用于图例展示
data:数据来源,默认为None
'''
plt.hlines([-7.5, 7.5], 0, 40, colors='r')
plt.savefig("./images/各个特征的箱线图.png")
plt.show()
# 从箱线图可以看出,有些特征存在明显的异常值,如V9变量。下面分别对训练集和测试集中的异常值删除
train_data = train_data[train_data['V9'] > -7.5]
test_data = test_data[test_data['V9'] > -7.5]
##########################################################
# 最大值和最小值的归一化
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']
print(train_data_scaler.describe())
print(test_data_scaler.describe())
####################################################
# 查看数据分布
# KDE(Kernel Density Estimation,核密度估计)可以理解为对直方图的加窗平滑。
# 通过绘制KDE分布图,可以查看并对比训练集和测试集中特征变量的分布情况,发现两个数据集中分布不一致的特征变量。
# 对比所有变量在训练集和测试集中的KDE分布
# 通过KDE分布对比了特征变量在两个数据集中的分布情况,
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.savefig("./images/部分特征的箱线图.png")
plt.show()
# 对比后发现:特征变量V5,V9,V11,V17,V22,V28在训练集和测试集中的分布差异较大,会影响模型的泛化能力,
# 故删除这些特征
# train_data_scaler.drop(["V5", "V9", "V11", "V17", "V22", "V28"], axis=1, inplace=True)
# test_data_scaler.drop(["V5", "V9", "V11", "V17", "V22", "V28"], axis=1, inplace=True)
####################################################################################
# 特征相关性
# 计算特征相关性,以热力图形式可视化显示
plt.figure(figsize=(20, 16))
column = train_data_scaler.columns.tolist()
# corr()括号里面没有填参数时默认是皮尔逊相关系数,corr(method = 'pearson');
# corr(method = 'spearman'),斯皮尔曼等级相关系数,用来分析非正态分布的数据;
# corr(method = 'kendall'),秩相关系数,用来分析两定序变量相关关系;
mcorr = train_data_scaler[column].corr(method="spearman")
mask = np.zeros_like(mcorr, dtype=np.bool) # np.zeros_like(a)的目的是构建一个与a同维度的数组,并初始化所有变量为零(False)。
mask[np.triu_indices_from(mask)] = True # np.triu_indices_from() 返回方阵的上三角矩阵的索引
'''
seaborn.diverging_palette(h_neg, h_pos, s=75, l=50, sep=10, n=6, center='light', as_cmap=False):
在两个 HUSL 颜色直接建立一个发散调色板。
参数:
h_neg, h_pos:float in [0, 359]:图的正负范围的锚定色调
as_cmap:bool, 可选:如果为 true,返回一个 matplotlib colormap 而不是一个颜色列表。
'''
cmap = sns.diverging_palette(220, 10, as_cmap=True) # 蓝-白-红
'''
heatmap():热力图,识别预测变量与目标变量相关性的方法,同时,也是发现变量间是否存在多重共线性的好方法。
mask:布尔数组或者DataFrame数据,可选参数
如果为空值,数据将不会显示在mask为True的单元格中。 具有缺失值的单元格将自动被屏蔽
cmap:matplotlib 颜色条名称或者对象,或者是颜色列表,可选参数
从数据值到颜色空间的映射。
square:布尔值,可选参数
如果为True,则将坐标轴方向设置为“equal”,以使每个单元格为方形
annot:布尔值或者矩形数据,可选参数
如果为True,则在每个热力图单元格中写入数据值。如果数组的形状与data相同,则使用它来代替原始数据注释热力图
fmt:字符串,可选参数
添加注释时要使用的字符串格式代码
'''
g = sns.heatmap(mcorr, mask=mask, cmap=cmap, square=True, annot=True, fmt='0.2f')
plt.savefig("./images/特征相关性热力图.png")
plt.show()
#####################################################################
# 特征降维
# 特征相关性的初筛,计算相关性系数并筛选大于0.1的特征变量
mcorr = mcorr.abs()
numerical_corr = mcorr[mcorr['target'] > 0.1]['target']
print(numerical_corr.sort_values(ascending=False))
# 对相关性系数进行排序显示
index0 = numerical_corr.sort_values(ascending=False).index
print(index0)
print("corr:\n", train_data_scaler[index0].corr('spearman')) # 交换列的顺序,再计算
####################################################################
# 多重共线性分析
# 多重共线性:是指各特征之间存在线性相关关系,即一个特征可以是其他一个或几个特征的线性组合。如果存在多重共线性,
# 求损失函数时矩阵会不可逆,导致求出结果会与实际不同,有所偏差。
# 多重共线性分析的原则是特征组之间的相关性系数较大,即特征变量之间的相关性系数较大,故可能存在较大的共线性影响,
# 这会导致模型估计不准确。
# 对数据进行多重共线性计算
# new_numerical的特征变量可以自行根据相关性矩阵看出并过滤筛选
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]) # numpy.matrix(data,dtype,copy):返回一个矩阵
'''
variance_inflation_factor() 计算方差膨胀系数
方差膨胀系数是衡量多元线性回归模型中多重共线性严重程度的一种度量。是指解释变量之间存在多重共线性时的方差与不存在多重共线性时的方差之比。
每个自变量都会有一个膨胀因子值,最后根据值的大小来选择是否删减
VIF越大,显示共线性越严重。经验判断方法表明:当0<VIF<10,不存在多重共线性;当10≤VIF<100,存在较强的多重共线性;当VIF≥100,存在严重多重共线性。
'''
VIF_list = [variance_inflation_factor(X, i) for i in range(X.shape[1])] # i是第i列
print('VIF_list:\n', VIF_list)
######################################################################################
# PCA处理
# 利用PCA方法去除数据的多重共线性,并进行降维。PCA处理后可保持90%的信息数据
# 主成分分析进行特征降维(会损失一部分信息)
# n_components可以指定0-1之间的小数(推荐0.9-0.95之间),表示信息保留量的百分比。 (推荐)
# n_components也可以指定整数,表示保留的特征数量。
# 1、n_components指定为小数
pca = PCA(n_components=0.9) # 保持90%的信息
new_train_pca_90 = pca.fit_transform(train_data_scaler.iloc[:, 0:-1])
new_test_pca_90 = pca.transform(test_data_scaler)
new_train_pca_90 = pd.DataFrame(new_train_pca_90)
new_test_pca_90 = pd.DataFrame(new_test_pca_90)
new_train_pca_90['target'] = train_data_scaler['target']
print(new_train_pca_90.describe())
print(train_data_scaler.describe())
# 2、n_components指定为整数
pca = PCA(n_components=16) # PCA处理后保留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']
print(new_train_pca_16.describe())
输出:
各个特征的箱线图.png
部分特征的KDE图.png
特征相关性热力图.png