这篇博客是接上文的,现在就开始做特征工程了,上面都是做的一些模型的融合,cv的验证,既然已经有了这些基础,那么必须要做最重要的部分了,特征工程十分重要,可以说是比赛的最关键步骤。赛题的链接:点击打开链接
1.引入相关的库,并读入数据。
# coding:utf-8
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import sys
reload(sys)
sys.setdefaultencoding('utf8')
sns.set_style('darkgrid')
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
train = pd.read_csv("data/d_train_20180102.csv")
test = pd.read_csv("data/d_test_A_20180102.csv")
2.先观察数据的前面几列,看一看数据的大体情况。
print "显示前面几行数据\n", train.head()
得到的输出:
id 性别 年龄 体检日期 *天门冬氨酸氨基转换酶 *丙氨酸氨基转换酶 *碱性磷酸酶 *r-谷氨酰基转换酶 *总蛋白 \
0 1 男 41 12/10/2017 24.96 23.10 99.59 20.23 76.88
1 2 男 41 19/10/2017 24.57 36.25 67.21 79.00 79.43
2 3 男 46 26/10/2017 20.82 15.23 63.69 38.17 86.23
3 4 女 22 25/10/2017 14.99 10.59 74.08 20.22 70.98
4 5 女 48 26/10/2017 20.07 14.78 75.79 22.72 78.05
白蛋白 ... 血小板计数 血小板平均体积 血小板体积分布宽度 血小板比积 中性粒细胞% 淋巴细胞% 单核细胞% 嗜酸细胞% \
0 49.60 ... 166.0 9.9 17.4 0.164 54.1 34.2 6.5 4.7
1 47.76 ... 277.0 9.2 10.3 0.260 52.0 36.7 5.8 4.7
2 48.00 ... 241.0 8.3 16.6 0.199 48.1 40.3 7.7 3.2
3 44.02 ... 252.0 10.3 10.8 0.260 41.7 46.5 6.7 4.6
4 41.83 ... 316.0 11.1 14.0 0.350 56.6 33.1 9.1 0.6
嗜碱细胞% 血糖
0 0.6 6.06
1 0.8 5.39
2 0.8 5.59
3 0.5 4.30
4 0.6 5.42
[5 rows x 42 columns]
3.查看需要预测的特征血糖的一些属性
print train['血糖'].describe()
count 5642.000000
mean 5.631925
std 1.544882
min 3.070000
25% 4.920000
50% 5.290000
75% 5.767500
max 38.430000
这里我们可以看得是,max肯定是异常值,因为人的血糖不可能这么高,所以在后面的处理过程中,我们会把这个异常点除掉,这个属性的异常在LB上面提升了0.011 。
接下来,我们观看血糖的分布,
可以看出,血糖的分布还是不成线性的,所以我们可以通过转换,将血糖线性分布。
我做了boxcox的处理
tmp, lambda_ = stats.boxcox(train['血糖'])
print len(tmp)
sns.distplot(tmp, fit=norm)
(mu, sigma) = norm.fit(tmp)
print( '\n mu = {:.2f} and sigma = {:.2f}\n'.format(mu, sigma))
plt.legend(['Normal dist. ($\mu=$ {:.2f} and $\sigma=$ {:.7f} )'.format(mu, sigma)],
loc='best')
plt.ylabel('Frequence')
plt.title('血糖分布')
fig = plt.figure()
res = stats.probplot(tmp, plot=plt)
plt.show()
得到的效果如下面
但是效果却不是很好,本地CV反而上升了。这就很尴尬了。可能是没对x属性做处理的原因吧。先不管了,我们接下来看一下特征之间的相关关系图,看看属性之间的关系。
corrmat = train.corr()
f, ax = plt.subplots(figsize=(20, 9))
ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
#ax.set_yticklabels(ax.get_yticklabels(), rotation=180)
sns.heatmap(corrmat, vmax=0.9, yticklabels=True, square=True)
locs, labels = plt.yticks()
plt.setp(labels, rotation=360)
plt.show()
得到的图形:
然后看关联关系大的图像:
corrmat = train.corr()
k = 10 #number of variables for heatmap
f, ax = plt.subplots(figsize=(20, 9))
ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
cols = corrmat.nlargest(k, '血糖')['血糖'].index
cm = np.corrcoef(train[cols].values.T)
#sns.set(font_scale=1.25)
hm = sns.heatmap(cm, cbar=True, annot=True, square=True, fmt='.2f', annot_kws={'size': 10}, yticklabels=cols.values, xticklabels=cols.values)
locs, labels = plt.yticks()
plt.setp(labels, rotation=360)
plt.show()
看到这个图,我是拒绝的。。。特征之间感觉没有关系,我们还应该查看缺失情况:
# 查看确实率
total = train.isnull().sum().sort_values(ascending=False)
percent = (train.isnull().sum()/train.isnull().count()).sort_values(ascending=False)
missing_data = pd.concat([total, percent], axis=1, keys=['Total', 'Percent'])
print missing_data.head(20)
Total Percent
乙肝e抗原 4278 0.758376
乙肝核心抗体 4278 0.758376
乙肝表面抗原 4278 0.758376
乙肝表面抗体 4278 0.758376
乙肝e抗体 4278 0.758376
肌酐 1378 0.244283
尿素 1378 0.244283
尿酸 1378 0.244283
*总蛋白 1220 0.216274
白球比例 1220 0.216274
白蛋白 1220 0.216274
*天门冬氨酸氨基转换酶 1220 0.216274
*r-谷氨酰基转换酶 1220 0.216274
*碱性磷酸酶 1220 0.216274
*丙氨酸氨基转换酶 1220 0.216274
*球蛋白 1220 0.216274
甘油三酯 1218 0.215919
总胆固醇 1218 0.215919
高密度脂蛋白胆固醇 1218 0.215919
低密度脂蛋白胆固醇 1218 0.215919
血小板平均体积 23 0.004077
血小板体积分布宽度 23 0.004077
血小板比积 23 0.004077
中性粒细胞% 16 0.002836
嗜酸细胞% 16 0.002836
嗜碱细胞% 16 0.002836
淋巴细胞% 16 0.002836
白细胞计数 16 0.002836
红细胞计数 16 0.002836
血红蛋白 16 0.002836
红细胞压积 16 0.002836
红细胞平均体积 16 0.002836
红细胞平均血红蛋白量 16 0.002836
红细胞平均血红蛋白浓度 16 0.002836
红细胞体积分布宽度 16 0.002836
血小板计数 16 0.002836
单核细胞% 16 0.002836
让我们来看看属性的重要性:
# 查看属性的重要性
train_y = train['血糖'].values
df_train=train.drop(['性别', '体检日期','血糖'], axis=1)
xgb_params = {
'eta': 0.05,
'max_depth': 8,
'subsample': 0.7,
'colsample_bytree': 0.7,
'objective': 'reg:linear',
'silent': 1,
'seed': 0
}
dtrain = xgb.DMatrix(df_train, train_y, feature_names=df_train.columns.values)
model = xgb.train(dict(xgb_params, silent=0), dtrain, num_boost_round=50)
# plot the important features #
fig, ax = plt.subplots(figsize=(12, 18))
ax.set_yticklabels(df_train.columns.values, rotation='horizontal')
xgb.plot_importance(model, height=0.8, ax=ax)
plt.show()
现在唯一要做的就是找出隐藏的特征了。下面将逐渐的探索隐性特征。