机器学习项目实战(工业蒸汽之数据探索)

注:某些图片截取了一部分,不完整。
核心要领通过各种对数据进行可视化,分析数据特征,进行增删改(包括缺失值处理,删除影响模型泛化的数据,进行数据变换从而更好地满足模型的假设条件,数据归一化等)。
除了数据本身的进行可视化描述,还可以将数据集和训练集进行比较。

导入数据的工具包

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#%matplotlib inline 可以在Ipython编译器里直接使用,功能是可以内嵌绘图,并且可以省略掉plt.show()这一步。

读取数据文件

使用Pandas库read_csv()函数进行数据读取,分割符为‘\t’

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')

数据查看(略)

查看数据后,说明多少个特征变量啊,有没有缺失值啊,或者哪些是数值变量,哪些是标签变量啊。找不同点嘛。

画箱图探索。

画箱型图从而对数据进行分析。

一个箱型图

fig=plt.figure(figsize=(4,6))
sns.boxplot(train_data['V0'],orient='v',width=0.5)


all

columns=train_data.columns.tolist()[:39]#由train_data.head()知道是5rows*39
fig=plt.figure(figsize=(10,20))#调整绘图对象宽高
for i in range(39):
 plt.subplot(13,3,i+1)#39个图分成13*3
 sns.boxplot(train_data[columns[i]],orient='v',width=0.5)
 plt.ylabel(columns[i],fontsize=8)
plt.show()


结果发现我也看不太来,meybe没有什么规律,题解也没说有什么规律。所以换个图来画画,再发现一下?

查看数据分布图

查看特征变量v0的数据分布直方图,并绘制Q-Q图看是否近似于正态分布。
each

fig=plt.figure(figsize=(10,5))
ax=plt.subplot(1,2,1)
sns.distplot(train_data['V0'],fit=stats.norm)#districution 分布直方图
ax=plt.subplot(1,2,2)
res=stats.probplot(train_data['V0'],plot=plt)


查看查看所有数据的直方图和Q-Q图,查看训练集的数据是否近似于正态分布

train_cols=6
train_rows=len(train_data.columns)
plt.figure(figsize=(4*train_cols,4*train_rows))
i=1
for col in train_data.columns:
 ax=plt.subplot(train_rows,train_cols,i)
 sns.distplot(train_data[col],fit=stats.norm)
 i+=1
 ax=plt.subplot(train_rows,train_cols,i)
 res=stats.probplot(train_data[col],plot=plt)
 i+=1
plt.show()


由上面的数据分布图信息可以看出,很多特征变量(如'V1','V9','V24','V28'等)的数据分布不是正态的,数据并不跟随对角线,后续可以使用数据变换对数据进行转换

对比一下训练集和验证集的数据分布情况是否一致

ax = sns.kdeplot(train_data['V0'], color="Red", shade=True)
ax = sns.kdeplot(test_data['V0'], color="Blue", shade=True)
ax.set_xlabel('V0')
ax.set_ylabel("Frequency")
ax = ax.legend(["train","test"])


查看所有特征变量下,测试集和数据集的分布情况,分析并寻找出数据不一致的特征变量

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', 'V17', 'V28', 'V22', 'V11', 'V9'数据的数据分布

drop_col = 6
drop_row = 1
plt.figure(figsize=(5*drop_col,5*drop_row))
i=1
for col in ["V5","V9","V11","V17","V22","V28"]:
 ax =plt.subplot(drop_row,drop_col,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' ,训练集和数据集分布不一致,会导致模型泛化能力差,so删除此类特征。

drop_columns = ['V5','V9','V11','V17','V22','V28']

#合并训练集和测试集数据,并可视化训练集和测试集数据特征分布图(i can't understand.好像没啥luanyong)

画个线性回归图和直方图看看所有特征量和target之间的关系呢。

(果然,发现没有任何关系)
特征'v0'和特征量'target'之间的特征关系。

fcols=2
frows=1
plt.figure(figsize=(8,4))
ax=plt.subplot(1,2,1)
sns.regplot(x='V0', y='target', data=train_data, ax=ax, 
 scatter_kws={'marker':'.','s':3,'alpha':0.3},
 line_kws={'color':'k'});#regplot就是regressionplot,线性回归拟合模型绘图
plt.xlabel('v0')
plt.ylabel('target')
ax=plt.subplot(1,2,2)
sns.distplot(train_data['V0'].dropna())
plt.xlabel('v0')
plt.show()


然后画出所有特征量和'target'之间的直方图和线性回归图瞅瞅。

fcols=6
frows=len(test_data.columns)
plt.figure(figsize=(5*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[col].dropna())
 plt.xlabel(col)

发现,果然没啥关系。
没关系,我们再来看看特征变量的相关性。

特征变量相关性。

data_train1=train_data.drop(['V5','V9','V11','V17','V22','V28'],axis=1)#先除去几个影响模型泛化的数据
train_corr=data_train1.corr()
train_corr


也没看出来什么特别的相关性,可以通过画出相关性热力图来直观地看。顺便说一下,得到的相似度系数corr越接近1或者-1,相关性越大,接近0基本没什么相关性。

查找出特征变量和target变量相关系数大于0.5的特征变量

#寻找K个最相关的特征信息
k = 10 # number of variables for heatmap
cols = train_corr.nlargest(k, 'target')['target'].index
cm = np.corrcoef(train_data[cols].values.T)
hm = plt.subplots(figsize=(10, 10))#调整画布大小
#hm = sns.heatmap(cm, cbar=True, annot=True, square=True)
#g = sns.heatmap(train_data[cols].corr(),annot=True,square=True,cmap="RdYlGn")
hm = sns.heatmap(train_data[cols].corr(),annot=True,square=True)
plt.show()

threshold = 0.5
corrmat = train_data.corr()
top_corr_features = corrmat.index[abs(corrmat["target"])>threshold]
plt.figure(figsize=(10,10))
g = sns.heatmap(train_data[top_corr_features].corr(),annot=True,cmap="RdYlGn")

drop_columns.clear()
drop_columns = ['V5','V9','V11','V17','V22','V28']


# Threshold for removing correlated variables
threshold = 0.5
# Absolute value correlation matrix
corr_matrix = data_train1.corr().abs()
drop_col=corr_matrix[corr_matrix["target"]<threshold].index
#data_all.drop(drop_col, axis=1, inplace=True)


#merge train_set and test_set
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)
#View data
data_all.head()


特征的相关系数值小于0.5的直接删除,认为这些特征与最终的预测target值不相关。即V14', 'V21', 'V25', 'V26', 'V32', 'V33', 'V34'这些。

# normalise numeric columns
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()


#col_data_process = cols_numeric.append('target')
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)


cols_numeric_left = cols_numeric[0:13]
cols_numeric_right = cols_numeric[13:]


## Check effect of Box-Cox transforms on distributions of continuous variables
train_data_process = pd.concat([train_data_process, train_data['target']], axis=1)
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) 
 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]))

## Check effect of Box-Cox transforms on distributions of continuous variables
fcols = 6
frows = len(cols_numeric_right)
plt.figure(figsize=(4*fcols,4*frows))
i=0
for var in cols_numeric_right:
 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) 
 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]))

作者:十八闲客原文地址:https://segmentfault.com/a/1190000043532542

%s 个评论

要回复文章请先登录注册