思维导图:零基础入门数据挖掘的学习路径

1. 写在前面

零基础入门数据挖掘是记录自己在Datawhale举办的数据挖掘专题学习中的所学和所想, 该系列笔记使用理论结合实践的方式,整理数据挖掘相关知识,提升在实际场景中的数据分析、数据清洗,特征工程、建模调参和模型融合等技能。所以这个系列笔记共五篇重点内容, 也分别从上面五方面进行整理学习, 既是希望能对知识从实战的角度串联回忆,加强动手能力的锻炼,也希望这五篇笔记能够帮助到更多喜欢数据挖掘的小伙伴,我们一起学习,一起交流吧。

既然是理论结合实践的方式,那么我们是从天池的一个二手车交易价格预测比赛出发进行学习,既可以学习到知识,又可以学习如何入门一个数据竞赛, 下面我们开始吧。

今天是本系列的第五篇文章模型的建立与调参部分,这一块也是很费时间且核心的一部分工作,毕竟特征工程也好,数据清洗也罢,都是为最终的模型来服务的,模型的建立和调参才决定了最终的结果,上限是一回事, 如何更好的去达到这个上限又是一回事, 前一篇我们已经做完了特征工程,好像是有了一个上限,到底应该怎么去达到这个上限呢? 就需要看我们的模型表现了。所以今天重点整理模型的评估和调参的相关技术。

首先,我们会先从简单的线性模型开始,看看如何去建立一个模型以及建立完模型之后要去分析什么东西, 然后我们会学习交叉验证的思想和技术(这个在评估模型的效果是经常会用到)并且会构建一个线下测试集(当然这个针对本比赛), 上面的这些算是建立模型的基础,然后我们会尝试建立更多的模型去解决这个问题,并对比它们的效果, 当把模型选择出来之后,我们还得掌握一些调参的技术发挥模型最大的性能, 模型选择出来之后,也调完参数,但是模型真的就没有问题了吗? 我们其实不知道, 所以最后我们学习绘制学习率曲线看模型是否存在过拟合或者欠拟合的问题并给出相应的解决方法。

大纲如下:

  • 我们先从最简单的模型开始(线性回归 & 交叉验证 & 构建线下测试集)
  • 评估算法模型的框架(这里会给出一个选择模型的框架,适合迁移)
  • 模型的调参技术(贪心调参, GridSearchCV调参和贝叶斯调参)
  • 绘制学习曲线和验证曲线(如何从学习曲线看过拟合欠拟合以及如果发生了过拟合欠拟合问题,我们应该怎么去尝试解决)
  • 对模型建立和调参部分的总结

PS: 本文默认学习者已经具备了机器学习和数据挖掘的基础知识,已经知道了一些基本概念,比如过拟合,欠拟合,正则化,模型复杂度等。 所以关于这些基础知识,本文不会过多的赘述,遇到了会提一下,如果没有掌握这些基本概念,建议先去补一下这些基本的概念,可以参考后面的第一篇链接。并且关于模型的原理部分,这里也不展开论述, 因为关于这个比赛后面我尝试用了五六种模型进行试验,如果单纯讲这些模型的原理,篇幅会超级长,也不是这个系列需要整理的问题了, 这些东西我都放在了链接里面。

Ok, let’s go!

2. 我们先从简单的线性模型开始

这部分也算是一个热身了,我们这个比赛是关于价格预测的,我们也知道了这是个回归的问题, 那么对于回归的问题,我们肯定是要选择一些回归模型来解决,线性模型就是一个比较简单的回归模型了, 所以我们就从这个模型开始,看看针对这个模型,我们会得到什么结果以及这些结果究竟是什么含义。

那么什么是线性回归模型, 线性回归(Linear Regression)是利用称为线性回归方程的最小平方函数对一个或多个自变量和因变量之间关系进行建模的一种回归分析, 简单的说,假设我们预测的二手车价格我们用YYY来表示, 而我们构造的特征我们用xix_ixi​, 我们就可以建立这样一个等式来表示它们的关系:
Y=w1x1+w2x2+....+wnxn+bY = w_1x_1+w_2x_2+....+w_nxn+bY=w1​x1​+w2​x2​+....+wn​xn+b

训练模型的过程其实就是根据训练集的这些(X,Y)(X, Y)(X,Y)样本来求出合适的权重www, 然后对新的测试集XXX预测相应的YtestY_{test}Ytest​, 这个YtestY_{test}Ytest​其实就是我们想要的答案。这就是这部分的逻辑,下面看实现。

首先导入上次特征工程处理完毕后保存的数据集:

# 导入之前处理好的数据
data = pd.read_csv('./pre_data/pre_data.csv')
data.head()# 然后训练集和测试集分开
train = data[:train_data.shape[0]]
test = data[train_data.shape[0]:]    # 这个先不用# 选择那些数值型的数据特征
continue_fea = ['power', 'kilometer', 'v_2', 'v_3', 'v_4', 'v_5', 'v_6', 'v_10', 'v_11', 'v_12', 'v_14','v_std', 'fuelType_price_average', 'gearbox_std', 'bodyType_price_average', 'brand_price_average','used_time', 'estivalue_price_average', 'estivalueprice_std', 'estivalue_price_min']
train_x = train[continue_fea]
train_y = train_data['price']

可以看一下,我这边处理的data数据的结果:

我这边data会有38个特征。

下面,我们建立线性模型,建立模型如果用sklearn的话还是非常简单的,包括训练和预测。

from sklearn.linear_model import LinearRegressionmodel = LinearRegression(normalize=True)
model.fit(train_x, train_y)

通过上面这两行代码,我们其实就建立了线性模型,并完成了训练。 .fit方法就是训练模型, 训练的结果就是求出了上面的w和b。我们可以查看一下:

"""查看训练的线性回归模型的截距(intercept)与权重(coef)"""
print('intercept: ' + str(model.intercept_))
sorted(dict(zip(continue_fea, model.coef_)).items(), key=lambda x: x[1], reverse=True)## 结果:
intercept: -178881.74591832393
[('v_6', 482008.29891714785),('v_std', 23713.66414841167),('v_10', 7035.056136559963),('v_14', 1418.4037751433352),('used_time', 186.48306334062053),('power', 12.19202369791551),('estivalue_price_average', 0.4082359327905722),('brand_price_average', 0.38196351334425965),('gearbox_std', 0.1716754674248321),('fuelType_price_average', 0.023785798378739224),('estivalueprice_std', -0.016868767797045624),('bodyType_price_average', -0.21364358471329278),('kilometer', -155.11999534761347),('estivalue_price_min', -574.6952072539285),('v_11', -1164.0263997737668),('v_12', -1953.0558048250668),('v_4', -2198.03802357537),('v_3', -3811.7514971187525),('v_2', -5116.825271420712),('v_5', -447495.6394686485)]

上面的这些就是我们那个等式中每个x前面的系数, intercept这个代表那个b, 我们上面说过了,有了系数,我们就可以对新的样本进行预测。 预测也很简单,只需要

y_pred = model.predict(x_test)

这样的一句代码就可以实现, 但是这里想探索一点别的东西, 因为后面模型对比中会发现线性模型的效果不好,因为我们前面特征选择的时候也看到过了啊, 并不是所有的数值特征都和price有相关关系啊, 还有一些非线性关系吧, 这些线性模型就捕捉不到了,并且一般线性模型喜欢那种归一化或者标准化的数据, 导致和非线性模型的数据还得分开处理,所以这个比赛不会用到线性模型。

但是关于线性模型还有些好玩的东西我们得了解一下, 比如从这些权重中如何看出哪个特征对线性模型来说更加重要些? 这个其实我们看的是权重的绝对值,因为正相关和负相关都是相关, 越大的说明那个特征对线性模型影响就越大。

其次,我们还可以看一下线性回归的训练效果,绘制一下v_6这个特征和标签的散点图:

subsample_index = np.random.randint(low=0, high=len(train_y), size=50)plt.scatter(train_x['v_6'][subsample_index], train_y[subsample_index], color='black')
plt.scatter(train_x['v_6'][subsample_index], model.predict(train_x.loc[subsample_index]), color='blue')
plt.xlabel('v_6')
plt.ylabel('price')
plt.legend(['True Price','Predicted Price'],loc='upper right')
print('The predicted price is obvious different from true price')
plt.show()

结果如下:

从上图中我们可以发现发现模型的预测结果(蓝色点)与真实标签(黑色点)的分布差异较大,且部分预测值出现了小于0的情况,说明我们的模型存在一些问题。 这个还是需要会看的,从这里我们也可以看出或许price这个需要处理一下。

哈哈,我们记得price的分布图吗?

print('It is clear to see the price shows a typical exponential distribution')
plt.figure(figsize=(15,5))
plt.subplot(1,2,1)
sns.distplot(train_y)
plt.subplot(1,2,2)
sns.distplot(train_y[train_y < np.quantile(train_y, 0.9)])

结果是长这个样子:

通过作图我们发现数据的标签(price)呈现长尾分布,不利于我们的建模预测。原因是很多模型都假设数据误差项符合正态分布,而长尾分布的数据违背了这一假设。参考博客:https://blog.csdn.net/Noob_daniel/article/details/76087829

所以,我们不妨取对数一下:

train_y_ln = np.log1p(train_y)
print('The transformed price seems like normal distribution')
plt.figure(figsize=(15,5))
plt.subplot(1,2,1)
sns.distplot(train_y_ln)
plt.subplot(1,2,2)
sns.distplot(train_y_ln[train_y_ln < np.quantile(train_y_ln, 0.9)])

这样效果是不是就好多了呢?

那么我们再来训练一下:

model = model.fit(train_x, train_y_ln)print('intercept:'+ str(model.intercept_))
sorted(dict(zip(continue_fea, model.coef_)).items(), key=lambda x:x[1], reverse=True)

这个权重结果就不显示了,我们依然是画出v_6和price的散点图, 会发现长这样子了:

好了,线性回归模型我们就探索到这里,引入这块到底要表达个什么意思呢?

  1. 线性模型是很简单的一个模型,我们虽然后面不会用到,但是后面建立模型,训练和预测模型的步骤和线性模型基本上是一致的,依然是.fit(X,Y), .predict(X_test)方法。所以在这里先体会一下如何建立一个模型,并且对它训练和预测。
  2. 线性模型这个操作中,有些方法还是可以用于其他模型的,比如模型训练之后,我们可以通过某种方式去看哪些特征对模型更加重要,这个在特征筛选的时候非常非常有用(还记得嵌入式或者包裹式特征选择方法吗),所以这里算是一个简单的温习操作
  3. 通过查看模型的训练效果,可能还会有意外的收获,就比如这里的price这个分布,从模型的训练效果也可以看出来这个分布可能有问题。

上面的三个点你get到了吗? 是不是这个热身中也潜藏好多知识

零基础数据挖掘入门系列(五) - 模型建立与调参相关推荐

  1. 零基础数据挖掘入门系列(三) - 数据清洗和转换技巧

    思维导图:零基础入门数据挖掘的学习路径 1. 写在前面 零基础入门数据挖掘是记录自己在Datawhale举办的数据挖掘专题学习中的所学和所想, 该系列笔记使用理论结合实践的方式,整理数据挖掘相关知识, ...

  2. 零基础数据挖掘入门系列(一) - 赛题理解

    思维导图:零基础入门数据挖掘的学习路径 1. 写在前面 零基础入门数据挖掘系列是记录自己在Datawhale举办的数据挖掘专题学习中的所学和所想, 该系列笔记使用理论结合实践的方式,整理数据挖掘相关知 ...

  3. 零基础数据挖掘入门系列(二) - 数据的探索性(EDA)分析

    思维导图:零基础入门数据挖掘的学习路径 1. 写在前面 零基础入门数据挖掘是记录自己在Datawhale举办的数据挖掘专题学习中的所学和所想, 该系列笔记使用理论结合实践的方式,整理数据挖掘相关知识, ...

  4. 零基础数据挖掘入门系列(四) - 特征工程

    思维导图:零基础入门数据挖掘的学习路径 1. 写在前面 零基础入门数据挖掘是记录自己在Datawhale举办的数据挖掘专题学习中的所学和所想, 该系列笔记使用理论结合实践的方式,整理数据挖掘相关知识, ...

  5. 【Python零基础快速入门系列 | 03】AI数据容器底层核心之Python列表

    • 这是机器未来的第7篇文章 原文首发地址:https://blog.csdn.net/RobotFutures/article/details/124957520 <Python零基础快速入门 ...

  6. 【Python零基础快速入门系列 | 07】浪漫的数据容器:成双成对之字典

    这是机器未来的第11篇文章 原文首发链接:https://blog.csdn.net/RobotFutures/article/details/125038890 <Python零基础快速入门系 ...

  7. 视频教程-零基础JS入门系列课程(2)之JS语法基础精讲-JavaScript

    零基础JS入门系列课程(2)之JS语法基础精讲 螺钉课堂讲师,擅长Vue.React.ReactNative.NodeJS等前端框架及技术 邓老师 ¥59.00 立即订阅 扫码下载「CSDN程序员学院 ...

  8. 零基础前端入门系列(八)

    CSS精讲(二) CSS体系知识介绍 选择器优先级 为什么关注优先级 优先级处理原则 !important 和 内联样式 样式继承 一个继承的例子 继承属性和非继承属性 范例 选择器权重计算 范例1 ...

  9. 数据挖掘小白系列!LightGBM详解与调参

    1理解 [白话机器学习]算法理论+实战之LightGBM算法 备注:看了N个这个算是最详细最容易懂的了,并且有调参步骤与实例需要对XGB了解 2调参 第一步:学习率&迭代次数&估计器 ...

最新文章

  1. [转]控制 Cookie 的作用范围
  2. Apache shutdown unexpectedly启动错误解决方法
  3. 智慧工厂如何运转?飞凌FCU2303-5G智能网关来告诉你
  4. 数据结构与算法--丑数
  5. Request/Response
  6. 从教科书式的失败到手术刀式的自救,李宁找回了“李宁”!
  7. 深度学习中的数据增强方法
  8. ModbusTCP协议
  9. php laravel 下载远程图片
  10. XPS是什么格式?如何免费转换为word?
  11. 台式计算机垃圾清理程序,PC Cleaning Utility(电脑垃圾清理软件)
  12. pe结构分析之手工修复导入表
  13. Delphi中的线程类--之(2)
  14. ValueError: Classification metrics can‘t handle a mix of binary and continuous targets
  15. 对数字身份认证安全,是企业的责任还是个人的责任?
  16. CSS样式写出三角形
  17. latex 编译eps文件时的问题
  18. 2022年索尼A7R4A与A7R3A如何选择?
  19. [Delaunay Triangle] [图形学] 优化方案
  20. Unity小技巧——Inspector中插入数组元素

热门文章

  1. 一元享移动怎么样_中国联通“放大招”强怼移动:再推0月租视频日租卡、1元享10G省内流量!...
  2. 什么从什么写短句_什么在什么,在什么,在什么写句子
  3. 今晚23点整Surface新品发布会
  4. 帝国导航高亮显示(只支持一级栏目,灵动标签)
  5. HTML电影页面美化,页面跳转美化 —— HTML源码
  6. 电话号码的组合(公式运算)
  7. 画课堂计算机作业答案,袁老师课堂:孩子们的电脑画
  8. 计算机动画_3dsmax的使用(四)
  9. PostgreSQL查询用户密码密码解密修改密码
  10. About 6.12 This Week