1. 机器学习简介
机器学习是从数据中自动分析获得模型,并利用模型对未知数据进行预测。它是一个流程性很强的工作,包括数据采集、数据清洗、数据预处理、特征工程、模型调优、模型融合、模型验证、模型持久化、在线服务等模块。
而在这些基本的步骤内,又存在很多种方式,比如数据采集可以是爬虫,可以是数据库拉取,可以是通过API获取等等,数据清洗要注意缺失值处理,异常值处理,特征工程更是复杂多样。
2. 数据采集与探索
所有的机器学习算法在应用场景、优势劣势、对数据要求、运行速度上都各有优劣,但有一点不变的是数据贪婪的,也就是说任何一个算法,都可以通过增加数据来达到更好的结果,因此第一步数据采集也是最基础,最重要的一步。
2.1 数据采集的几种方式
2.1.1 API
现在有很多公开的数据集,一些组织也提供开放的API接口来获取相关数据,这类数据通常数据更加规范;比如:
1. sklearn.datasets中有很多练习数据;
2. OpenDota提供的Dota2相关数据,好处是通常数据更加规范。
2.1.2 数据库
这种是最常见,也最理想的状态,通过公司自身的数据库保存数据,更加可控,也更加自由灵活。
2.1.3 爬虫
这种通常在个人项目、公司资源不足以提供数据、原始数据不足需要扩展数据情况下使用较多,比如根据时间获取天气数据,一般都是通过爬虫爬来的;
2.1.4 一些常见数据集
MNIST:手写数据集;
ImageNet:图片数据集,从图片搜索引擎上获得;
AudioSet:音频数据集,youtube上的音频切片;
Kinetics:人类行为数据集,youtube上的视频切片;
KITTI:无人驾驶数据集,被相机记录到的一些交通场景;
Amazon Review:评论数据集,亚马逊网站上的一些用户评论;
SQuAD:问答数据集;
LibriSpeech:有声读物数据集。
机器学习数据集汇总收集:
https://blog.csdn.net/qq_15698613/article/details/116957307
2.2 数据信息探索
了解数据集基本信息,包括数据集大小,各个字段的含义类型,目标和特征,也可通过可视化了解数据的分布。
data.shape查看数据形状;.shape[0]查看行;.shape[1]查看列数;
df.head()查看前几行;
df.describe()查看数值数据的描述统计信息;
df.info()根据行数查看数据是否有缺失值,数据类型是否合适。
3. 数据清洗与预处理
3.1 数据清洗
这部分更多是针对类似爬虫这种方式获取的数据,这种数据通常没有一个非常固定规范的格式,数据非常不稳定,因此需要进行前期的清洗工作,工作量很大。清洗的目标是让模型更加泛化,让数据更体现其价值,从而让模型更精确。
几种清洗方向:
1. 检查数据合理性:比如爬到的数据是否满足需求;
2. 检查数据有效性:爬到的数据量是否足够大,以及是否都是相关数据;3. 检查工具:爬虫工具是否有bug。
3.2 数据预处理
因为人为、软件、业务导致的异常数据还是比较多的,比如性别数据的缺失、年龄数据的异常(负数或者超大的数),而大多数模型对数据都有基本要求,比如不能缺失,而异常数据对模型是有影响的,因此通常都需要进行预处理。
3.2.1 数据缺失及异常场景
1. 数据缺失场景
1. bug导致缺失
因为程序bug导致缺失,这种缺失通常是少数的,一般都需要进行某种方式的填充;
2. 打点缺失
3. 正常业务情况导致缺失比如性别字段本身就是可以不填的,那么性别就存在缺失,且这种缺失可能是大量的,这里就要首先评估该字段的重要性以及缺失率,再考虑是填充,还是丢弃;
2. 数据异常场景
1. 绝对异常
比如人的年龄200岁,这个数据放到什么场景下都是异常;
2. 统计异常
比如某个用户一分钟内登陆了100次,虽然每一次登陆看着都是正常的,但是统计起来发现是异常的(可能是脚本在自动操作);
3. 上下文异常
比如冬天的北京,晚上温度为30摄氏度,虽然但看数据是正常,但是跟当前的日期、时间一关联,发现是异常;
3.2.2 数据预处理
一般包括:缺失值处理、重复值处理、数据类型的转换、字符串数据的规整。
1. 缺失值处理
1. 直接删除(适合缺失值数量较多,并且是随机出现的,删除它们对整体数据影响不大);
2. 数值类型,用平均值取代:data[A].fillna(data[A].mean())
3. 分类数据,用最常见的类别或代表未知的字符串填充;data[A].value_counts();
data[A].fillna("前面得到的最常见的类别");
data[A].fillna("U")缺失比较多时,填充代表未知的字符串;
4. 使用模型预测缺失值,例如:K-NN。
2. 数据归一化/标准化
一些模型具有伸缩可变性(如SVM),最好进行标准化,避免模型参数受极值影响;另一方面对于伸缩不变模型,如逻辑回归,最好也进行标准化,可以加快训练速度。
归一化/标准化常见两种方法:
1. min-max
化为[0,1]:
;适合分别在有限范围内的数据,数值较集中,但min/max不稳定会影响结果。
2. Z-core
化为均值为0,方差为1:,适合最大/最小值未知,或者有超出取值范围的离散值。
3.处理离群/极端值
识别异常值的方法有以下几种:
(1)简单的统计分析
(2)3∂原则
如果数据服从正态分布,在3∂原则下,异常值为一组测定值与平均值的偏差超过3倍标准差的值。如果数据服从正态分布,距离平均值3∂之外的值的出现的概率为P(|x-u|>3∂)<=0.003,属于极个别的小概率事件。如果数据不服从正态分布,也可以用远离平均值的多少倍标准差来描述。
(3)箱型图分析
箱型图提供了识别异常值的一个标准:如果一个值小于Q1-1.5IQR或大于Q3+1.5IQR,则被称为异常值。箱型图判断异常值的方法以四分位数和四分位距为基础,四分位数具有鲁棒性(25%的数据可以变得任意远并且不会干扰四分位数,所以异常值不能对这个标准施加影响,因此箱型图识别异常值比较客观)。
(4)基于模型检测
首先建立一个模型,异常值是那些与模型不能完美拟合的数据。
如何最大限度降低这些极端离群值的影响?
1. 对每个值取对数(对数缩放)
2. 限制最大/最小值
3. 删除异常值
4. 平均值替代
5. 视为缺失值
4. 数据分箱(Binning)
将特征值浮点数,分为几个范围,如32.3 32.5 为32-33范围,相应值为1为了将纬度变为一项实用的预测指标,对纬度“分箱”。
4. 特征工程
特征工程决定了机器学习的上限,模型只是逼近这个上限!特征工程是机器学习中最重要,也最难的部分,它难并不是技术上的,而是经验上的,一个经验丰富的算法工程师在看到项目、数据的同时,脑子里已经有了特征工程的雏形,这可以帮助他很快的得到一个不错的分数,而后续的优化上,经验也是最重要的参考。
4.1 特征构建
4.1.1 特征组合
例如组合日期、时间两个特征,构建是否为上班时间(工作日的工作时间为1,其他为0)特征,特征组合的目的通常是为了获得更具有表达力、信息量的新特征;
4.1.2 特征拆分
将业务上复杂的特征拆分开,比如将登陆特征,拆分为多个维度的登陆次数统计特征,拆分为多个的好处一个是从多个维度表达信息,另一个多个特征可以进行更多的组合;
4.1.3 外部关联特征
例如通过时间信息关联到天气信息,这种做法是很有意义的,首先天气数据不是原始数据集的,因此这样想当于丰富了原始数据,通常来讲会得到一个比仅仅使用原始数据更好的结果,不仅仅是天气,很多信息都可以这样关联(比如在一个Kaggle上的房屋预测问题上,可以通过年份关联到当时的一些地方政策、国际大事等等,都是有影响的,比如金融危机);
4.2 特征选择
1. 特征自身的取值分布
主要通过方差过滤法比如性别特征,1000个数据,999个是男的,1个是女的,这种特征由于自身过于偏斜,因此是无法对结果起到足够的帮助;
2. 特征与目标的相关性
可以通过皮尔逊系数、信息熵增益、基尼指数等来判断,思路是如果一个特征与目标的变化是高度一致的,那么它对于预测目标就是具有很大指导意义的;
3. 单特征AUC
4. 特征分裂次数
5. 模型输出特征重要度
4.3 特征处理
4.3.1 离散特征处理
1. 独热编码(one-hot encoding)
处理方法比较简单,比如某特征的取值是高、中和低,那么就可以创建三个取值为0或者1的特征,将高编码为1,0,0;中编码为0,1,0;低编码为0,0,1。也就是说,之前的一个特征被转化为了三个特征。
2. 特征嵌入(embedding)
这个一般用于深度学习中。比如对于用户的ID这个特征,如果要使用独热编码,则维度会爆炸,如果使用特征嵌入维度就低很多了。对于每个要嵌入的特征,会有一个特征嵌入矩阵,这个矩阵的行很大,对应该特征的数目。比如用户ID,如果有100万个,那么嵌入的特征矩阵的行就是100万。但是列一般比较小,比如可以取20。这样每个用户ID就转化为了一个20维的特征向量,进而参与深度学习模型。
在tensorflow中,可以先随机初始化一个特征嵌入矩阵,对于每个用户,可以用tf.nn.embedding_lookup找到该用户的特征嵌入向量。特征嵌入矩阵会在反向传播的迭代中优化。
4.3.2 连续特征的离散化处理
连续特征的离散化就是在数据的取值范围内设定若干个离散的划分点,将取值范围划分为一些离散化的区间,最后用不同的符号或整数值代表落在每个子区间中的数据值。首先要确定分类数,然后将连续特征值映射到这些分类值(等宽法、等频法、一维聚类)。
1. 根据阈值进行分组
比如根据连续值特征的分位数,将该特征分为高,中和低三个特征。将分位数从0-0.3的设置为低,0.3-0.7的设置为中,0.7-1的设置为高。
2. 基于聚类分析的方法
一维聚类的方法包括两个步骤,首先将连续特征的值用聚类算法(如K-Means算法)进行聚类,然后再将聚类得到的簇进行处理,合并到一个簇的连续特征值并做同一标记。聚类分析的离散化方法也需要用户指定簇的个数,从而决定产生的区间数。
3. 使用梯度提升树(GDBT)将连续值转化为离散值
在sklearn中,可以用GradientBoostingClassifier的 apply方法很方便的得到样本离散化后的特征,然后使用独热编码即可。
4.3.3时间类型的数据处理
1. 连续的时间差值法
即计算出所有样本的时间到某一个未来时间之间的数值差距,这样这个差距是UTC的时间差,从而将时间特征转化为连续值。
2. 将一个时间转化为离散特征
根据时间所在的年,月,日,星期几,小时数,将一个时间特征转化为若干个离散特征,这种方法在分析具有明显时间趋势的问题比较好用。
4.3.4 文本类型的数据预处理
1. 词袋
直接把文本数据丢给模型,模型是无法解释的,因此需要把文本型的数据用数值表示。去掉停用词,标点符号,留下表达实际含义的词组成列表,在词库中映射稀疏向量。
2. 把词袋中的词扩充到 n-gram
它的思想是:在整个语言环境中,句子T的出现概率是由组成T的N个词组成的。
3. 使用TF-IDF方法
4. word2vec将词转化为词向量(NLP)
4.4 降维
当特征选择完成后,可以直接训练模型了,但是可能由于特征矩阵过大,导致计算量大,训练时间长的问题,因此降低特征矩阵维度也是必不可少的。常见的降维方法除了以上提到的基于L1惩罚项的模型以外,另外还有主成分分析法(PCA)和线性判别分析(LDA),线性判别分析本身也是一个分类模型。PCA和LDA有很多的相似点,其本质是要将原始的样本映射到维度更低的样本空间中,但是PCA和LDA的映射目标不一样:PCA是为了让映射后的样本具有最大的发散性;而LDA是为了让映射后的样本有最好的分类性能。所以说PCA是一种无监督的降维方法,而LDA是一种有监督的降维方法。
1. 主成分分析法(PCA)
2. 线性判别分析法(LDA)
3. 奇异值分解(SVD)-文本降维
降维技术不是特征选择,降维是把高维数据的特征映射到低维空间中,而特征选择是在高维空间中直接剔除部分特征,选出重要特征。
5. 模型构建
5.1 训练集测试集划分
训练模型前,常用的HoldOut验证法(此外还有留一法、k折交叉验证等方法),把数据集分为训练集和测试集,并可再对训练集进一步细分为训练集和验证集,以方便评估模型的性能。
1. 训练集(training set): 用于运行学习算法,训练模型;
2. 开发验证集(development set): 用于调整超参数、选择特征等,以选择合适模型;
3. 测试集(test set): 只用于评估已选择模型的性能,但不会据此改变学习算法或参数。
5.2 模型选择
在更复杂的情况下,我们需要做出与预期结果相匹配的选择。可以在3大类中探索机器学习模型的选项。
5.2.1 监督学习模型
在这样的模型中,结果是已知的,因此不断改进模型本身,直到输出达到所需的精度水平。
5.2.2 无监督学习
如果结果未知,但需要分类,则需使用无监督学习。无监督学习的示例包括K-means和Apriori算法。
5.2.3 强化学习
它着重于学习在反复试验的基础上做出更好的决策。它们通常在商业环境中使用。马尔可夫的决策过程就是一个例子。
5.3 模型调优
模型的训练过程即学习数据经验得到较优模型及对应参数(如神经网络最终学习到较优的权重值)。整个训练过程还需要通过调节超参数(如神经网络层数、梯度下降的学习率)进行控制优化的。调节超参数是一个基于数据集、模型和训练过程细节的实证过程,需要基于对算法的原理理解和经验,借助模型在验证集的评估进行参数调优。
同一个模型不同参数下的表现依然是天差地别,通常在特征工程部分结束后就进入到模型参数调优的步骤,这一步也是最无聊最耗时间的,因此一个好的技巧还是比较实用的。
调参方式与工具:
1. 自动调参技术:网格搜索GridSearch、随机搜索及贝叶斯优化等;
2. 调参顺序上,建议是先重要的影响大的参数,后没那么重要的,影响小的参数;
3. 举例随机森林:作为集成方法中最常用的模型之一,通常第一个调的是n_estimator即树的个数,其次是学习率,再其次是max_feature,会发现这三个都是随机森林自身的参数,后面可以细调每棵树的参数,比如最小分裂样本数等等;
5.4 模型融合
一般来讲,任何一个模型在预测上都无法达到一个很好的结果,这是因为通常来说单个模型无法拟合所有数据,及不具备对所有未知数据的泛化能力,因此需要对多个模型进行融合,这一点在Kaggle上体现的也很明显,好的排名中基本都用了模型融合。主要有以下融合方式:
5.4.1 简单融合
1. 分类问题:
投票法融合,不考虑单个模型自身的得分;
2. 回归问题:
假设每个模型权重一致,计算融合结果;
5.4.2 加权融合
基本同上,区别是考虑每个模型自身得分,得分高的权重大;
5.4.3 使用模型进行融合
即将多个单模型的输出作为输入送入到某个模型中,让模型去做融合,通常可以达到最好的效果,但是由于用到了模型,因此要注意过拟合问题。
6. 模型评估
机器学习的直接目的是学(拟合)到“好”的模型,不仅仅是学习过程中对训练数据的良好的学习预测能力,根本上在于要对新数据能有很好的预测能力(泛化能力),所以客观地评估模型性能至关重要。技术上常根据训练集及测试集的指标表现,评估模型的性能。
6.1 评估分类模型
常用的评估标准有查准率P、查全率R及两者调和平均F1-score 等,并由混淆矩阵的统计相应的个数计算出数值。
查准率是指分类器分类正确的正样本(TP)的个数占该分类器所有预测为正样本个数(TP+FP)的比例;查全率是指分类器分类正确的正样本个数(TP)占所有的正样本个数(TP+FN)的比例。F1-score是查准率P、查全率R的调和平均:
6.2 评估回归模型
常用的评估指标有MSE均方误差等。反馈的是预测数值与实际值的拟合情况。
6.3 评估聚类模型
可分为两类方式,一类将聚类结果与某个“参考模型”的结果进行比较,称为“外部指标”(external index):如兰德指数,FM指数等。另一类是直接考察聚类结果而不利用任何参考模型,称为“内部指标”(internal index):如紧凑度、分离度等。
6.4 常用评估指标
6.4.1 P-R曲线
P-R曲线的横轴是召回率,纵轴是精确率。对于一个排序模型来说,其P-R曲 线上的一个点代表着,在某一阈值下,模型将大于该阈值的结果判定为正样本, 小于该阈值的结果判定为负样本,此时返回结果对应的召回率和精确率。整条P-R 曲线是通过将阈值从高到低移动而生成的。下图是P-R曲线样例图,其中实线代表 模型A的P-R曲线,虚线代表模型B的P-R曲线。原点附近代表当阈值最大时模型的 精确率和召回率。
6.4.2 F1分数
F1分数是精度和召回率的谐波平均值,正常的平均值平等对待所有的值,而谐波平均值回给予较低的值更高的权重,因此,只有当召回率和精度都很高时,分类器才能得到较高的F1分数。
6.4.3 AUC
AUC指的是ROC曲线下的面积大小,该值能够量化地反映基于ROC曲线衡量出的模型性能。计算AUC值只需要沿着ROC横轴做积分就可以了。 由于ROC曲线一般都处于 𝑦=𝑥。这条直线的上方(如果不是的话,只要把模型预测的概率反转成 1−𝑝 就可以得到一个更好的分类器),所以AUC的取值一般在 0.5~1 之间。AUC越大,说明分类器越可能把真正的正样本排在前面,分类性能越好。
7. 模型持久化
将得到的模型持久化到磁盘,方便后续使用、优化时,不需要从头开始;
8. 模型部署及监控
8.1 模型部署
模型评估通过后,模型将部署上线投入运营,接受线上的考验,任何的错误将直接造成经济损失。所以,在评估、验证模型的过程中,除了常规的模型性能统计指标外,还要重视可视化方法、多维度分析、线上比对分析,灰度上线、小流量测试等。上线时确保模型开发环境和线上环境一致,例如查看主要包的版本是否一致,特征处理结果是否一致、同一批数据的预测结果在开发和线上两个环境中是否一致,统计指标是否一致(AUC、KS)等。
8.2 模型监控
模型监控应该在模型上线前就有所准备,并在模型上线时一并上线,有时模型异常可能导致巨大的经济损失。当模型评分出现了偏移,需要查找是哪些特征造成的,此时特征监控将指出问题所在。当寻找这些问题的原因时,也可能牵扯出IT系统的故障。发现问题就是模型监控的意义所在。
模型监控的内容可分为如下几个部分。
1. 模型评分稳定性的监控:分布、稳定性指标、业务指标等;
2. 特征稳定性的监控:分布、稳定性指标等;
3. 线上服务稳定运行的监控。