机器学习实战
本书内容广博,不仅介绍了传统ML,还用sklearn演示了端到端训练实例。
尤其对DL进行了深入探讨,涵盖强化学习、利用TF/Keras构建和训练神经网络
ML
1. 前置补充
- 在机器学习里,属性是一种数据类型,而特征取决于上下文,通常意味着属性+值(很多人混淆)
- 一些回归算法和可用于分类任务,反之亦然。比如逻辑回归可以输出“属于某个给定类别的概率”,可用于分类
- 无监督应用:
- 聚类
- 异常检测、新颖性检测
- 可视化、降维(可先用降维减少数据维度,再提供给别的算法)
- 关联规则学习
- 比起在线学习,批量学习也可以适应变化,但是需要重新训练全新的系统,成本高
- 在线学习也可以用于超大数据集,因为超出了一台计算机的主存储器的数据
- 基于实例(相似度),和基于模型(我看到的好像都是这个)的学习
- 特征工程 vs 端到端学习
- 正则化实质是约束模型,限制变化范围,降低复杂度。
- 测试验证:保持验证、交叉验证
- 没有免费的午餐:如果你对数据绝对没有假设,那么就没有理由更偏好某个模型,必须得有假设,然后只评估部分合理的模型。
2.端到端的机器学习项目
假设你是一个房地产公司最近雇佣的数据科学家,你会经历:
- 观察大局
- 获得数据
- 从数据探索和可视化中获得洞见
- 机器学习算法的数据准备
- 选择并训练模型
- 微调模型
- 展示解决方案
- 启动、监控和维护模型
(使用真实数据,详情见我的另一篇博文:DS资源)
观察大局
附录B,记录了一个数据科学项目的大致流程以供参考
流水线:一个序列的数据处理组件称为一个数据流水线。在机器学习系统中非常普遍。
组件通常异步进行,组件间很独立,连接只有数据仓库。Robustness++,但需要适当的监控。
问老板业务目标,公司期望如何使用该模型,如何从中获益才是重要问题:
这决定怎么设定问题,选择什么算法,通过什么方式评估模型性能,花多少精力来进行调整
问老板当前的解决方案(可能存在),当作建议、参考,获得洞察
开始设计系统,回答框架问题:有无监督/强化、分类/回归、批量/在线
选择性能指标:
RMSE 均方根误差 欧几里得范数 L2
MAE 平均绝对误差 曼哈顿范数 L1
-
指标越高越关注大值而不是小值,这就是为何RMSE比MAE对异常值更敏感
检查假设,与数据流水线上下游团队沟通。
获取数据(数据库),可以编写shell脚本来辅助
通过查看数据描述、部分数据,简单可视化来了解数据
创建测试集
在简单了解数据后,创建测试集(有点奇怪),因为大脑容易过拟合(数据窥探偏误):
浏览数据,跌入某个看似有趣的测试数据模式,选择某个特殊的模型,估计结果过于乐观,但其实泛化能力一般。
所以要在没有进一步了解的时候创建测试集,有一些方法,比如用标签确定哪些是选出来的测试集,有时候要用纯随机,有时候要分层抽样。
这一步没有想象中的简单,而很多人忽视了它创建的时机。
从数据探索和可视化中获得洞见
现在把测试集放在一边不要碰,只关注训练集。如果训练集太大,可以抽样一个探索集
xs,通过设置透明度更好的看清密度
我们的大脑擅长从图片中发现模式,但这需要你玩转可视化的参数。
先试试寻找不同特征之间的相关性,既包括线性,也有非线性并可视化出来康康,有许多函数可以实现这一步
中间省略众多有趣的方法
最后我们应该尝试各种属性的组合,创建新属性(我感觉吴恩达教的更好),再检测一下相关性等指标。
数据准备
这个过程应该编写函数而不是手动操作:
- 以便在任何数据集上轻松重现
- 可以逐渐建立起转换函数库,在以后的项目中重用
- 可以在实时系统中用函数转换新的数据,在输入给算法
- 可以轻松尝试多种转换方式,比较效果。
回到干净的训练集,进行数据清理,处理文本和分类属性的时候用到了独热码
ps:sklearn的API设计规则非常好,原则如下:
- 一致性:所有对象共享一个简单的界面
- 估算器:能够根据数据集对某些参数进行估算
- 转换器:可以转换数据集
- 预测器:能够基于一个给定的数据集进行预测
- 检查:所有估算器的超参数都可以通过公共实例变量直接方位(例如imputer.strategy)
- 防止类扩散:数据集被表示为Numpy数组或Scipy稀疏矩阵,超参数只是普通的Python字符串或数值
- 构成:现有的构建尽最大可能重用
- 合理的默认值
而尽管sklearn提供了许多有用的转换器,你仍然需要为一些注入自定义清理操作或组合特定属性等任务编写自己的转换器。
而sklearn依赖鸭子类型编译,而不是继承。
这些数据准备步骤的执行越自动化,你自动尝试的组合也就越多,从而有更大的可能找到一个重要的组合并节省大量时间。
最重要也最需要应用到数据上的转换就是特征缩放,(仅用于拟合训练集)
两种常用方法:最小-最大缩放(归一化)、 标准化
前者是减去最小值然后除以(最大-最小),收缩到0—1,当然也可以更改
后者是减去平均值然后除以方差,标准化没有特定范围,但是受异常值的影响更小。
转换流水线(后来补充)
通过Pipeline类来支持,方法与最终的估算器方法相同。
如果要用于多列,可以用Column-Transformer,他与pandas DataFrame 一起使用时效果很好。
选择和训练模型
完成了前面的步骤后,事情现在变得比想象中容易很多。
别忘了使用交叉验证来更好地评估:
- 可以将训练集分为较小的训练集和验证集,然后加以训练
- 也可以使用sklearn的K-折交叉验证功能。(更偏向于使用效用函数而不是使用成本函数)
在深入某些算法之前,应该尝试一遍各种机器学习算法的其他模型(不同内核的支持向量机,神经网络。。)
但是别花太多时间调整超参数,我们的目的是筛选出几个(2~5)个有效的模型,每一个尝试的模型都应该妥善保管,以及对应的超参数和训练过的参数,以及交叉验证的评分和实际检测的结果。
可以用Python的pickle模块或joblib库来保存模型。
微调
有了有效模型的候选列表,现在进行微调。
你可以手动调整超参数直到找到一组不错的组合。。非常枯燥乏味,耗时间
你也可以用sklearn的GridSearchCV替你搜索,如果不知道超参数怎么赋值,可以先尝试10的连续次幂
当然也可以把它用在数据准备的步骤,还可以用来自动寻找处理问题的最佳方法。
网格搜索👆是一项模型超参数(即需要预先优化设置而非通过训练得到的参数)优化技术,常用于优化三个或者更少数量的超参数,本质是一种穷举法。
但是如果超参数搜索的方法较大,建议使用随机搜索。
还有集成方法,组合方法往往比单一的模型更好。。。。。最后通过测试集评估系统。、
还是小心吴恩达说的那个问题,不要拼命调调超参数让测试集结果好看,这可能会使其“适应测试集”。。。
启动!监控与维护
预启动:展示解决方案(学了什么、什么有用、基于什么假设、系统的限制),记录所有的事情,通过可视化和故事化制作漂亮的演示文档。
你可以部署到服务器,通过web来让用户调用,但更流行的策略是将模型部署到云上:用joblib保存模型上传到Google Cloud Storage(GCS),然后转到Google Cloud AI Platform并创建一个新的模型版本,指向GCS文件。
你还要编写监控代码以定期检查系统的实时性能,在降低时触发警报,因为数据会过时,会腐朽。
各种层面,甚至包括相机的图像清晰度、格式变化,还有人们的偏好变化。。。
但是确定模型的性能并不总是可行的,你可能需要人工分析。。。反正建立一个监控系统和相关流程,包括如何定义故障以及如何做准备。
这个工作量甚至比构建和训练模型多得多。。你还要定期更新数据集并定期重新训练模型(数据发展),最好自动化:
- 自动定期收集数据并标记(如聘用人工标注者)
- 编写脚本来训练模型并自动调微超参数。
- 编写脚本在更新的测试集上评估新旧模型,性能好则自动部署,差就调查原因。
做好版本管理(包括每个版本的数据集),以防新模型故障时需要回滚
3.分类
终于了解完了大概流程,有些麻烦,但不出所料,让我们正式进入学习吧!