蒸汽预测赛题之数据探索
天池大赛比赛地址:链接
理论知识
- 连续性变量 需要统计数据的中心分布趋势和变量的分布
- 类别变量 统计频次(次数)和频率(占比)
- 连续型和连续型变量分析
- 绘制散点图 scatter
- 相关性计算
- 取值[-1,1] 负数表示负线性相关 0表示不相关
- cor = np.corrcoef(x,y) 返回的是2x2的array数组 取第一行第二个数
- 类别型和类别型
- 双向表 通过建立频次和频率的双向表
- 堆叠柱状图 比较直观
- 卡方检验 主要用于两个和两个以上样本 及 两个二值型离散变量的相关性分析
- from sklearn.feature_selection import chi2
- chi2(x,y)
- 类别型和连续型
- 小提琴图 sns.violinplot()
- 缺失值处理方法
- 成列删除 删除任何变量丢失的结果
- 成对删除 删除对应的缺失值
- 均值mean、众数mode、中值填充meadin
- 预测模型填充
- 异常值检验
- 箱线图 boxplot
- plt.boxplot(data,labels=lables)
- sns.boxplot(train_data[columns_name[i]],orient=‘v’,width=0.5)
- 散点图 scatter
- plt.scatter(x, y,marker=‘x’)
- plt.plot(tmp_data[var],tmp_data[‘target’],’.’,alpha=0.5)
- df = pd.DataFrame({‘x’: x, ‘y’: y}) sns.jointplot(x=“x”, y=“y”, data=df, kind=‘scatter’);
- 直方图 displot
- sns.distplot(train_data[col],fit=stats.norm)
- 核密度 kdeplot
- sns.jointplot(x=“total_bill”, y=“tip”, data=tips, kind=‘kde’)
- sns.kedplot(test_data[col],color=“blue”,shade=True)
- 箱线图 boxplot
- 异常值处理方法
- 删除
- 转换 对数转换
- 填充
- 区别对待 另成一组
- 变量转换
- 对数变化 通常用于向右倾的分布 不能用于含有0或负值的变量
- 取平方根或立方根
- 变量分组 类似于onehot
- 变量生成
- 派生变量
- 哑变量 类似onehot
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
2. 查看数据
train_data_file = "../datasets/zhengqi_train.txt"
test_data_file = "../datasets/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')
train_data.describe()
train_data.head()
3. 画出所有特征字段的箱形图(boxplot)
columns_name = train_data.columns.tolist()[:-1]
plt.figure(figsize=(50,80),dpi=75)
for i in range(len(columns_name)):
# 总共8行5列
plt.subplot(8,5,i+1)
# orient 代表方向 h横 v竖
sns.boxplot(train_data[columns_name[i]],orient='v',width=0.5)
plt.ylabel(columns_name[i],fontsize=36)
plt.show()
4. 直方图(displot)和Q-Q图(stats.proplot)
# 如果字段的分布近似于正态分布 数据在Q-Q图中随对角线分布
# 画布中一行4列子图 row_nums行
col_nums = 6
row_nums = len(columns_name)
plt.figure(figsize=(4*col_nums,6*row_nums))
i = 0
for col in train_data.columns:
i+=1
ax = plt.subplot(row_nums,col_nums,i)
sns.distplot(train_data[col],fit=stats.norm)
i+=1
ax = plt.subplot(row_nums,col_nums,i)
res = stats.probplot(train_data[col],plot=plt)
plt.show()
5. 在训练集和测试集的KDE分布图(kdeplot)
col_nums = 4
row_nums = len(columns_name)
plt.figure(figsize=(4*col_nums,4*row_nums))
i = 0
for col in test_data.columns:
i+=1
plt.subplot(row_nums,col_nums,i)
ax = sns.kdeplot(train_data[col],color="red",shade=True)
ax = sns.kedplot(test_data[col],color="blue",shade=True)
ax.set_xlabel(col)
ax.set_ylabel("Frequency")
ax = ax.legend(["train","test"])
plt.show()
# v5、v9、v11、v17、v22、v28字段在训练集和测试集的分布不一致 泛化能力差 需要删除这些特征
6. 线性回归关系图(regplot)
col_nums = 4
row_nums = len(columns_name)
plt.figure(figsize=(4*col_nums,4*row_nums))
i = 0
for col in train_data.columns:
i+=1
plt.subplot(row_nums,col_nums,i)
sns.regplot(x=col,y="target",data=train_data, scatter_kws={"marker":"+","s":3,"alpha":0.5}, line_kws={"color":"k"})
plt.xlabel(col)
plt.ylabel("target")
plt.show()
7. 字段之间相关性(corr) 和 热力图(heatmap)
# 删除 测试集和训练集分布不同的特征值
train_data1 = train_data.drop(['V5','V9','V11','V17','V22','V28'],axis=1)
train_corr = train_data1.corr()
pd.set_option('display.max_columns',10)
pd.set_option('display.max_rows',10)
print(train_corr)
plt.figure(figsize=(20,16))
# vmax最大值 annot显示相关系数
# sns.heatmap(train_corr,vmax=.8,square=True,annot=True)
# 寻找k个与target变量最相关的特征变量
k = 10
top_feature_k = train_corr.nlargest(k,'target')['target'].index
plt.figure(figsize=(5,5),dpi=150)
sns.heatmap(train_data1[top_feature_k].corr(),square=True,annot=True)
# 找与target变量相关性 绝对值大于0.5的
cols_abs = train_corr.index[abs(train_corr['target'])>0.5]
#sns.heatmap(train_data1[cols_abs].corr(),square=True,annot=True,cmap="RdYlGn")
8. 归一化处理
def scale_minmax(col):
return (col-col.min())/(col.max()-col.min())
col_numeric = train_data1.columns[:-1]
print(col_numeric)
train_data_process = train_data1[col_numeric].apply(scale_minmax,axis=0)
test_data_process = test_data[col_numeric].apply(scale_minmax,axis=0)
train_data_process.describe()
9. Box-Cox变换(stats.boxcox)
fcols = 6
frows = len(col_numeric)
plt.figure(figsize=(4*fcols,4*frows))
train_data_process = pd.concat([train_data_process,train_data1['target']],axis=1)
i = 0
for var in col_numeric:
tmp_data = train_data_process[[var,'target']]
i+=1
plt.subplot(frows,fcols,i)
sns.distplot(tmp_data[var],fit=stats.norm)
plt.title(var + ' Original')
plt.xlabel('')
i+=1
plt.subplot(frows,fcols,i)
_ = stats.probplot(tmp_data[var],plot=plt)
# skew 偏斜值
plt.title('skew = '+'{:.4f}'.format(stats.skew(tmp_data[var])))
plt.xlabel('')
plt.ylabel('')
i+=1
plt.subplot(frows,fcols,i)
plt.plot(tmp_data[var],tmp_data['target'],'.',alpha=0.5)
plt.title('corr = '+'{:.2f}'.format(np.corrcoef(tmp_data[var],tmp_data['target'])[0][1]))
#boxcox 要求传入的数据是正的 所以+1
trains_var,lambda_var = stats.boxcox(tmp_data[var]+1)
trans_var = scale_minmax(trains_var)
i+=1
plt.subplot(frows,fcols,i)
sns.distplot(trans_var,fit=stats.norm)
plt.title(var + ' Transformed')
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,tmp_data['target'],'+',alpha=0.5)
plt.title('corr = '+'{:.2f}'.format(np.corrcoef(trans_var,tmp_data['target'])[0][1]))