机器学习
系统结构
系统认识, 机器学习就是 模型 + 策略 + 算法.
- 模型
- 就是是用什么模型来建模实际问题,比如线性,非线性,概率,图等;生成模型还是判别模型;决策函数;模型假设;模型复杂度.
-
策略
- 更多可以理解为损失函数;损失函数一般又是一个优化理论问题;
- 策略选取的目的是使得结构化风险最小;结构化风险=经验风险+lambda*正则.
- lambda用于权衡模型复杂度和经验风险, 往往模型复杂度和经验风险同时都小的时候,模型泛华能力就比较强.即对训练集和未知的测试数据预测都较好.
-
算法
- 对于建立的模型和评估模型好坏的策略, 需要我们找到一种算法, 得到最优解,或者近似最优解,局部或者全局的.
- 比如, 同样一个极小化损失函数, 你可以选取不同的方法来求解, 梯度下降(BGD,SGD,mini_BGD) 可以得到局部最优. 也可以采用QP二次规划求解, 甚至对于线性回归问题,可以直接用非奇异矩阵解线性方程组.
- SVM 求解方法就是采用了拉格朗日乘子法和对偶问题,使用 KTT 条件去解支撑向量点. 以及采用SMO算法优化.
- 算法,主要考虑数学上,模型收敛性,是否最优解等, 从计算机运行角度讲, 内存,计算量,快慢, 并行化等.
对于一个模型, 除了数学上的建模,优化外, 计算机角度来看,还需要考虑模型实现难度,学习算法的时间空间复杂度等.
学习的目的就是最小化期望风险, 即 最小化结构化风险=经验风险+lambda*正则. lambda就是经验风险和模型复杂度的权衡, 最终目的就是两者都尽可能小.
为什么朴素贝叶斯做了条件独立性假设之后, 模型效果还是很不错呢?
个人认为有两点, 第一是虽然条件变量之间的确不独立, 但是变量之间的相关性往往也没有我们想象的那么大;
第二, 如果假设不独立, 反而会让模型变得更加复杂, 更简单的模型相当于加入正则的经验风险, 模型泛化能力可能更好, 考虑过多相关性反而会出现过拟合.
策略选取(损失函数, 决策树并没有直接的损失函数,它是一种按照最大信息增益的标准做贪心选取算法)
- 0-1 损失 (朴素贝叶斯)
- 平方损失MSE (线性回归)
- 绝对值损失
- 对数损失(Logistic Regression): -Sigma(Yi * log H(Xi) + (1-Yi) * log (1 - H(Xi)); 正确肯定没有损失,情况下,假设是1, 那么就只有前面一项, 那么H(Xi) 的概率越大, 损失反而越小. 假设不正确,本来是1,预测0, 那么 H(Xi) 很小, 损失反而很大.
- Hinge 损失(SVM): 先斜线,后直线. 就是在个阈值之后, 损失都没有. 因为远离超平面的点没有影响.
- KL 散度
模型评估方法
- 方差(Variances)/偏差(Biases)度量:
- 混淆矩阵:
- 精确率Precision: 所有预测的正例中,有多少是真实的正例. TP/(TP+FP)
- 召回率Recall: 所有真实的正例中有多少被预测到了. TP/(TP+FN)
- 正确率Accuracy: 预测正确比所有的.(TP+TN)/(TP+FP+FN+TN)
- F1-Score: P 和 R 的调和平均
- ROC/AUC: Y轴-TPR[正样本召回率], X轴-FPR=(1-TNR)[1-负样本召回率], 两个同时都大,那么 AUC(ROC曲线下的面积)就大.模型越稳定,效果越好.
模型优化
过拟合
过拟合是在训练集非常好, 测试集不好. 这时从数据量,数据特征和模型本身考虑;
- 数据过少
- 增大数据量
- 特征过多
- 去掉冗余特征, 做特征选取
- 模型太复杂
- 选择更加简单的模型, 或者加入正则, DropOut
- 训练时间提前结束
- 模型融合
- Bagging
- Boosting
- 利用贝叶斯
哪些模型如果不做修改直接用,很容易过拟合?
决策树就容易过拟合, 解决方法是剪枝,控制深度,叶子节点个数等.
欠拟合
- 特征太少了
- 增加特征, 多项式特征等
- 模型太简单了
- 减少正则数量.
数据量
剔除噪声点,数据样本不均衡问题.
数据特征
为什么要做特征工程?
训练数据往往并不是所有数据的代表, 一方面含有噪声. 另一方面,特征过多, 训练时间过长,模型维度更大,更加复杂.
特征选择能剔除不相关(irrelevant)或亢余(redundant )的特征,从而达到减少特征个数,提高模型精确度,减少运行时间的目的。另一方面,选取出真正相关的特征简化了模型.
什么时候需要减少特征,什么时候需要增加特征?
噪声,特征升维, 特生抽取. 那些特征可以使用,人口统计学特征,时间,行为,点击,浏览,扫描.....
如何选取特征?
统计学相关性分析, 计算距离, 信息增益. 决策树模型, 线性回归等都可以看到特征重要性,因此也可以做特征选取.
特征分类:
(1)Low level特征和High level特征。(2)稳定特征与动态特征。(3)二值特征、连续特征、枚举特征。
特征处理与分析
- 特征归一化,离散化,缺省值处理
归一化
第三步:在导入LR模型进行训练之前还需要做一些特征工程的工作:
i. 清洗,删除或补齐一些会影响训练的脏数据,如空值、异常值等等;
ii. 标准化,为了消除不同特征之间由于量纲不同带来对模型拟合影响,需要对特征做标准化,不仅能加快模型拟合,还能提升效果。方法可根据情况使用如下几种:
(a) Min-Max:S(x) = (x – min(x))/(max(x) – min(x))
(b) Z-Score:S(x) = (x-avg(x))/stddev(x)
(c) Log:S(x) = ln(1+x)/(1+ln(1+x))
(d) 其他:
正向特征:S(x) = (1-exp(ln(1/3)/avg(x)x))/ (1+exp(ln(1/3)/avg(x)x))
负向特征:S(x) = 1-(1-exp(ln(1/3)/avg(x)x))/ (1+exp(ln(1/3)/avg(x)x))
iii. 平滑化,某些转化率特征,如点击率、留存率等,当分母很小的时候,往往会出现转化率极高的反常情况,会影响模型判断的准确性,所以需要做平滑。方法有几个:
(a)使用足够多的历史数据平滑;
(b)在分母大于某个量级才采用此转化率,否则为0或其他;
(c)在分母都加一个足够大的数据来稀释这种负面效果,如这个特征的平均值;
(d) 贝叶斯参数估计平滑。
iv. 离散化,即把原来的特征值分段,离散为一系列0、1向量,离散特征有几个优势:
(a)离散特征的增加和减少都很容易,易于模型的快速迭代;
(b)稀疏向量内积乘法运算速度快,计算结果方便存储,容易扩展;
(c)离散化后的特征对异常数据有很强的鲁棒性:比如一个特征是年龄>30是1,否则0;如果特征没有离散化,一个异常数据“年龄300岁”会给模型造成很大的干扰;
(d)逻辑回归属于广义线性模型,表达能力受限;单变量离散化为N个后,每个变量有单独的权重,相当于为模型引入了非线性,能够提升模型表达能力,加大拟合;
(e)离散化后可以进行特征交叉,由M+N个变量变为M*N个变量,进一步引入非线性,提升表达能力;
(f)特征离散化后,模型会更稳定,比如如果对用户年龄离散化,20-30作为一个区间,不会因为一个用户年龄长了一岁就变成一个完全不同的人。当然处于区间相邻处的样本会刚好相反,所以怎么划分区间是门学问;
Tips:用户画像特征、物品属性特征必须做离散化,用户对物品属性的行为特征和物品画像特征也必须做离散化,用于后续特征组合Cross;其他连续型特征可以看情况做,如需快速上线,可考虑省略,也可考虑直接用GBDT这样的算法来自动做特征离散化。
v. 特征组合 cross,上一步做离散化其中一个目的就是为了方便做 cross,cross 不仅能从数据上真正实现把用户最可能感兴趣的物品推荐给他,而且还能帮模型引入非线性,提高模型表达能力,提升效果;常用的 Cross 方法一般有内积和笛卡尔积两种,可能更具具体情况使用,笛卡尔积带来的特征膨胀会比较厉害。
Tips:以下两类 cross 必须要做,用户画像特征X 物品画像特征;用户对物品属性行为特征X 物品属性特征。用户对用户和物品对物品的 cross 可以根据具体情况考虑来做。
vi. 特征筛选,目的是选择模型最优特征子集。特征与特征之间多多少少会有一些相互作用,比如有些特征是包含其他特征,有些特征与另一些特征存在相关性的,也有一些特征需要与其他特征组合起来才能起作用,还有一些特征是会存在负相关的;正是因为特征之间的这些关系,合理的选择适合的特征集合对于模型效果有非常大的作用。比较可行的选择方法有以下两类:
(a) Filter,这种方法是衡量单个特征值与目标变量也就是样本label值之间的关联,常用的方法有:相关系数,卡方检验,信息增益,基尼系数;
(b)Embedded,这种方法我觉得是一个比较可行的一种方法,它的思想是使用模型自身自动的选择特征,比如正则化—L1 Lasso具有特征选择能力,决策树,每次选择分类节点时,都会选择最佳的分类特征来进行切分。
Tips:可以抽样样本数据到R中去训练,结果会输出一个特征显著性p值打分,很方便我们进行初步特征筛选,如下图;也可能在LR训练前,先尝试用RF训练一次,能得出特征对label的重要性排序,然后在根据这个排序选择比重较大的特征放到LR去训练。
离散化
- 离散特征的增加和减少都很容易,易于模型的快速迭代;
- 稀疏向量内积乘法运算速度快,计算结果方便存储,容易扩展;
- 离散化后的特征对异常数据有很强的鲁棒性:比如一个特征是年龄>30是1,否则0。如果特征没有离散化,一个异常数据“年龄300岁”会给模型造成很大的干扰;
- 逻辑回归属于广义线性模型,表达能力受限;单变量离散化为N个后,每个变量有单独的权重,相当于为模型引入了非线性,能够提升模型表达能力,加大拟合;
- 离散化后可以进行特征交叉,由M+N个变量变为M*N个变量,进一步引入非线性,提升表达能力;
- 特征离散化后,模型会更稳定,比如如果对用户年龄离散化,20-30作为一个区间,不会因为一个用户年龄长了一岁就变成一个完全不同的人。当然处于区间相邻处的样本会刚好相反,所以怎么划分区间是门学问;
-
特征离散化以后,起到了简化了逻辑回归模型的作用,降低了模型过拟合的风险。
-
特征降维
- 特征选择
机器学习中的数据清洗与特征处理综述
数据量和特征维度对模型选取的影响
先用简单模型,
SVM一般做到几十万的数据量就会变得很慢了.SVM对数据范围敏感,需要归一化.
样本不均衡问题
数据采样.对负样本多采样.
softmax 和 sigmoid 区别
softmax 是直接可以做多分类的, 因为计算结果的每一个score都指数化之后除以他们的加和, 最终对每一类的预测就是基于概率模型的.
sigmoid 直接使用的时候其实就只能做二分, 现将 决策函数算出来的 score 通过 sigmoid 映射到 0 - 1, 然后设置一个概率阈值,决定二分类问题.
模型本身复杂度
加入正则. 正则区别L0, L1, L2. 为了降低模型复杂度, 防止模型将某些不重要的特征也学习出一个较高的权重, 在训练数据集上过拟合, 我们需要找出哪些特征是不重要甚至是无用的, 即L0 正则. 但是这是 NP 问题, 很难求解.
L1 正则, L1 正则是 在 0 处不可导, 这个特性使得在求解最小化结构风险函数的时候, L1 正则学习出来的参数倾向于稀疏, 有些地方就直接是 0 了. 因此可以做特征抽取和降维. 典型的是 Lasso 线性回归.
L2 正则处处可导, 学习出来的参数也是比较平滑的,他可以保证所有的特征不会出现一些权重很大的, 可以防止过拟合. 典型的是 Rindge 线性回归.
另外, L1 和 L2 使用梯度下降求解的时候, 收敛速度也不一样. 对于 L1 最后权重更新公式其实是每一次都做在原来权重基础上先做一个减法减少权重, 因此在权重较小的时候他下降的比较快,但是权重还很大的时候下降比较慢;
而 L2 正则导数之后, 梯度更新公式每一次先在原来权重基础上成比例减小, 对于大权重的时候, 收敛下降就快.
模型融合Ensembling
Bagging:
- RandomForest
- 数据采样,特征采样, 稳定性,数据多样性复杂也适用
Boosting:
- AdaBoost(加权投票机制)
- 每一课树其实是可用的.
- Gradient Boosting Decision Tree(基于梯度提升)
- 当前的树学习的是前面累计模型的残差, 因此只有组合起来才可用.
- Xgboost
- 利用二阶导, 能够更快的在训练集上收敛, 并在实现上充分利用了多核并行计算.
模型分类
监督学习可以分为生成模型还是判别模型
生成模型: 可以还原输入变量和输出变量的联合概率分布P(X, Y), 收敛速度快, 存在隐变量也可以使用,但判别模型不能
- 朴素贝叶斯
判别模型: 不能还原联合概率,学习的是条件概率P(Y|X)或者决策函数f(X).含有隐变量时不能使用.
- K近邻法(KNN), 感知机(Perceptron), 决策树(Decision Tree), 逻辑斯特回归(Logistic Regression), 最大熵模型, 支持向量机(SVM), 提升方法(Boosting), 条件随机场(CRF)
线性模型还是非线性模型
主要是决策函数部分决定的, 比如 Linear Regression, Logistic Regression, Linear Kernel SVM, 感知器 都是线性模型.
Decsion Tree, Naive Bayes, AdaBoost, GBDT, SVM(非线性核), KNN(K近邻)都是非线性模型.
监督还是无监督还是半监督
带标签,不带标签.
二分类模型如何延展做多分的
One-Vs-One k*(k-1)/2 投票
One-vs-All k 概率最大的那个
决策树中, 回归就取叶子中所有值的均值,或者继续加一个LinearModel. 多分类就做投票.
资源
KNN 和 K-Means 算法的区别
K 近邻算法KNN(K-nearest-neighbors) 是一种有监督学习算法,对于一个给定的样例,通过找出所有训练样例[(x1,y1),(x2,y2)...(xn,yn)]中与该样例距离最近的K个点,看这k个点大多数属于那个类别,就将该节点归为哪一类,也就是说评价函数采用的是投票。
K-Means 算法是一种无监督学习算法,他的目的是将所有的没有标签的数据[x1,x2,...xn]划分成 K 类。采用随机选择k个点作为k个类的中心,然后计算每一个点到这k个点的距离,距离那个近就属于哪一类,然后一轮聚类完成之后,根据 K 类的数据中心点,重新分配k个中心点,再次聚类,直到和上一次聚类选出的中心点相同或者误差可接受稳定后,就可以停止聚类。而评价聚类好坏的函数是算出每一种K聚类之后,各个类中的样本点到其中心的距离的和,取最小的。K-means Clustering in Python
以上两种算法的计算量就在于,每次计算距离都需要计算所有的点到样本或者是中心点的距离,计算量巨大。因此,这两种算法都是可以通过 KD树(kd-tree) 进行加速搜索和计算的。KD 树可以在确定某一个点属于哪个类别的时候,较少和训练点的距离计算,可以直接忽略某些点从而加速计算过程;
KD 树通过对样本维度进行空间划分,构成一个平衡二叉树,然后再进行KD搜索,搜索的时候,例如在KNN中,先确定给定点在KD树的叶节点位置,然后计算该区域最近的点,以给定点S为圆心,以最近距离为半径的圆超平面,然后回溯到父节点,检查父节点的另一个子节点里是否有更近的点,没有则继续回溯到父节点,检查父节点的另一个子节点是否有,知道没有或者到根即终止。时间复杂度是O(lgN)
使用kd-tree加速k-means
贝叶斯先验概率后验概率条件概率似然函数
后验概率 = 先验概率 x 似然函数
- 详解最大似然估计(MLE)、最大后验概率估计(MAP),以及贝叶斯公式的理解
- 先验分布、后验分布、似然估计这几个概念是什么意思,它们之间的关系是什么?
- 贝叶斯平滑