sklearn文档 — 1.1. 普通线性模型
原文章为scikit-learn中"用户指南"-->"监督学习的第一节:Generalized Linear Models"######
下面是一组用在回归中的方法,其预期的结果为各输入变量的线性组合。在数学的概念里,如果** ý 表示我们预测出的结果:
在这一节中,我们定义向量 w = (w1, ..., wp) 为 系数(coef_) ,而 w0 为 截距(intercept_) **。如果要使用线性模型来进行分类的话,可以查看下方的Logistic回归。
1.1.1. 普通最小二乘法(Ordinary Least Squares)#
Linear Regression 拟合一个带有系数** w = (w1, ..., wp) **的线性模型去最小化其预测结果与实际结果的残差平方和。它的公式为:
Linear Regression 会接收其** fit 方法的数组X, y,并且在拟合后将其计算出的系数 w 存放至其线性模型的 coef_ **属性里:
>>> from sklearn import linear_model
>>> reg = linear_model.LinearRegression()
>>> reg.fit ([[0, 0], [1, 1], [2, 2]], [0, 1, 2])
LinearRegression(copy_X=True, fit_intercept=True, n_jobs=1, normalize=False)
>>> reg.coef_
array([0.5, 0.5])
然而,OLS(普通最小二乘法)里面的系数估量器依赖于当前的模型。当模型与设计矩阵** X **存在近似线性相关的关系时,设计矩阵会变得趋近奇异,其结果是最小二乘法的估量器对观察结果(估量结果)中出现的随机错误会变得很敏感,以致于产生很大的方差。在这种情况下有几率会出现多重共线性,例如,当没有经过实验与设计(数据)时所采集到的数据。
示例
1.1.1.1. OLS的复杂度##
这个方法通过X的奇异值分解来计算其最小二乘解。如果X是一个大小为(n, p)的矩阵,在假设** n ≥ p 的情况,其复杂度为 O(np^2) **。
1.1.2. 岭回归 (Ridge Regression)#
Ridge Regression通过对系数的大小添加一些惩罚以解决一些OLS(普通最小二乘法)的问题。通过岭系数来最小化惩罚的残差平方和。
其中,α ≥ 0 是一个控制收缩量的复杂度参数:α的值越大,收缩量的值也越大。因此系数对共线性变得更加鲁棒。
岭系数作为正则化函数
与其他线性模型一样,岭会接收其** fit 方法的数组X, y,并且在拟合后将其计算出的系数 w 存放至其线性模型的 coef_ **属性里:
>>> from sklearn import linear_model
>>> reg = linear_model.Ridge (alpha = .5)
>>> reg.fit ([[0, 0], [0, 0], [1, 1]], [0, .1, 1])
Ridge(alpha=0.5, copy_X=True, fit_intercept=True, max_iter=None,
normalize=False, random_state=None, solver='auto', tol=0.001)
>>> reg.coef_
array([0.34545455, 0.34545455])
>>> reg.intercept_
0.13636...
示例
1.1.2.1. 岭的复杂度##
该方法与OLS有着相同的复杂度。
1.1.2.2. 设置正则化参数:广义交叉验证法##
RidgeCV实现了内置对α参数交叉验证的岭回归。该对象的工作方式与GridSearchCV相同,除了它缺省为广义交叉验证(GCV),其为留一法交叉验证的一种高效实现:
>>> from sklearn import linear_model
>>> reg = linear_model.RidgeCV(alphas=[0.1, 1.0, 10.0])
>>> reg.fit([[0, 0], [0, 0], [1, 1]], [0, .1, 1])
RidgeCV(alphas=[0.1, 1.0, 10.0], cv=None, fit_intercept=True, scoring=None,
normalize=False)
>>> reg.alpha_
0.1
参考资料
1.1.3. Lasso回归分析#
Lasso是一个估量稀疏系数的线性模型。因为它倾向于选择具有比较少的参数值的解,所以它在一些特定的情况下很有用,因此可以有效的减少依赖的变量个数。因为这种特性,Lasso和其衍生算法都是压缩感知领域的基石。在特定的情况下,他可以恢复特定非零权重的集合(可以查看Compressive sensing: tomography reconstruction with L1 prior (Lasso))。
在数学概念上,它是由经过** L1 作为正则化参数先验后的一个线性模型组成。它的最小化公式为:
Lasso估量在添加了α || ω ||1后,其中 α 是为常数且 || ω ||1 为 L1范数 **的参数向量时,其能够最小化最小二乘法的惩罚。
Lasso的实例使用坐标下降法去拟合其系数。若要查看另一种实现,可以参考最小角回归:
>>> from sklearn import linear_model
>>> reg = linear_model.Lasso(alpha = 0.1)
>>> reg.fit([[0, 0], [1, 1]], [0, 1])
Lasso(alpha=0.1, copy_X=True, fit_intercept=True, max_iter=1000,
normalize=False, positive=False, precompute=False, random_state=None,
selection='cyclic', tol=0.0001, warm_start=False)
>>> reg.predict([[1, 1]])
array([0.8])
lasso_path很适用于低维的任务,其会沿着所有的可能值路径来计算出系数。
示例
注释: Lasso的特征选择
因为Lasso回归会产生出稀疏模型,所以它可以用来作为特征选择,在基于L1的特征选择可以查看其处理细节。
注释: 随机稀疏
对于特征选择或稀疏恢复,使用 Randomized sparse models 可能会更好。
1.1.3.1. 设置正则化参数##
**α **参数控制了估量器系数的稀疏程度。
1.1.3.1.1. 使用交叉验证###
scikit-learn的 LassoCV
和 LassoLarsCV
可以通过其对象的交叉验证来设置Lasso的** α 参数:。LassoLarsCV
是基于下面所解释的最小角回归算法来实现的。
对于带有许多共线性回归的高维度数据集,LassoCV
可以说是最适合的。但LassoLarsCV
却对揭露 α **参数的相关值有优点,并且如果样本的数量与观察数量相比非常小的话,其处理速度要远远快于 LassoCV
Lasso中,每个折叠上的均方误差:最小角回归
1.1.3.1.2. 基于模型选择的信息准则##
LassoLarsIC
估量器建议使用赤池信息准则(AIC)和贝叶斯信息准则(BIC)。当使用K层交叉检验时,由于正则化路径仅仅只计算一次而不是K + 1次,所以这是一种更节省的替代方案去获取** α **的最优值。然而, 许多准则需要对解决方案中存在对自由度的适当估量结果,即为在假设模型是正确的,且计算数据确实是由该模型生成的情况下,针对大样本(渐近结果)导出的估计结果,不过当条件处于失衡状态时(特征数大于样本数),它们却倾向于打破此准则。
示例
1.1.4. 多任务Lasso回归分析#
MultiTaskLasso
是一个用于在多重回归问题中估量稀疏系数的线性模型,其** y 是一个二维数组,即形状 (n_samples, n_tasks) **。这个约束的所选特征对于所有回归问题都是一样的,统称为任务。
下面各图比较了简单Lasso与多任务Lasso的W中非零的位置情况。Lasso估量器产生了分散的非零,而多任务Lasso则是完整的列。
多任务Lasso与简单Lasso的对比图B
在拟合时间序列模型时,需强制任何活动特征始终处于活动状态。
示例
在数学概念上,其包含了一个经过混合L1,L2范数训练出的线性模型。其最小化函数为:
其中** Fro **表示弗罗贝尼乌斯范数:
弗罗贝尼乌斯范数
且L1,L2:
L1,L2范数
在类MultiTaskLasso
的实现里,其使用了坐标下降算法去拟合其系数。
1.1.5. 弹性网络#
ElasticNet
是一个使用L1和L2范数进行先验训练出的线性回归模型。这种组合允许学习稀疏模型,例如Lasso这样在权重中带有少量非零项的,同时也能像岭般保留其正规化的特性。我们可以通过使用** l1_ratio 参数来控制L1和L2的凸组合。
当存在互相依赖的多重特征时,弹性网络很适合应用在这种情况。Lasso倾向于随机的取出其中一项,而弹性网络则倾向于一组一组来取出。
这种在Lasso与岭的折中办法是它允许弹性网络继承一些岭在旋转下的稳定性。
其最小化公式如下:
弹性网络与Lasso的对比
ElasticNetCV
类可以通过交叉验证来设置 alpha(α) 和 l1_ratio(ρ) **参数。
示例
1.1.6. 多任务弹性网络#
MultiTaskElasticNet
是估计多重回归问题中稀疏系数的一个弹性网络模型。其** Y 是一个二维数组,即形状 (n_samples, n_tasks) 。这个约束的所选特征对于所有回归问题都是一样的,统称为任务。
在数学定义上,其是由混合了L1,L2范数且使用L2范数作为正规化参数训练出的一个线性模型。其最小化公式为:
在类MultiTaskElasticNet
的实现里,其使用了坐标下降算法去拟合其系数。
MultiTaskElasticNet
类可以通过交叉验证来设置 alpha(α) 和 l1_ratio(ρ) **参数。
1.1.7. 最小角回归#
最小角回归(LARS)是一种面向高维度数据由 Bradley Efron, Trevor Hastie, Iain Johnstone 和 Robert Tibshirani开发的一种回归算法。
LARS的优点有:
- 在 p >> n 的情况下拥有高效的计算能力(即当维度的数量明显大于样本点的数量)
- 在计算速度上与前向选择一样快,并且具有与普通最小二乘法相同的复杂度。
- 产生一个完整的分段线性求解路径,其在交叉验证或类似的调整模型的行为上十分有效。
- 如果两个变量的响应几乎相等,那么其系数也有大致相同的增长速率。也因此该算法会表现的如同我们所期望般,并且也会更加稳定。
- 很容易为其他估量器产生解决解,例如Lasso。
当然也有缺点:
- 因为LARS是基于残差的迭代重组,所以它会表现出对噪音的高度敏感。这个问题的讨论细节于 Weisberg 在 Annals of Statistics article(2004) 中与 Efron 等人的讨论部分。
LARM模型能够使用 Lars
估量器,或者其低维的实现版本 lars_path
。
1.1.8.1 LARS Lasso#
LassoLars
是Lasso模型在引入了LARS算法后的一种新的实现。这不同于基于坐标下降的实现,它会产生一个精确的解,作为其系数的范数的分段线性函数。
>>> from sklearn import linear_model
>>> reg = linear_model.LassoLars(alpha=.1)
>>> reg.fit([[0, 0], [1, 1]], [0, 1])
LassoLars(alpha=0.1, copy_X=True, eps=..., fit_intercept=True,
fit_path=True, max_iter=500, normalize=True, positive=False,
precompute='auto', verbose=False)
>>> reg.coef_
array([0.717157..., 0. ])
示例
-
使用LARS的Lasso路径
LARS算法几乎完全提供了沿着正则化参数的系数的完整路径,因此常见的操作是使用包括所有检索的路径的 lars_path
函数。
1.1.8.1. 数学公式##
该算法类似前向逐步回归,但不在每一个步骤中都包含了变量,估计出的参数在与残差的每个相关的相同方向上增加。
LARS的解法是通过曲线表示参数向量的L1范数上每个值的解,而且不是输出一个向量值。全关联路径通过排序后存储进** coef_path_ **数组里,其大小为(n_features, max_features + 1),并且其第一列的值始终为0。
引用
- 原始算法在 Hastie 等人编写的论文 Least Angle Regression中有详细的描述。
1.1.9. 正交匹配追踪(OMP)#
OrthogonalMatchingPursuit
和 orthogonal_mp
实现了OMP算法去近似的拟合在非零系数的数量上有约束的线性模型(即存在L0 伪范数)。
作为一个像 最小角回归(LAR)的前向特征选择算法,OMP可以在固定数量的非零元素下逼近最优解向量:
或者,OMP可以针对一个特定的误差而不是固定数量的非零系数来求最优解,这过程可以表达为:
OMP下对特定误差求最优解
OMP基于一个贪婪算法,使其能够包含在每一步计算中与当前残差最相关的元素。这与简单匹配追踪(MP)有点相似,但是比这一点更好的是,在每一次迭代中,它都会在先前选择出的字典元素空间中重新使用正交投影来计算残差。
示例
引用
- http://www.cs.technion.ac.il/~ronrubin/Publications/KSVD-OMP-v2.pdf
- Matching pursuits with time-frequency dictionaries, S. G. Mallat, Z. Zhang,
1.1.10 贝叶斯回归#
贝叶斯回归技术能够在估量结果的过程中包含正规化的参数:其正规化参数并不是预先设置好的,而是根据获得的数据进行调整。
这种特性可以通过在模型的超参数上引入无信息先验(uninformative priors)来完成。L2-正则化在岭回归里,用来在通过精度为** λ - 1 的高斯先验的参数 ω 的情况下,为模型寻找一个最大归纳解,而不是手动设置一个 λ 值,所以视其在估量数据的过程中的一个随机变量。
为了获得一个完全概率模型,输出值 γ 假定为 Χω **的高斯分布:
**α **同样可以视为在估量过程中的一个随机变量。
贝叶斯回归的优点有:
- 它是适配数据的;
- 能够在估量过程中包含正则化参数。
其缺点为:
- 在推理模型的过程中可能很耗时。
引用
- BishopChristopher M. Bishop 著的 《Pattern Recognition and Machine learning》 一书中关于贝叶斯的章节。
- Radford M. Neal 著的 《Bayesian learning for neural networks》 一书中对原始算法的讨论。
1.1.10.1 贝叶斯岭回归##
BayesianRidge
为估计上述章节说明的回归问题的概率模型。其参数** ω 的先验值由球面高斯给出:
α 和 λ 的先验是通过伽玛分布决定的,即共轭先验的高斯精度。
其产生的模型被称之为贝叶斯岭回归,并且其跟岭相似。参数 ω , α 和 λ 都是在拟合模型的过程中同步估计出的。而剩余的超参数则是 α 和 λ **的先验参数。他们通常都是被选择为无信息的,通过最大化边际对数似然来估计参数。
在默认情况下, ** α1 = α2 = λ1 = λ2 = 1.e^-6 **。
权重分布图
以下是使用贝叶斯岭回归的例子:
>>> from sklearn import linear_model
>>> X = [[0., 0.], [1., 1.], [2., 2.], [3., 3.]]
>>> Y = [0., 1., 2., 3.]
>>> reg = linear_model.BayesianRidge()
>>> reg.fit(X, Y)
BayesianRidge(alpha_1=1e-06, alpha_2=1e-06, compute_score=False, copy_X=True,
fit_intercept=True, lambda_1=1e-06, lambda_2=1e-06, n_iter=300,
normalize=False, tol=0.001, verbose=False)
经过拟合后,模型就可以用来预测数据了:
>>> reg.predict ([[1, 0.]])
array([0.50000013])
可以通过访问模型的** coef_ 变量成员来获取权重 ω **:
>>> reg.coef_
array([ 0.49999993, 0.49999993])
因为贝叶斯的框架所致,用OLS和贝叶斯产生出来的模型的权重是不一样的。但是贝叶斯岭对此问题却更健壮。
示例
引用
- 能够在MacKay, David J. C编写的文章 《Bayesian Interpolation》 中获取到更多有关于此的细节。
1.1.10.2. 自动相关决策 - ARD##
ARDRegression
与 贝叶斯岭回归 非常相似,除了它会导致产生的稀疏权重外[1][2]。
ARDRegression
在** ω 上给出了一个不同先验,通过忽视高斯是球形的事实,而是相假定分布为轴平行的椭圆高斯分布。
这意味着每个权重 ωi 都是由以零为中心,且精确度为 λ **的高斯分布中获取的。
其中
A的角度
相比 贝叶斯岭回归,每一个** ωi 的坐标都有其标准差 λi 。所有 λi 的先验都是通过超参数 λ1 和 λ2 **给出的一个相同的伽马分布中获取的。
ARD在文献中也被称为稀疏贝叶斯学习和相关向量机[3][4]。
示例
引用
- Christopher M. Bishop: Pattern Recognition and Machine Learning, Chapter 7.2.1
- David Wipf and Srikantan Nagarajan: A new view of automatic relevance determination
- Michael E. Tipping: Sparse Bayesian Learning and the Relevance Vector Machine
- Tristan Fletcher: Relevance Vector Machines explained
1.1.11. Logistic 回归#
Logistic回归,虽然他的名字带有回归,但是他是一个用来解决分类问题的线性模型。Logistic回归在文献里也被称为Logit回归,最大熵分类(MaxEnt)或对数线性分类器。在这个模型里,其概率为在单次试验中使用logistic函数生成的概率。
scikit-learn中的logistic回归的实现为类 LogisticRegression
。这个实现能够使用可选的L2或L1正则化来拟合二元问题,One-vs-Rest,或者多项式Logistic回归。
在优化方面,L2二元类通过惩罚logistic回归来最小化下述的代价函数:
使用L1最小化的方法也是类似的:
Logistic的L1最小化
LogisticRegression
类中实现的解算器有“liblinear”,“newton-cg”,“lbfgs”和“sag”:
"liblinear"使用坐标下降(CD)算法并依赖于在scikit-learn内的C++的优秀类 LIBLINEAR library 实现的 。但是"liblinear"却没办法学习多分类模型。但是对这个问题的替代方案是,使用"one-vs-rest"方式来把所有的分类分割成单独的二元分类问题(即判断一个东西为A,B还是C,可以对这个东西分别判断A,B,C)。当然这一处理过程是向使用者隐藏的,所以LogisticRegression
实例在默认情况下是使用这一方式来作为求解器的。对于L1惩罚项, sklearn.svm.l1_min_c
会计算C的下限以获得一个非零模型(即防止所有特征权重值均为0)。
"lbfgs","sag"和"newton-cg"求解器只支持L2惩罚项且在对高维数据时有收敛更快的特性。可以通过在求解器设置** multi_class **为 "multinomial"使其能够支持多元Logistic回归模型[5],同时这样做能够使其比默认的"one-vs-rest"设置上有着更好的准确度。但"lbfgs","sag"和"newton-cg"求解器无法优化带有L1惩罚项的模型。
"sag"求解器使用一种叫随机梯度下降的算法[6]。它在大型数据集下有着比其他模型更快的收敛速度,即在大量样本数量和特征数量的情况下。
简而言之,根据下面的规则可以选择一个相对合适的求解器:
场景 | 求解器 |
---|---|
比较小的数据集 或 使用了L1惩罚项 | "liblinear" |
大型数据集 或 多项式损失 | "lbfgs", "sag" 或 "newton-cg" |
非常大型的数据集 | "sag" |
对于大型数据集,你或许会考虑使用带有“log”损失的SGDClassifier
。
示例
与liblinear的不同
在参数 fit_intercept=False,在拟合** coef_ 或被预测的数据全为零的情况下,使用 solver=liblinear 的 LogisticRegression
与直接使用外置的 liblinear 库的 LinearSVC 的预测分数可能会有一些不一样。这是因为对于 decision_function 为零的样本而言,LogisticRegression
与 LinearSVC 都是预测其负类,而 liblinear 却预测其正类。不过要注意的是,fit_intercept=False** 与 decision_function 为零的大量样本的情况下,其很容易出现过拟合现象。所以建议你设置fit_intercept=True 并增加 intercept_scaling的值。
注释:在稀疏Logistic回归下的特征选择
带有L1惩罚项的Logistic回归会产生稀疏模型,因此也能用来执行特征选择,在L1-based feature selection有其细节说明。
LogisticRegressionCV
实现了内置交叉验证去寻找C的最优值的Logistic回归。“newton-cg”, “sag” 和 “lbfgs” 被发现在热启动下,对高维复杂数据有着很快的执行速度。对于多元分类,如果** multi_class **被设置为 ** ovr ,那么则会为每一类寻找C的最优值。如果 multi_class **被设置为 ** multinomial **,则会通过使交叉熵损失最小化来获得C的最优值。
引用
- Christopher M. Bishop: Pattern Recognition and Machine Learning, Chapter 4.3.4
- Mark Schmidt, Nicolas Le Roux, and Francis Bach: Minimizing Finite Sums with the Stochastic Average Gradient.
1.1.12 随机梯度下降 - SGD#
随机梯度下降是一种简单但非常有效的拟合线性模型的方法,尤其是在样本的数量(特征的数量)非常大的情况下。其** partial_fit 方法允许使用 only/out-of-core 学习。
SGDClassifier
和 SGDRegressor
类提供了在使用不同的(凸)损失函数与不同的惩罚项(例如 loss="log")的情况下去拟合分类与回归的线性模型。 SGDClassifier
拟合出一个Logistic回归模型,而当 loss="hinge" **,它则可以拟合线性支持向量机(SVM)。
引用
1.1.14. Passive Aggressive 算法#
Passive Aggressive 算法是大规模学习算法中的算法族。它们类似于感知器,因此它们不需要学习速率。但不同于感知器,它们包含一个正则化参数** C 。
对于分类问题, 能够使用设置为 loss='hinge' **(PA-I) 或 ** loss='squared_hinge' 的PassiveAggressiveClassifier
。对于回归则可以使用设置为 loss='epsilon_insensitive' **(PA-I) 或 ** loss='squared_epsilon_insensitive' **(PA-II)。
引用
- “在线 Passive-Aggressive 算法” K. Crammer, O. Dekel, J. Keshat, S. Shalev-Shwartz, Y. Singer - JMLR 7 (2006)
1.1.15. 稳健回归:异常值和建模误差#
稳健回归能够在有损坏的数据下拟合出一个回归模型:异常值或模型中的误差。
受损的y
1.1.15.1. 不同的场景和有用的概念##
在处理由异常值损坏的数据时有几点我们需要注意:
- 误差值在 X 还是 y ?
误差值在y | 误差值在X |
---|---|
误差值在y | 误差值在X |
- 异常值的比值与误差的幅度
小误差 | 大误差 |
---|---|
小误差 | 大误差 |
稳健拟合的一个重要概念是抛锚点(breakdown point):即模型会为了拟合外部的少量数据,而开始丢失内部的数据。
要时刻注意这一点,稳健回归在拟合高维度的数据(大量的 n_feature)中的设置是很难的。所以在这种设置下稳健模型可能不会进行工作。
权衡:哪种估量器?
Scikit-learn提供了三种稳健回归估量器:RANSAC, Theil Sen 与 HuberRegressor
- 除非样本的数据量非常大,否则一般情况下 HuberRegressor 会比 RANSAC 与 Theil Sen 要快得多,即 ** 样本数量 >> 特征数量**。这是因为 RANSAC 和 Theil Sen 是拟合数据集中的子集。
- RANSAC 比 Theil Sen 要快,且会随着样本的数量增加而表现的更好。
- RANSAC 在处理大量于 y 里的异常值(同时这也是异常值最普遍出现的形式)表现良好。
-
Theil Sen 能够比较好的应对于 X 里存在中等数量异常值的情况。但是这一特性会在高维中失效。
也就是说,如果不知道要用那种估量器时,用 RANSAC 就对了。
1.1.15.2. RANSAC: 随机抽样一致##
RANSAC(随机抽样一致)从完整数据中的随机子集来拟合模型。
RANSAC是一个非确定性算法他只会在一定概率下产生合理的结果,这概率取决于迭代的次数(可以通过** max_trals **参数设置)。其典型的应用场景是用来解决线性与非线性回归问题,并且它也在摄影测量计算机视觉领域中非常流行。
这个算法会把完整的输入拆分成一个集合集,同时这也会使得在每个集合中多多少少受到噪音与异常值的影响。例如。由错误测量引起的噪音或由无效的假设所收集的数据。最终产生的模型也是根据集合来决定。
RANSAC回归
1.1.15.2.1. 算法的细节###
该算法在每次迭代中都会执行以下步骤:
- 从原始数据中选出** min_samples 个随机样本并且检查数据集是否有效( is_data_valid **)。
- 根据随机出来的子集进行拟合。(base_estimator.fit),并且对估量出的模型进行判断其是否有效(is_model_valid)。
- 通过计算估量模型的残差(base_estimator.predict(X) - y)将所有数据进行分类(内点与离群点)。数据的残差比** residual_threshold **要小的就作为内点。
- 如果内点样本已达到最大值,就保存拟合后的模型为合适模型。以防止当前估计出的模型拥有相同数量的内点。不过如果模型的分数更高也会被认为是更好的模型。
这些步骤的最大执行次数(max_trials)或直到满足特殊停止条件之一(详见** stop_n_inliers ** 和 ** stop_score**)后停止。最后会使用先前所有估计出的合适模型来验证所有内点样本来决定最合适的模型。
** is_data_valid ** 和 ** is_model_valid 函数允许用来识别和拒绝随机子样本的退化组合。如果估计出的模型不再需要鉴定退化样本,那么就应该在拟合模型之前调用is_data_valid**,使的模型能够获得一个更好的计算性能。
示例
引用
- https://en.wikipedia.org/wiki/RANSAC
- “Random Sample Consensus: A Paradigm for Model Fitting with Applications to Image Analysis and Automated Cartography” Martin A. Fischler and Robert C. Bolles - SRI International (1981)
- “Performance Evaluation of RANSAC Family” Sunglok Choi, Taemin Kim and Wonpil Yu - BMVC (2009)
1.1.15.3. Theil-Sen估量器:普通中值估量器##
TheilSenRegressor 估量器使用了多维数据中的中值概括。因此对于有多变量异常值时仍旧是稳健的。但无论如何都要注意的是,估量器的鲁棒性会随着问题的维度的增加而快速减少。所以在高维度的情况其在失去鲁棒性的情况,并且效率可能还不如OLS高。
示例
引用
1.1.15.3.1. 理论限制###
TheilSenRegressor
作为一个无偏差值的估计器而言,在拟合效率上与OLS相似。与OLS相反,Theil-Sen是一个非参数方法,这意味着它不会对地底层分布的数据作任何假设。因为** Theil-Sen **是一种基于中值的估量器,所以它对于损坏的数据更具鲁棒。在单变量设置里,在简单线性回归的情况下Theil-Sen的击破点率为29.3%,这意味着它可以容忍高达29.3%的任意损坏的数据。
在scikit-learn中,TheilSenRegressor
的实现是根据多元线性回归的空间中值这一多维中值的概念[7][8]。
在时间和空间复杂度方面,Theil-Sen的尺度根据
Tenil-Sen的尺度
使得在大量数据与特征的情况下,不可能将所有的子集样本应用到该问题中。因此子集的量级可从考虑所有的随机子集的集合来限制时间和空间复杂度。
示例
引用
- Xin Dang, Hanxiang Peng, Xueqin Wang and Heping Zhang: Theil-Sen Estimators in a Multiple Linear Regression Model.
- T. Kärkkäinen and S. Äyrämö: On Computation of Spatial Median for Robust Data Mining.
1.1.15.4. Huber回归##
HuberRegressor
与 Ridge
的不同在于前者应用线性损失到样本时,是将其归类为异常值。样本的分类为内点是根据其的绝对错误是否低于一个确定的阈值。其跟 TheilSenRegressor
的 RANSACRegressor
不同之处在于它并不会忽略异常值,相反而是给予他们一个很小的权重值。
HuberRegressor
的最小化损失函数的公式为:
其中:
Huber的最小化损失公式中的H
建议设置参数** epsilon **的值为1.35以获得95%统计效率。
1.1.15.5. 注意事项##
在损失设置上, HuberRegressor
与 SGDRegressor
的不同之处在于:
-
HuberRegressor
是缩放不变的。当** epsilon 被设置了后,通过任意值缩放 X 与 y 都不会改成其异常值的鲁棒性。而 SGDRegressor
在缩放 X 与 y 后仍需要重新设置 epsilon **的值。 -
HuberRegressor
能够充分使用少量样本的数据,而 SGDRegressor
为了产生一致的鲁棒性则需要多次传递数据。
示例
引用
- Peter J. Huber, Elvezio M. Ronchetti: Robust Statistics, Concomitant scale estimates, pg 172
同样的,该估计器与R语言实现的稳健回归(http://www.ats.ucla.edu/stat/r/dae/rreg.htm)也是有不同的地方。因为R语言的实现是基于加权最小二乘,根据残差大于特定阈值多少来给予每个样本的权重。
1.1.16 多项式回归:扩展具有基函数的线性模型#
一种常见的机器学习模式是使用数据的非线性函数的值(即不使用a,而是使用func(a)来代替a)去训练线性模型。这种方式能够保持线性方法的运行性能,也因此使其有能力去拟合更广泛的数据。
举个例子,一个简单的线性回归能够通过在系数上构造多项式特征来进行扩展。在标准的线性回归案例,你可能会有一个像下面这样的公式去拟合二维数据。
拟合二维数据的模型
如果我们想要拟合抛物面到数据而不是一个平面,我们可以结合一个二次多项式特征,所以现在我们的模型看起来是这样子的:
虽然对这个模型进行过处理,但是这个模型(可能会有点让人惊讶)仍旧是一个线性模型:为了了解这一点,想象一下创建一个新的变量向量
新变量Z
在数据进行重标签后,我们的模型看起来是这样的:
对数据重标签后的模型
我们可以知道这个多项式回归与我们先前的设想一样,跟线性模型是同一类的(即模式对** ω **是线性的),并且也可以通过相同(处理线性回归)的技术去处理他。通过考虑在用这些基函数构建的更高维空间内的线性拟合,这个模型对拟合更广泛的数据有具灵活。
这里是一个对单位数据上使用不同程度的多项式特征的例子:
这个图表是通过使用 PolynomialFeatures
预处理器生成的。这个预处理器转换输入的数据矩阵成为一个给定维度的新数据矩阵。使用方式如下:
>>> from sklearn.preprocessing import PolynomialFeatures
>>> import numpy as np
>>> X = np.arange(6).reshape(3, 2)
>>> X
array([[0, 1],
[2, 3],
[4, 5]])
>>> poly = PolynomialFeatures(degree=2)
>>> poly.fit_transform(X)
array([[ 1., 0., 1., 0., 0., 1.],
[ 1., 2., 3., 4., 6., 9.],
[ 1., 4., 5., 16., 20., 25.]])
**X 的特征已经从 [x1, x2] 转换成 [1, x1, x2, x1^2, x1x2, x2^2] **,并且能够在任意的线性模型中使用它了。
这种预处理能够在 Pipeline 工具下进行流化。一个代表简单多项式回归的对象能够以下面这种方式创建并使用:
>>> from sklearn.preprocessing import PolynomialFeatures
>>> from sklearn.linear_model import LinearRegression
>>> from sklearn.pipeline import Pipeline
>>> import numpy as np
>>> model = Pipeline([('poly', PolynomialFeatures(degree=3)),
... ('linear', LinearRegression(fit_intercept=False))])
>>> # fit to an order-3 polynomial data
>>> x = np.arange(5)
>>> y = 3 - 2 * x + x ** 2 - x ** 3
>>> model = model.fit(x[:, np.newaxis], y)
>>> model.named_steps['linear'].coef_
array([ 3., -2., 1., -1.])
这个模型由多项式特征上训练而成,使得其能够精确地恢复输入的多项式系数。
在某些情况下是没有必要去包含太重要的内容在一个特征里,除了所谓在不同的特征(d)上互相关联的交互特征。这些特征可以通过设置** interaction_only=True **的PolynomialFeatures
上获得。
例如当处理布尔特征时,对于所有的n而言,** xi^n = xi 是毫无作用的(因为等于本身而且是布尔量)。但是 xixj 却代表了两个布尔量之间的链接关系。根据这种关系,我们可以通过线性分类来解决异或问题**:
>>> from sklearn.linear_model import Perceptron
>>> from sklearn.preprocessing import PolynomialFeatures
>>> import numpy as np
>>> X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
>>> y = X[:, 0] ^ X[:, 1]
>>> y
array([0, 1, 1, 0])
>>> X = PolynomialFeatures(interaction_only=True).fit_transform(X).astype(int)
>>> X
array([[1, 0, 0, 0],
[1, 0, 1, 0],
[1, 1, 0, 0],
[1, 1, 1, 1]])
>>> clf = Perceptron(fit_intercept=False, n_iter=10, shuffle=False).fit(X, y)
并且这个分类器的“预测”是完全正确的:
>>> clf.predict(X)
array([0, 1, 1, 0])
>>> clf.score(X, y)
1.0
(在尝试翻译这篇文档的时候难免会因为各种问题而出现错翻,如果发现的话,烦请指出,谢谢> <)