比赛介绍
这个比赛是阿里天池的新人赛,基本算是数据挖机的入门比赛。数据是火力发电采集到的数据,没有给出数据说明。每条数据给出了38个特征,需要预测目标值。评判预测结果的标准为MSE(mean square error)均方误差。
mse为预测值与真实值之差的平方除以样本数。
思路
拿到题发现,这是一道回归问题,直接预测target值。就先用最简单的线性回归测试了一下。(数据预处理和绘图分析都没做2333)
测完线性回归,从模型扩展(岭回归,Lasso,神经网络),特征处理(PCA,特征缩放,特征选择)两个方向出发,分别寻找更优的方法。实在不行再试试模型融合。
线性回归
这东西也叫最小二乘,线性回归寻找参数w和b,使得对训练集与真实的回归目标值y之间的MSE最小。理论推导就不写了,核心代码先列出来。
1 | '''线性回归''' |
直接用这个线下可以很高,但是因为数据样本太少,容易过拟合。而且又没有对数据做预处理。所以首先要对数据做预处理,看了一下论坛,发现有人的baseline使用了PCA。
主成分分析(PCA)
PCA将n个特征降维到k个,换句话说对数据进行了降维处理。在降维的同时最大程度上保持了原有数据的信息。PCA在处理过程中不需要人为干预,处理只与原数据相关。
1 | # PCA数据处理-降维 |
使用PCA过后,再利用线性回归进行预测,线上MSE就能达到0.14,但还是没有进榜。
于是开始进行特征分析,绘制数据图像。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18plt.figure(figsize=(20, 16)) # 指定绘图对象宽度和高度
colnm = zhengqi_train.columns.tolist()[:39] # 列表头
mcorr = zhengqi_train[colnm].corr() # 相关系数矩阵,即给出了任意两个变量之间的相关系数
mask = np.zeros_like(mcorr, dtype=np.bool) # 构造与mcorr同维数矩阵 为bool型
mask[np.triu_indices_from(mask)] = True # 角分线右侧为True
cmap = sns.diverging_palette(220, 10, as_cmap=True) # 返回matplotlib colormap对象
g = sns.heatmap(mcorr, mask=mask, cmap=cmap, square=True, annot=True, fmt='0.2f') # 热力图(看两两相似度)
plt.show()
# 画正太分布图
sns.distplot(zhengqi_train['target'], fit=norm)
(mu, sigma) = norm.fit(zhengqi_train['target'])
print('\n mu = {:.2f} and sigma = {:.2f}\n'.format(mu, sigma))
plt.legend(['Normal dist. ($\mu=$ {:.2f} and $\sigma=$ {:.2f} )'.format(mu, sigma)], loc='best')
plt.ylabel('Frequency')
fig = plt.figure()
res = stats.probplot(zhengqi_train['target'], plot=plt)
plt.show()
热力图是特征之间的相关性分析,是一个38维的矩阵,保存了两两间相关系数值。然后对target值用正态分布进行极大似然估计,求出对应的mu和sigma值。
这里发现有几个特征相关性特别高,不管是正负相关。相关系数该怎么利用,这是我下一步准备做的。然后观察target的分布,看mu值和sigma值和预测集的进行对比。
岭回归
在特征提取之前,为了得到更好的结果,我开始寻找更好的线性模型。岭回归也是一种用于回归的线性模型。但是在岭回归中,对系数w的选择尽可能的小,即应接近于0。这种约束是正则化的。这种方式对模型做显示约束以避免过拟合,岭回归用到的方法也被称为L2正则化。
1 | '''岭回归''' |
RidgeCV是一种用于自动选择最优的方法,增加会使得系数w更加趋向于0,从而降低训练集性能,但会提升泛化性能。
Lasso
Lasso也是约束系数使得其接近于0,但用到的方法与岭回归不同,叫做L1正则化。即某些系数为0时,特征被模型完全忽略,可以将其看作一种自动化特征选择的方法,更能展示更重要的模型特征。1
2
3
4
5
6
7
8'''lasso'''
X_train, X_test, Y_train, Y_test = train_test_split(X_pca, y, test_size=0.2, random_state=40)
lasso_model = Lasso(max_iter=100000)
lasso_model = LassoCV()
lasso_model.fit(X_train,Y_train)
print('最佳的alpha:',lasso_model.alpha_)
Y_pred = lasso_model.predict(X_test)
print(mean_squared_error(Y_test, Y_pred))
如果特征很多,或者只有其中几个是重要的,那么Lasso的效果可能更好。
总结
目前为止,单模型效果最好的方案是PCA+Lasso,线上结果为0.1386。写博客的顺序打算按照我自己的比赛思路来走,所以下一篇将总结使用树模型的GBR,LGB等方法,以及模型融合,特征处理的思路及方法。/4.png)