数据预处理
数据EDA
数据可视化 数据离散和连续性分析
数据加载相关的包
import pandas as pd
import numpy as np
防止部分警告
import warnings
warnings.filterwarnings("ignore")
数据可视化
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False # 用来正常显示负号
数据的标签处理
from sklearn.preprocessing import LabelEncoder
卡方检验
from sklearn.feature_selection import chi2
from sklearn.feature_selection import SelectKBest
train_data = pd.read_csv('data/first_round_training_data.csv')
1、数据探索(数据EDA)
获取数据信息
train_data.info()
由上信息可以得到,此数据 共 6000 条,21列, 无空值, 除标签 Quality_label 这一列 数据类型全为
float64
train_data.head()
数据离散性和连续性分析
获取列名
col_name = train_data.drop(['Quality_label'], 1).columns
Notdlts_count = []
for i in col_name:
# 计算非重复值的个数
Notdlts = len(train_data[i].drop_duplicates()) / 6000 # 如果没有重复的 计算结果是1 有重复的结果就不是1 比1小
Notdlts_count.append(Notdlts)
plt.plot(col_name, Notdlts_count, c='r')
plt.title('非重复值的总数计算') # 标题
plt.xlabel('列名') # x轴 的轴名
plt.ylabel('非重复数据在全数据上的占比') # y轴 的轴名
plt.xticks(rotation=45) # 旋转 x轴的刻度名
plt.show()
得到的结论是什么?由上图可得Parameter 5 - 10基本为离散特征,而 Attribute4 - 10,有可能是离散特征, 其余均为连续特征提取出全部的特征
unit = train_data.drop(['Quality_label'], 1)
数据的分布差异(对应于(pandas_profiling)中的警告(skew))
遍历列名
通过直方图进行操作
for i in col_name:
plt.hist(unit[i], bins=20)
plt.title('%s 平均分割取值范围计数统计图' % i)
plt.xlabel('%s范围' % i)
plt.ylabel('值在该范围的个数')
plt.show()
这里得到的结论是什么?
由以上图表可以看出大部分的值全部聚集在左侧(靠近于0),分布不均匀数据分布不均衡 - -接下来要怎么做?–去偏 开根号 取对数
数据的离散程度–看数据的标准差
获取列名
col_name = unit.columns
### 计算 标准差(std)
col_std = unit.describe().T['std']
plt.plot(col_name, col_std, c='red') # 作图
plt.title('列 - 标准差') # 标题
plt.xlabel('列名') # x轴 的轴名
plt.ylabel('标准差') # y轴 的轴名
plt.xticks(rotation=45) # 旋转 x轴的刻度名
plt.show()
得到结论:由上图可得: 列Attribute10标准差太高,导致无法明显分辨其他列的标准差怎么做?–>开根号还是取对数?
数据的标签处理
lb = LabelEncoder()
train_data["Quality_label"] = lb.fit_transform(train_data["Quality_label"])
拿到数据之后的常规操作也是要必须进行的操作—都是要和背景相关的东西与知识相结合一起来做
2、特征工程–>为了解决(数据探索性分析所出现的问题)–结合背景来做,知识点也就那么一点
去偏:解决办法:通过 开N方(取2,3,4都可以,不建议过大,这里以 4为例) 的方式,将 0-1 的值增大,并缩小 大于1的值
unit[col_name] = unit[col_name] ** (1 / 4)
遍历列名
for i in col_name:
plt.hist(unit[i], bins=20)
plt.title('%s 平均分割取值范围计数统计图' % i)
plt.xlabel('%s范围' % i)
plt.ylabel('值在该范围的个数')
plt.show()
去除数据的标准差
解决办法: 将标准差进行开N次方,再观察图像
此处选择 开4次方 (一般在2-10之间)
plt.plot(col_name, col_std ** (1 / 4), c='g') # 作图
plt.plot(col_name, 10 * np.ones((1, 20))[0], c='m', linestyle="--")
plt.title('列 - 标准差') # 标题
plt.xlabel('列名') # x轴 的轴名
plt.ylabel('标准差') # y轴 的轴名
plt.xticks(rotation=90) # 旋转 x轴的刻度名
plt.legend(['标准差', '等高线:10'])
plt.show()
通过观察可以看出 绝大多数列 的标准差已经突破1e4(10, 000)
解决方法:因为全部的特征取值范围都要 > 0, 所以可以通过log变换,但为了不影响接近于0的小数故因为当 x --> 0时, 有 ln(x + 1) --> x所以:np.log() 默认底数为 e
unit[col_name] = np.log(unit[col_name] + 1)
计算变换后的 标准差(std)
col_log_std = unit[col_name].describe().T['std']
plt.plot(col_name, col_log_std, c='red') # 作图
plt.title('列 - 标准差') # 标题
plt.xlabel('列名') # x轴 的轴名
plt.ylabel('标准差') # y轴 的轴名
plt.xticks(rotation=90) # 旋转 x轴的刻度名
plt.show()
从图中可以明显看出
数据的标准差已经稳定在[0, 1]
这个范围内了, 说明
log变换
很成功
特征归一化
for i in unit.columns:
unit[i] = (unit[i] - unit[i].min()) / (unit[i].max() - unit[i].min())
特征选择
# 设置卡方检验,选择k=2个最佳特征
test = SelectKBest(score_func=chi2, k=14) ##选择成最后的十四个特征
# 进行检验
fit = test.fit(unit, train_data['Quality_label'])
# 打印卡方检验值
print(fit.scores_)
train = pd.DataFrame(fit.transform(unit), columns=['V{0}'.format(i) for i in range(1, 15)])
train.head()