对于实际生活中的复杂事物来说,如果要使用机器学习方法来解决,对实际问题进行建模,将其抽象为数学问题是首要的工作。下面举几个简单例子
预测本地明天的天气
首先你需要利用生活常识和收集资料得到的专业知识,知道可能会对天气有影响的因素;然后去收集数据,明确自己的目的。是想使用过去的天气情况来预测明天的气温范围呢,还是单纯的想知道明天会不会下雨,会不会有雾霾。根据你的目标不同,前者是回归问题,而后者是分类问题。
决定要不要购买一件商品
首先你可能会查看店铺评分,判断这是不是一家靠谱的店铺;其次可能会查看一些商品信息,如品牌、商品的成交量、价格、评论、实物图等等。这里所有你可以搜集到的信息都可以作为是否购买这件商品的参考,同样的这是一个分类问题。
简而言之,在这个阶段我们应该充分发掘复杂场景的内容,充分明确我们的目标。
hive
表和集群(如HDFS
)文件数据和特征决定了机器学习结果的上限,而算法只是尽可能逼近这个上限。
大多数模型对于样本分布(如二分类任务中的正负样本分布)比较敏感,如LR、NN比较敏感,而基于树的模型不是很敏感。当我们要处理海量数据时,一般没有时间和精力在所有的数据上面进行特征提取、模型训练、寻找超参数等,需要对数据进行采样处理。对原始数据集划分为训练集和测试集的过程也是一种数据采样操作。
可能会破坏掉原来数据中存在的结构(如性别比例等)
在保持数据原有结构(如性别比例等)的情况下,进行采样
这里我们认为正样本数量少,负样本数量多,差距在一个数量级以上
正负样本数据量都很大的情况下:
下采样(随机采样、分层抽样)
正负样本数据量都很小的情况下:
改变正负样本权重
lightGBM
、xgboost
的模型中可以进行相关设置(balanced
,scale_pos_weight
)特征是指从数据中抽取出来的对预测结果有用的信息
特征工程指使用专业背景知识和技巧处理数据,使得特征能够在机器学习算法中发挥更好作用地过程。更好地特征意味着模型更高的上限,意味着使用简单的模型就能达到好的效果,意味着更强的灵活度。
对于工业界来说,大部分复杂模型的算法精进都是资深的数据科学家的任务,大部分人员的工作还是跑数据、map-reduce
,hive SQL
,数据仓库搬砖,做一些业务分析、数据清洗、特征工程(找特征)的工作。
特征工程的作用也很明显,对于搜索引擎厂、广告部门、电商的商品推荐,阿里天池比赛经常出现上万维的交叉特征。
>>> from sklearn.preprocessing import Binarizer
>>> X = [[ 1., -1., 2.],
... [ 2., 0., 0.],
... [ 0., 1., -1.]]
>>> transformer = Binarizer().fit(X) # fit does nothing.
>>> transformer
Binarizer(copy=True, threshold=0.0)
>>> transformer.transform(X)
array([[1., 0., 1.],
[1., 0., 0.],
[0., 1., 0.]])
X_std = (X - X.min(axis=0)) / (X.max(axis=0) - X.min(axis=0))
X_scaled = X_std * (max - min) + min
example:
>>> from sklearn.preprocessing import MinMaxScaler
>>>
>>> data = [[-1, 2],
... [-0.5, 6],
... [0, 10],
... [1, 18]]
>>> scaler = MinMaxScaler()
>>> print(scaler.fit(data))
MinMaxScaler(copy=True, feature_range=(0, 1))
>>> print(scaler.data_max_)
[ 1. 18.]
>>> print(scaler.transform(data))
[[0. 0. ]
[0.25 0.25]
[0.5 0.5 ]
[1. 1. ]]
>>> print(scaler.transform([[2, 2]]))
[[1.5 0. ]]
归一化:均值为0,方差为1
标准化:
log、exp等变化:针对长尾分布,将其转换为类正态分布
统计值max、min、mean、std:如考虑日最高气温、日最低气温来决定是否开空调
连续数值离散化:对于如用户年龄、商品价格等离散化。等步长划分:简单、线上线下没有区别。等频划分(等分位数、等样本数),如min,25%,50%,75%,max:精准,线上应用时需要重新计算
hash分桶:如判断新闻主题的时候,统计每句话中含有的政治、经济、体育词库中词的个数
每个类别下对应的变量统计值histohistogram(分布状况):如分别统计男生和女生对于所有爱好的比例,将其作为男生和女生的直方图映射,如男:[1/3,2/3,0]
,女:[1/3,0,2/3]
转换为类别型
sklearn.one-hot_encoder()
,对于user id
等数量很大的特征,会先根据其历史购物行为进行聚类,再按照其cluster id
进行one-hot编码pandas.get_dummies()
TF(t)=词t在当前文中出现的次数/词t在全部文档中出现的次数
,IDF(t)=ln(总文档数/含t的文档数)
,TF-IDF权重=TF(t)*IDF(t)
word2vec
:现有的工具有Google word2vec
、gensim
历届kaggle、天池比赛,天猫、京东排序和推荐业务线里模型用到的特征:
user clustered id && category
,user clustered id && clothes style
直到这一步才用到我们上面说的算法进行训练。现在很多算法都能够封装成黑盒供人使用。但是真正考验水平的是调整这些算法的超参数,使得结果变得更加优良。这需要我们对算法的原理有深入的理解。理解越深入,就越能发现问题的症结,提出良好的调优方案。
如何确定模型调优的方向与思路呢?这就需要对模型进行诊断的技术。
过拟合、欠拟合判断是模型诊断中至关重要的一步。常见的方法如交叉验证,绘制学习曲线(如同时绘制训练数据和验证数据的损失,观察其变化情况)等。过拟合的基本调优思路是增加数据量,降低模型复杂度(如进行特征选择)。欠拟合的基本调优思路是提高特征数量和质量,增加模型复杂度。
误差分析也是机器学习至关重要的步骤。通过观察误差样本,全面分析误差产生误差的原因:是参数的问题还是算法选择的问题,是特征的问题还是数据本身的问题……
诊断后的模型需要进行调优,调优后的新模型需要重新进行诊断,这是一个反复迭代不断逼近的过程,需要不断地尝试, 进而达到最优状态。
一般来说,模型融合后都能使得效果有一定提升,而且效果很好。
工程上,主要提升算法准确度的方法是分别在模型的前端(特征清洗和预处理,不同的采样模式)与后端(模型融合)上下功夫。因为他们比较标准可复制,效果比较稳定。而直接调参的工作不会很多,毕竟大量数据训练起来太慢了,而且效果难以保证。
这一部分内容主要跟工程实现的相关性比较大。工程上是结果导向,模型在线上运行的效果直接决定模型的成败。 不单纯包括其准确程度、误差等情况,还包括其运行的速度(时间复杂度)、资源消耗程度(空间复杂度)、稳定性是否可接受。
这些工作流程主要是工程实践上总结出的一些经验。并不是每个项目都包含完整的一个流程。这里的部分只是一个指导性的说明,只有大家自己多实践,多积累项目经验,才会有自己更深刻的认识。
后面会整理数据处理、特征处理的例子,加入到文章中