不贴图都没人看系列。。。。

线性回归推导:

上图求导部分有误,少些一个转置符号,更正为:

逻辑回归推导:

公式中“ln”和“log”表示一个意思,都是以“e”为低的自然对数):

公式中:X是m*n矩阵,m个样本,n维特征。

1、内容简介:

本章我们将从最简单的模型之一——线性回归模型,开始介绍两种非常不同的训练模型的方法:

  1. ·通过“闭式”方程——直接计算出最适合训练集的模型参数(也就是使训练集上的成本函数最小化的模型参数)。
  2. ·使用迭代优化的方法,即梯度下降(GD),逐渐调整模型参数直至训练集上的成本函数调至最低,最终趋同于第一种方法计算出来的模型参数。我们还会研究几个梯度下降的变体,包括批量梯度下降、小批量梯度下降以及随机梯度下降。等我们进入到第二部分神经网络的学习时,会频繁地使用这几个变体。

接着我们将会进入多项式回归的讨论,更适合非线性数据集。由于该模型的参数比线性模型更多,因此更容易造成对训练数据过度拟合,我们将使用学习曲线来分辨这种情况是否发生。然后,再介绍几种正则化技巧,降低过度拟合训练数据的风险。最后,我们将学习两种经常用于分类任务的模型:Logistic回归和Softmax回归。

2、线性回归

线性模型就是对输入特征加权求和,再加上一个我们称为偏置项(也称为截距项)的常数,以此进行预测

其中: y是预测值;n是特征数量;是第i个特征值;是第j个模型参数(包括偏置项以及特征权重θ1,…,θn)用向量化形式表达:

·θ是模型的参数向量,列向量,包括偏置项θ0 以及特征权重θ1 到θn;
·X是实例的特征向量,是m*n的矩阵,表示m个样本,每个样本由n个特征表示。

2.1、怎样训练线性回归模型?

训练模型就是设置模型参数直到模型最适应训练集的过程。要达到这个目的,我们首先需要知道怎么衡量模型对训练数据的拟合程度是好还是差。回归模型最常见的性能指标是均方根误差(RMSE)。因此,在训练线性回归模型时,你需要找到最小化
RMSE的θ值。在实践中,将均方误差(MSE)最小化比最小化RMSE更为简单,二者效果相同。在训练集X上,使用下列公式计算线性回归的MSE。

为了得到使成本函数最小的θ值,有一个闭式解方法——也就是一个直接得出结果的数学方程,即标准方程:

其中 θ-hat 是使成本函数最小的θ值; y是包含 的目标值向量

公式推导请参见:https://blog.csdn.net/qq_30815237/article/details/86549010

我们生成一些线性数据来测试这个公式,使用标准方程来计算θ 。使用inv()函数来对矩阵求逆,并用dot方法计算矩阵的内积

import numpy as np
#rand均匀分布,randn正态分布,创造100*1的列向量
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)
plt.plot(X,y,"b.")
plt.xlabel("$x_1$", fontsize=18)#          "_1"表示下标
plt.ylabel("$y$", rotation=0, fontsize=18) #rotation控制旋转方位
plt.axis([0, 2, 0, 15])                   #坐标轴范围
save_fig("generated_data_plot")
#用标准方程求系数
theta_best = np.linalg.inv(X_b.T.dot(X_b)).dot(X_b.T).dot(y)  #linalg是线性代数模块
theta_best                #实际值是4,3.由于存在噪声,这个结果非常接近#随机构造两个点,测试求得的系数的测量误差
X_new = np.array([[0], [2]])
X_new_b = np.c_[np.ones((2, 1)), X_new]  # add x0 = 1 to each instance
#两种形式
y_predict = X_new_b.dot(theta_best)
#y_predict = np.dot(X_new_b,theta_best)
y_predict
输出:array([[  3.76800535],[ 10.23321346]])

绘制图像:

plt.plot(X_new, y_predict, "r-",linewidth=2, label="Predictions")#   "-"表示画一条线
plt.legend(loc="upper left", fontsize=14)
plt.plot(X, y, "b.")            #   "."表示画一点
plt.axis([0, 2, 0, 15])
plt.show()

Scikit-Learn的等效代码如下所示:

#scikit-learn LinearModel predict
from sklearn.linear_model import LinearRegression
lin_reg=LinearRegression()
lin_reg.fit(X,y)
lin_reg.predict(X_new)

2.2、小结:

特征数量比较大(例如100000)时,标准方程的计算将极其缓慢。好的一面是,相对于训练集中的实例数量m来说,方程是线性的,所以能够有效地处理大量的训练集,只要内存足够。同样,线性回归模型一经训练,预测就非常快速:因为计算复杂度相对于想要预测的实例数量和特征数量来说,都是线性的。换句话说,对两倍的实例(或者是两倍的特征数)进行预测,大概需要两倍的时间。

3、梯度下降

梯度下降是一种非常通用的优化算法,能够为大范围的问题找到最优解。梯度下降的中心思想就是迭代地调整参数从而使成本函数最小化。假设你迷失在山上的浓雾之中,你能感觉到的只有你脚下路面的坡度。快速到达山脚的一个策略就是沿着最陡的方向下坡。这就是梯度下降的做法:通过测量参数向量θ相关的误差函数的局部梯度,并不断沿着降低梯度的方向调整,直到梯度降为0,到达最小值!

梯度下降中一个重要参数是每一步的步长,这取决于超参数学习率。如果学习率太低,算法需要经过大量迭代才能收敛,这将耗费很长时间,如果学习率太高,那你可能会越过山谷直接到达山的另一边,甚至有可能比之前的起点还要高。这会导致算法发散,值越来越大,最后无法找到好的解决方案。

最后,并不是所有的成本函数看起来都像一个漂亮的碗。下图显示了梯度下降的两个主要挑战:如果随机初始化,算法从左侧起步,那么会收敛到一个局部最小值,而不是全局最小值。如果算法从右侧起步,那么需要经过很长时间才能越过整片高原,如果你停下得太早,将永远达不到全局最小值。幸好,线性回归模型的MSE成本函数恰好是个凸函数

但如果不同特征的尺寸差别巨大,那它可能是一个非常细长的碗。如图4-7所示的梯度下降,左边的训练集上特征1和特征2具有相同的数值规模,而右边的训练集上,特征1的值则比特征2要小得多。(注:因为特征1的值较小,所以θ1 需要更大的变化来影响成本函数,这就是为什么碗形会沿着θ1 轴拉长。)

3.1、批量梯度下降

要实现梯度下降,你需要计算每个模型关于参数θ的成本函数的梯度。换言之,你需要计算的是如果改变θ,成本函数会改变多少。这被称为偏导数。

成本函数的偏导数:

成本函数的梯度向量:

在计算梯度下降的每一步时,都是基于完整的训练集X的。这就是为什么该算法会被称为批量梯度下降:每一步都使用整批训练数据。因此,面对非常庞大的训练集时,算法会变得极慢。但是,梯度下降算法随特征数量扩展的表现比较好:如果要训练的线性模型拥有几十万个特征,使用梯度下降比标准方程要快得多。

批量学习的效果:

#不同的学习率带来不同的结果
theta_path_bgd = []def plot_gradient_descent(theta, eta, theta_path=None):m = len(X_b)plt.plot(X, y, "b.")n_iterations = 1000for iteration in range(n_iterations):if iteration < 10:y_predict = X_new_b.dot(theta)style = "b-" if iteration > 0 else "r--"plt.plot(X_new, y_predict, style)gradients = 2/m * X_b.T.dot(X_b.dot(theta) - y)theta = theta - eta * gradientsif theta_path is not None:theta_path.append(theta)plt.xlabel("$x_1$", fontsize=18)plt.axis([0, 2, 0, 15])plt.title(r"$\eta = {}$".format(eta), fontsize=16)np.random.seed(42)
theta = np.random.randn(2,1)  # random initializationplt.figure(figsize=(10,4))
plt.subplot(131); plot_gradient_descent(theta, eta=0.02)
plt.ylabel("$y$", rotation=0, fontsize=18)
plt.subplot(132); plot_gradient_descent(theta, eta=0.1, theta_path=theta_path_bgd)
plt.subplot(133); plot_gradient_descent(theta, eta=0.5)save_fig("gradient_descent_plot")
plt.show()

左图的学习率太低:算法最终能找到解决方法,但需要太长时间。中间的学习率看起来非常棒:几次迭代就收敛出了最终解。右边的学习率太高:算法发散,直接跳过了数据区域。
     要找到合适的学习率,可以使用网格搜索。但是你需要限制迭代次数,这样网格搜索可以淘汰掉那些收敛耗时太长的模型。你可能会问,要怎么限制迭代次数呢?如果设置太低,算法可能在离最优解还很远时就停了;但是如果设置得太高,模型达到最优解后,继续迭代参数不再变化,又会浪费时间。

3.2、随机梯度下降

批量梯度下降的主要问题是它要用整个训练集来计算每一步的梯度,所以训练集很大时,算法会特别慢。与之相反的极端是随机梯度下降,每一步在训练集中随机选择一个实例,并且仅基于该单个实例来计算梯度。它也可以被用来训练海量的数据集,因为每次迭代只需要在内存中运行一个实例即可。

由于算法的随机性质,它比批量梯度下降要不规则得多。成本函数将不再是缓缓降低直到抵达最小值,而是不断上上下下,但是从整体还是慢慢下降。最终会非常接近最小值,但是即使它到达了最小值,依旧还会持续反弹,永远不会停止。所以算法停下来的参数值肯定是足够好的,但不是最优的。

当成本函数非常不规则时,随机梯度下降帮助算法跳出局部最小值,所以相比批量梯度下降,它对找到全局最小值更有优势。
因此,随机性的好处在于可以逃离局部最优,但缺点是永远定位不出最小值。要解决这个困境,有一个办法是逐步降低学习率。开始的步长比较大(这有助于快速进展和逃离局部最小值),然后越来越小,让算法尽量靠近全局最小值。这个过程叫作模拟退火确定每个迭代学习率的函数叫作学习计划。如果学习率降得太快,可能会陷入局部最小值,甚至是停留在走向最小值的半途中。如果学习率降得太慢,你需要太长时间才能跳到差不多最小值附近,如果提早结束训练,可能只得到一个次优的解决方案。


模拟退火(Simulate Anneal)

想象一下如果我们现在有下面这样一个函数,现在想求函数的(全局)最优解,那么从A点开始试探,如果函数值继续减少,那么试探过程就会继续。而当到达点B时,显然我们的探求过程就结束了(因为无论朝哪个方向努力,结果只会越来越大)。最终我们只能找打一个局部最后解B。

模拟退火在它的搜索过程引入了随机因素。模拟退火算法以一定的概率来接受一个比当前解要差的解,因此有可能会跳出这个局部的最优解,达到全局的最优解。以上图为例,模拟退火算法在搜索到局部最优解B后,会以一定的概率接受向右继续移动。也许经过几次这样的不是局部最优的移动后会到达B 和C之间的峰点,于是就跳出了局部最小值B。

根据Metropolis准则,粒子在温度T时趋于平衡的概率为exp(-ΔE/(kT)),其中E为温度T时的内能(成本函数),ΔE为其改变量,k为Boltzmann常数。Metropolis准则常表示为:


        Metropolis准则表明,在温度为T时,出现能量差为ΔE的降温的概率为P(ΔE),表示为:P(ΔE) = exp(-ΔE/(kT) )。其中k是一个常数,且ΔE<0。所以P和T正相关。这条公式就表示:温度越高,出现一次能量差为ΔE的降温的概率就越大;温度越低,则出现降温的概率就越小。又由于ΔE总是小于0(因为退火的过程是温度逐渐下降的过程),因此ΔE/kT < 0 ,所以P(ΔE)的函数取值范围是(0,1) 。随着温度T的降低,P(ΔE)会逐渐降低。

我们将一次向较差解的移动看做一次温度跳变过程,我们以概率P(ΔE)来接受这样的移动。也就是说,在用固体退火模拟组合优化问题,将内能E模拟为目标函数值 f,温度T演化成控制参数 t,即得到解组合优化问题的模拟退火演算法:由初始解 i 和控制参数初值 t 开始,对当前解重复“产生新解→计算目标函数差→接受或丢弃”的迭代,并逐步衰减 t 值,算法终止时的当前解即为所得近似最优解,这是基于蒙特卡罗迭代求解法的一种启发式随机搜索过程。退火过程由冷却进度表(Cooling Schedule)控制,包括控制参数的初值 t 及其衰减因子Δt 、每个 t 值时的迭代次数L和停止条件S。

总结起来就是:

  • 若f( Y(i+1) ) <= f( Y(i) )  (即移动后得到更优解),则总是接受该移动;
  • 若f( Y(i+1) ) > f( Y(i) )  (即移动后的解比当前解要差),则以一定的概率接受移动,而且这个概率随着时间推移逐渐降低(逐渐降低才能趋向稳定)相当于上图中,从B移向BC之间的小波峰时,每次右移(即接受一个更糟糕值)的概率在逐渐降低。如果这个坡特别长,那么很有可能最终我们并不会翻过这个坡。如果它不太长,这很有可能会翻过它,这取决于衰减 t 值的设定。

from:https://blog.csdn.net/weixin_40562999/article/details/80853354


实例:

#使用SGDRegressor实现SGD线性回归
from sklearn.linear_model import SGDRegressor
sgd_reg = SGDRegressor(n_iter=50, penalty=None, eta0=0.1, random_state=42)
#y.ravel()是将 列向量y 变成行向量y
sgd_reg.fit(X, y.ravel())sgd_reg.intercept_, sgd_reg.coef_

SGDRegressor参数说明:

SGDRegressor(loss=’squared_loss’, penalty=’l2’, alpha=0.0001, l1_ratio=0.15,fit_intercept=True, max_iter=None, tol=None, shuffle=True, verbose=0, epsilon=0.1,random_state=None, learning_rate=’invscaling’, eta0=0.01, power_t=0.25, early_stopping=False, validation_fraction=0.1, n_iter_no_change=5, warm_start=False, average=False, n_iter=None)

通过最小化SGD的正则化损失来拟合线性模型,SGD一次估计每个样本的损失梯度,并且模型随着强度递减计划(即学习率)一路更新。正则化器是对损失函数添加的惩罚,其使用平方欧几里德范数L2或绝对范数L1或两者的组合(弹性网络)将模型参数缩减到零向量。

损失函数可取: ‘squared_loss’, ‘huber’ ‘epsilon_insensitive’‘squared_epsilon_insensitive’

'squared_loss':普通的最小二乘拟合(线性回归,为默认值,此时添加正则项,就会变为岭回归,Losso回归,参见第5节)
'huber'更少关注异常值。 (soft-margin)线性SVM
'epsilon_insensitive'忽略的错误少于epsilon, 这是SVR中使用的损失函数。 'squared_epsilon_insensitive'是相同的,但是变为平方损失超过epsilon的容差。其实当损失函数取不同的方程式,SGD也就转换成了不同的模型。例如如果是Square loss,那就是最小二乘了;如果是Hinge Loss,那就是著名的SVM了。

原文:The ‘squared_loss’ refers to the ordinary least squares fit. ‘huber’ modifies ‘squared_loss’ to focus less on getting outliers correct by switching from squared to linear loss past a distance of epsilon. ‘epsilon_insensitive’ ignores errors less than epsilon and is linear past that; this is the loss function used in SVR. ‘squared_epsilon_insensitive’ is the same but becomes squared loss past a tolerance of epsilon.

官方文档:https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.SGDRegressor.html

3.3、小批量梯度下降

小批量梯度下降:每一步的梯度计算,既不是基于整个训练集(批量梯度下降)也不是基于单个实例(随机梯度下降),而是基于一小部分随机的实例集也就是小批量。这个算法在参数空间层面的前进过程也不像SGD那样不稳定,特别是批量较大时。所以小批量梯度下降最终会比SGD更接近最小值一些。下图显示了三种梯度下降算法在训练过程中参数空间里的行进路线。它们最终都汇聚在最小值附近,批量梯度下降最终停在了最小值上,而随机梯度下降和小批量梯度下降还在继续游走。但是,别忘了批量梯度可是花费了大量时间来计算每一步的,如果用好了学习计划,随机梯度下降和小批量梯度下降也同样能到达最小值。

这四种方法训练后的模型几乎无差别:所有这些算法最后出来的模型都非常相似,并且以完全相同的方式做出预测。

4、多项式回归

如果数据比简单的直线更为复杂,该怎么办?令人意想不到的是,其实你也可以用线性模型来拟合非线性数据。一个简单的方法就是将每个特征的幂次方添加为一个新特征,然后在这个拓展过的特征集上训练线性模型。这种方法被称为多项式回归。

基于简单的二次方程 生成一些非线性数据,直线永远不可能拟合这个数据。所以我们使用Scikit-Learn
的PolynomialFeatures类来对训练数据进行转换(只有一个特征:x),将每个特征的平方(二次多项式)作为新特征加入训练集,在新的数据集上进行线性拟合:

import numpy as np
import numpy.random as rndnp.random.seed(42)
m = 100
X = 6 * np.random.rand(m, 1) - 3
y = 0.5 * X**2 + X + 2 + np.random.randn(m, 1)
#将每个特征的平方作为新特征,
from sklearn.preprocessing import PolynomialFeatures
poly_features = PolynomialFeatures(degree=2, include_bias=False)
X_poly = poly_features.fit_transform(X)
#对扩展特征后的数据进行线性拟合
lin_reg = LinearRegression()
lin_reg.fit(X_poly, y)

PolynomialFeatures会在给定的多项式阶数下,添加所有特征组合。例如,有两个特征a和b,阶数degree=3,不只会添加特征a^2 、a^3 、b^2 和b^3 ,还会添加组合ab、以及。要小心特征组合的数量爆炸!

4.1、确定模型的复杂程度?判断模型是过拟合还是拟合不足?

1、使用了交叉验证来评估模型的泛化性能。如果模型在训练集上表现良好,但是交叉验证的泛化表现非常糟糕,那么模型就是过度拟合。如果在二者上的表现都不佳,那就是拟合不足。

2、观察学习曲线:这个曲线绘制的是模型在训练集和验证集上,关于“训练集大小”的性能函数。要生成这个曲线,只需要在不同大小的训练子集上多次训练模型即可。

左图采用线性拟合,这条学习曲线是典型的模型拟合不足。两条曲线均到达高地,非常接近,而且相当高。如果你的模型对训练数据拟合不足,添加更多训练示例也于事无补。你需要使用更复杂的模型或者找到更好的特征。

右图用10阶多项式拟合,两条曲线之间有一定差距。这意味着该模型在训练数据上的表现比验证集上要好很多,这正是过度拟合的标志。改进模型过度拟合的方法之一是提供更多的训练数据,直到验证误差接近训练误差。


偏差/方差权衡

偏差:这部分泛化误差的原因在于错误的假设,比如假设数据是线性的,而实际上是二次的。高偏差模型最有可能对训练数据拟合不足。

方差:这部分误差是由于模型对训练数据的微小变化过度敏感导致的。具有高自由度的模型(例如高阶多项式模型)很可能也有高方差,所以很容易对训练数据过度拟合。

增加模型的复杂度通常会显著提升模型的方差,减少偏差。反过来,降低模型的复杂度则会提升模型的偏差,降低方差。


5、正则线性模型

减少过度拟合的一个好办法就是对模型正则化(即约束它):它拥有的自由度越低,就越不容易过度拟合数据。比如,将多项式模型正则化的简单方法就是降低多项式的阶数。对线性模型来说,正则化通常通过约束模型的权重来实现。接下来我们将会使用岭回归(Ridge  Regression)、套索回归(Lasso Regression)及弹性网络(Elastic Net)这三种不同的实现方法对权重进行约束。

5.1、岭回归Ridge Regression

岭回归是线性回归的正则化版,在线性回归的成本函数中添加一个正则项,即为岭回归。

岭回归的成本函数:

超参数α控制的是对模型进行正则化的程度。如果α=0,则岭回归就是线性模型。如果α非常大,那么所有的权重都将非常接近于零,结果是一条穿过数据平均值的水平线。在执行岭回归之前,必须对数据进行缩放(例如使用StandardScaler),因为它对输入特征的大小非常敏感。大多数正则化模型都是如此。

与线性回归一样,我们也可以在计算闭式方程或者执行梯度下降时,执行岭回归。

对于闭式解:

对于梯度下降,只需要在MSE梯度向量上添加αw即可。

#执行闭式解的岭回归
from sklearn.linear_model import Ridge
ridge_reg = Ridge(alpha=1, solver="cholesky", random_state=42)
ridge_reg.fit(X, y)
ridge_reg.predict([[1.5]])##执行SGD的岭回归
sgd_reg=SGDRegressor(penalty="l2")
#sgd_reg.fit(X,y#这样也行,但有警告‘y = column_or_1d(y, warn=True
sgd_reg.fit(X,y.ravel())
sgd_reg.predict([[1.5]])

超参数penalty设置的是使用正则项的类型。设为"l2"表示希望SGD在成本函数中添加一个正则项,等于权重向量的l2范数的平方的一半,即岭回归。

使用不同α值对某个线性数据进行训练的几种岭回归模型。左边直接使用岭回归,导致预测是线性的。而右边,首先使
用PolynomialFeatures(degree=10)对数据进行扩展,然后用StandardScaler进行缩放,最后再将岭回归模型用于结果特征,这就是岭正则化后的多项式回归。

岭回归的完整参数表示:

Ridge(alpha=1, copy_X=True, fit_intercept=True, max_iter=None,normalize=False, random_state=42, solver='cholesky', tol=0.001)

sklearn.linear_model.ridge模块中的函数,是Ridge类,线性最小二乘L2正则化。该模型求解了线性最小二乘函数和L2正则化的回归模型。

  1. alpha:正则化强度。 较大的值指定较强的正则化。 Alpha对应于其他线性模型(如Logistic回归或LinearSVC)中的
  2. fit_intercept:是否计算该模型的截距。如果设置为False,将不会在计算中使用截距(比如,预处理数据已经中心化)
  3. normalize:当fit_intercept设置为False时,该参数将会被忽略。如果为True,则回归前,回归变量X将会进行归一化,减去均值,然后除以L2范数。如果想要标准化,请在评估器(normalize参数为False)调用fit方法前调用StandardScaler,
  4. copy_X:如果是True,x将被复制,否则,有可能被覆盖。
  5. max_iter:共轭梯度求解器的最大迭代次数。对于‘sparse_cg’ 和 ‘lsqr’ 求解器,默认值由 scipy.sparse.linalg确定。对于‘sag’求解器,默认值是1000。
  6. tol:求解方法精度
  7. solver:类型: {‘auto’, ‘svd’, ‘cholesky’, ‘lsqr’, ‘sparse_cg’, ‘sag’, ‘saga’},计算例程中使用的求解程序。

返回值

  1. coef_:权重向量
  2. intercept_:决策函数中的独立项,即截距,如果fit_intercept=False,则设置为0
  3. n_iter_:每个目标的实际迭代次数。只能用于sag和lsqr求解器。其他求解器将返回None。

5.2、套索回归 Lasso Regression

线性回归的另一种正则化,叫作最小绝对收缩和选择算子回归(Lasso回归)。与岭回归一样,它也是向成本函数增加一个正则项,但是它增加的是权重向量的L1范数

成本函数:

当时=0(i=1,2,…,n),Lasso成本函数是不可微的,但是,当任意=0时,如果使用次梯度向量g作为替代,依旧可以让梯度下降正常运转。

Lasso回归次梯度向量:

Lasso回归的一个重要特点是它倾向于完全消除掉最不重要特征的权重(也就是将它们设置为零)。例如所有高阶多项式的特征权重都等于零。换句话说,Lasso回归会自动执行特征选择并输出一个稀疏模型(即只有很少的特征有非零权重)

两种方法实现Lasso回归:

#套索回归
from sklearn.linear_model import Lasso
lasso_reg=Lasso(alpha=0.1)
lasso_reg.fit(X,y)
lasso_reg.predict([[1.5]])#也可以使用SGDRegressor实现套索回归
sgd_reg=SGDRegressor(alpha=0.1,penalty="l1")
#sgd_reg.fit(X,y#这样也行,但有警告‘y = column_or_1d(y, warn=True
sgd_reg.fit(X,y.ravel())
sgd_reg.predict([[1.5]])

5.3、弹性网络Elastic Net

弹性网络是岭回归与Lasso回归之间的中间地带。其正则项就是岭回归和Lasso回归的正则项的混合,混合比例通过r来控制。当r=0时,弹性网络即等同于岭回归,而当r=1时,即相当于Lasso回归

如何选用线性回归、岭回归、Lasso回归和弹性网络?

通常来说,有正则化——哪怕是很小,总是比没有更可取一些。所以大多数情况下,你应该避免使用纯线性回归。岭回归是个不错的默认选择,但是如果你觉得实际用到的特征只有少数几个,那就应该更倾向于Lasso回归或是弹性网络,因为它们会将无用特征的权重降为零。一般而言,弹性网络优于Lasso回归,因为当特征数量超过训练实例数量,又或者是几个特征强相关时,Lasso回归的表现可能非常不稳定。

岭回归、Lasso回归除了自身有调用的函数外,还可以通过SGDRegressor函数实现,只要将惩罚函数penalty设置成“l1”"l2"即可。

(线性回归,是求解算法;正则化是约束,它可以和任何求解算法结合;SGD是优化算法,它可以和任何求解算法结合,使求解更快;线性回归与正则化结合就产生了岭回归,套索回归,弹性网络;线性回归加岭回归加SGD产生SGDRegressor(此时成本函数是默认值的情况,因为不同的成本函数对应的并不是线性回归,可能是逻辑回归或SVM))

正则参数alpha的范围是0-1,越大,正则程度越高,斜率绝对值越小,要与后面参数C做区分!!!

from sklearn.linear_model import ElasticNet
elastic_net=ElasticNet(alpha=0.1,l1_ratio=0.5)
elastic_net.fit(X,y)
elastic_net.predict([[1.5]])
out:array([ 1.54333232])

5.4、早期停止法

对于梯度下降这一类迭代学习的算法,还有一个与众不同的正则化方法,就是在验证误差达到最小值时停止训练,该方法叫作早期停止法。一旦验证误差达到最小值就立刻停止训练。这是一个非常简单而有效的正则化技巧

对随机梯度下降和小批量梯度下降来说,曲线没有这么平滑,所以很难知道是否已经达到最小值。一种解决方法是等验证误差超过最小值一段时间之后再停止(这时你可以确信模型不会变得更好了),然后将模型参数回滚到验证误差最小时的位置。

6、逻辑回归Logistic Regression

一些回归算法也可用于分类。逻辑回归(Logistic回归)被广泛用于估算一个实例属于某个特定类别的概率。(比如,这封电子邮件属于垃圾邮件的概率是多少?)如果预估概率超过50%,则模型预测该实例属于该类别(称为正类,标记为“1”),反之,则预测不是(也就是负类,标记为“0”)。这样它就成了一个二元分类器。

跟线性回归模型一样,逻辑回归模型也是计算输入特征的加权和(加上偏置项),但是不同于线性回归模型直接输出结果,它输出的是结果的数理逻辑:

逻辑回归成本函数:

这个函数没有已知的闭式方程(不存在一个标准方程的等价方程)来计算出最小化成本函数的θ值。而这是个凸函数,所以通过梯度下降(或是其他任意优化算法,看到了吧:梯度下降只是一种优化计算方法)保证能够找出全局最小值:

Logistic成本函数的偏导数:

计算出每个实例的预测误差,并将其乘以第j个特征值,然后再对所有训练实例求平均值。一旦你有了包含所有偏导数的梯度向量就可以使用梯度下降算法了。

详细推导参见:https://blog.csdn.net/qq_30815237/article/details/86549010


6.1、鸢尾花数据iris介绍:

这里我们用鸢尾植物数据集来说明逻辑回归。这是一个非常著名的数据集,共有150朵鸢尾花,分别来自三个不同品种:Setosa鸢尾花、Versicolor鸢尾花和Virginica鸢尾花,数据里包含花的萼片以及花瓣的长度和宽度。鸢尾花识别是一个经典的机器学习分类问题,它的数据样本中包括了4个特征变量,1个类别变量,样本总数为150。

啊,好美。。。。

它的目标是根据花萼长度(sepal length)、花萼宽度(sepal width)、花瓣长度(petal length)、花瓣宽度(petal width)这四个特征来识别出鸢尾花属于山鸢尾(iris-setosa)、变色鸢尾(iris-versicolor)和维吉尼亚鸢尾(iris-virginica)中的哪一种。

from sklearn import datasets
iris = datasets.load_iris()
list(iris.keys())out:['filename', 'feature_names', 'target', 'DESCR', 'data', 'target_names']iris.feature_names
out:['sepal length (cm)','sepal width (cm)','petal length (cm)','petal width (cm)']iris.target
out:array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2])iris.target_names
out:array(['setosa', 'versicolor', 'virginica'],dtype='<U10')iris.data.shape
out:(150,4)

基于花瓣宽度这一个特征,创建一个分类器来检测Virginica鸢尾花:

#使用鸢尾花的宽度特征进行逻辑回归
X=iris["data"][:,3:]#3后面加“:”是为了输出列向量
y = (iris["target"] == 2).astype(np.int)  # 1 if Iris-Virginica, else 0from sklearn.linear_model import LogisticRegression
log_reg = LogisticRegression(random_state=42,solver='liblinear')
log_reg.fit(X, y)X_new = np.linspace(0, 3, 1000).reshape(-1, 1)
y_proba = log_reg.predict_proba(X_new)#输出预测的概率plt.plot(X_new, y_proba[:, 1], "g-", linewidth=2, label="Iris-Virginica")
plt.plot(X_new, y_proba[:, 0], "b--", linewidth=2, label="Not Iris-Virginica")

Virginica鸢尾花(三角形所示)的花瓣宽度范围为1.4~2.5厘米,而其他两种鸢尾花(正方形所示)花瓣通常较窄,花瓣宽度范围为0.1~1.8厘米。对花瓣宽度超过2cm的花,分类器可以很有信心地说它是一朵Virginica鸢尾花(对该类别输出一个高概率值),对花瓣宽度低于1cm以下的,也可以说其不是(对“非Virginica鸢尾花”类别输出一个高概率值)。在这两个极端之间,分类器则不太有把握。但是,如果你要求它预测出类别(使用predict方法而不是predict_proba方法),它将返回一个可能性最大的类别。也就是说,在大约1.6厘米处存在一个决策边界,这里“是”和“不是”的可能性都是50%,如果花瓣宽度大于1.6厘米,分类器就预测它是Virginica鸢尾花,否则就预测不是。

与其他线性模型一样,逻辑回归模型可以用L1 或L2 惩罚函数来正则化。默认添加的是L2 函数。控制LogisticRegression模型正则化程度的超参数不是alpha,而是(其他线性模型使用alpha,alpha的值越大,则具有更强的正则化,Alpha对应于其他线性模型中的,例如LogisticRegression或LinearSVC)。

函数说明:

LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,penalty='l2', random_state=42, solver='liblinear', tol=0.0001,verbose=0, warm_start=False)

1、penalty参数可选择的值为"l1"和"l2".分别对应L1的正则化和L2的正则化,默认是L2的正则化。
penalty参数的选择会影响我们损失函数优化算法的选择。即参数solver的选择,如果是L2正则化,那么4种可选的算法{‘newton-cg’, ‘lbfgs’, ‘liblinear’, ‘sag’}都可以选择。但是如果penalty是L1正则化的话,就只能选择‘liblinear’了。这是因为L1正则化的损失函数不是连续可导的,而{‘newton-cg’, ‘lbfgs’,‘sag’}这三种优化算法时都需要损失函数的一阶或者二阶连续导数。而‘liblinear’并没有这个依赖。

2、优化算法选择参数:solver参数决定了我们对逻辑回归损失函数的优化方法,有4种算法可以选择,分别是:

    a) liblinear:使用了开源的liblinear库实现,内部使用了坐标轴下降法来迭代优化损失函数。

    b) lbfgs:拟牛顿法的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。

    c) newton-cg:也是牛顿法家族的一种,利用损失函数二阶导数矩阵即海森矩阵来迭代优化损失函数。

    d) sag:即随机平均梯度下降,是梯度下降法的变种,和普通梯度下降法的区别是每次迭代仅仅用一部分的样本来计算梯度,适合于样本数据多的时候,SAG是一种线性收敛算法,这个速度远比SGD快。

 同时,sag每次仅仅使用了部分样本进行梯度迭代,所以当样本量少的时候不要选择它,而如果样本量非常大,比如大于10万,sag是第一选择。但是sag不能用于L1正则化,所以当你有大量的样本,又需要L1正则化的话就要自己做取舍了。要么通过对样本采样来降低样本量,要么回到L2正则化。

3、分类方式选择参数:multi_class
     multi_class参数决定了我们分类方式的选择,有 ovr和multinomial两个值可以选择,默认是 ovr。ovr即前面提到的one-vs-rest(OvR),而multinomial即前面提到的many-vs-many(MvM)。如果是二元逻辑回归,ovr和multinomial并没有任何区别,区别主要在多元逻辑回归上。

 OvR的思想很简单,无论你是多少元逻辑回归,我们都可以看做二元逻辑回归。具体做法是,对于第K类的分类决策,我们把所有第K类的样本作为正例,除了第K类样本以外的所有样本都作为负例,然后在上面做二元逻辑回归,得到第K类的分类模型。其他类的分类模型获得以此类推。

  而MvM则相对复杂,这里举MvM的特例one-vs-one(OvO)作讲解。如果模型有T类,我们每次在所有的T类样本里面选择两类样本出来,不妨记为T1类和T2类,把所有的输出为T1和T2的样本放在一起,把T1作为正例,T2作为负例,进行二元逻辑回归,得到模型参数。我们一共需要T(T-1)/2次分类。

  从上面的描述可以看出OvR相对简单,但分类效果相对略差(这里指大多数样本分布情况)。而MvM分类相对精确,但是分类速度没有OvR快。

  如果选择了ovr,则4种损失函数的优化方法liblinear,newton-cg, lbfgs和sag都可以选择。但是如果选择了multinomial,则只能选择newton-cg, lbfgs和sag了。

更多参考:https://blog.csdn.net/laobai1015/article/details/80512849

7、多元逻辑回归Softmax

逻辑回归模型可以直接支持多个类别,而不需要训练并组合多个二元分类器,这就是Softmax回归,或者叫多元逻辑回归。对于一个给定的实例x,Softmax回归模型首先计算出每个类别k的分数,然后对这些分数应用softmax函数,估算出每个类别的概率。你应该很熟悉计算分数的公式,因为它看起来就跟线性回归预测的方程一样。

类别k的Softmax分数:

 注意,每个类别都有自己特定的参数向量 。所有这些向量通常都作为行存储在参数矩阵Θ中。

计算完实例x每个类别的分数后,就可以通过Softmax函数来计算分数:计算出每个分数的指数,然后对它们进行归一化
处理(除以所有指数的总和):

跟逻辑回归分类器一样,Softmax回归分类器将估算概率值最高的类别作为预测类别.

Softmax回归分类器一次只会预测一个类别(也就是说,它是多类别,但是不是多输出),所以它仅适用于互斥的类别之上,例如植物的不同种类。你不能用它来识别一张照片中的多个人。

7.1、怎么训练

训练目标是得到一个能对目标类别做出高概率估算的模型(也就是其他类别的概率相应要很低)。通过将成本函数(交叉熵)最小化来实现这个目标,因为当模型对目标类别做出较低概率的估算时,会受到惩罚。交叉熵经常被用于衡量一组估算出的类别概率跟目标类别的匹配程度

交叉熵成本函数:

如果第i个实例的目标类别为k,则等于1,否则为0。当只有两个类别(K=2)时,该成本函数等价于逻辑回归的成本函数

对于类别k的交叉熵梯度向量:

计算出每个类别的梯度向量,然后使用梯度下降(或任意其他优化算法)找到最小化成本函数的参数矩阵Θ

交叉熵

交叉熵源于信息理论。假设你想要有效传递每天的天气信息,选项(晴、下雨等)有8个,那么你可以用3比特对每个选项进行编码,因为。但是,如果你认为几乎每天都是晴天,那么,对“晴天”用1比特(0),其他七个类别用4比特(从1开始)进行编码,显然会更有效率一些。

交叉熵衡量的是你每次发送天气选项的平均比特数。如果你对天气的假设是完美的,交叉熵将会等于天气本身的熵(也就是
其本身固有的不可预测性)。但是如果你的假设是错误的(比如经常下雨),交叉熵将会变大,增加的这一部分我们称之为KL散度(Kullback-Leibler divergence,也叫作相对熵)。两个概率分布p和q之间的交叉熵定义为:

KL 散度

两个概率分布之间的距离是可以测量的。在统计学里面经常需要测量两组样本分布之间的距离,进而判断出它们是否出自同一个 population,常见的方法有卡方检验(Chi-Square)和 KL 散度( KL-Divergence)。

KL 散度又叫相对熵(relative entropy)。在 Softmax 回归(或者 Logistic 回归),最后的输出节点上的值表示这个样本分到该类的概率,这就是一个概率分布。对于一个带有标签的样本,我们期望的概率分布是:分到标签类的概率是 1, 其他类概率是 0。但是理想很丰满,现实很骨感,我们不可能得到完美的概率输出,能做的就是尽量减小总样本的 KL 散度之和(目标函数)。这就是 Softmax 回归或者 Logistic 回归中成本函数的优化过程啦。(PS:因为概率和为 1,一般的 logistic 二分类的图只画了一个输出节点,隐藏了另外一个)。

现有关于样本集的2个概率分布p和q,其中p为真实分布,q非真实分布。按照真实分布p来衡量识别一个样本的所需要的编码长度的期望(即平均编码长度)为:熵:

如果使用错误分布q来表示来自真实分布p的平均编码长度,H(p,q)称之为“交叉熵”:

我们将由q得到的平均编码长度比由p得到的平均编码长度多出的bit数称为“相对熵”:

又被称为KL散度,它表示2个函数或概率分布的差异性:差异越大则相对熵越大,差异越小则相对熵越小,特别地,若2者相同则熵为0。注意,KL散度的非对称性。

交叉熵可在神经网络(机器学习)中作为损失函数,p表示真实标记的分布,q则为训练后的模型的预测标记分布,交叉熵损失函数可以衡量p与q的相似性。交叉熵作为损失函数还有一个好处是使用sigmoid函数在梯度下降时能避免均方误差损失函数学习速率降低的问题,因为学习速率可以被输出的误差所控制。

PS:通常“相对熵”也可称为“交叉熵”,虽然公式上看相对熵=交叉熵-信息熵,但由于真实分布p是固定的,D(p||q)由H(p,q)决定。

from:https://blog.csdn.net/witnessai1/article/details/79574812

7.2、实例:

使用Softmax回归将鸢尾花分为三类。当用两个以上的类别训练时,Scikit-Learn的LogisticRegressio默认选择使用的是一对多的训练方式,不过将超参数multi_class设置为"multinomial",可以将其切换成Softmax回归。你还必须指定一个支持Softmax回归的求解器,比如"lbfgs"求解器(详见Scikit-Learn文档)。默认使用l2正则化,你可以通过超参数C进行控制。

X = iris["data"][:, (2, 3)]  # petal length, petal width
y = iris["target"]
#多分类时LogisticRegression默认一对多策略,multi_class="multinomial"用于切换成soft max
softmax_reg = LogisticRegression(multi_class="multinomial",solver="lbfgs", C=10, random_state=42)
softmax_reg.fit(X, y)
softmax_reg.predict([[5, 2]])out:array([2])#一朵长宽为5,2的花属于3类花的概率
softmax_reg.predict_proba([[5, 2]])
out:array([[  6.38014896e-07,   5.74929995e-02,   9.42506362e-01]])

完整代码:https://github.com/liuzheCSDN/Scikit-Learn

机器学习实战4-sklearn训练线性回归模型(鸢尾花iris数据集分类)相关推荐

  1. sklearn训练感知器用iris数据集

    简化版代码 1 from sklearn import datasets 2 import numpy as np 3 4 #获取data和类标 5 iris = datasets.load_iris ...

  2. 《机器学习实战》8.4 线性回归之乐高玩具套件二手交易价格预测

    <机器学习实战>8.4 线性回归之乐高玩具套件二手交易价格预测 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多人工智能.机器学习干货 csdn:https: ...

  3. 机器学习(2)---简单线性回归模型

    机器学习(2)---简单线性回归模型 第一步:数据预处理 import pandas as pd import numpy as np import matplotlib.pyplot as pltd ...

  4. 《机器学习实战》8.2 线性回归基础篇之预测鲍鱼年龄

    <机器学习实战>8.2 线性回归基础篇之预测鲍鱼年龄 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多人工智能.机器学习干货 csdn:https://blo ...

  5. [机器学习-sklearn]鸢尾花Iris数据集

    鸢尾花数据集 1. 鸢尾花Iris数据集介绍 2. Sklearn代码获取Iris 2. 描述性统计 3. 箱线图 4. 数据分布情况 1. 鸢尾花Iris数据集介绍 Iris flower数据集是1 ...

  6. sklearn基础篇(三)-- 鸢尾花(iris)数据集分析和分类

    后面对Sklearn的学习主要以<Python机器学习基础教程>和<机器学习实战基于scikit-learn和tensorflow>,两本互为补充进行学习,下面是开篇的学习内容 ...

  7. 【统计学习方法】朴素贝叶斯对鸢尾花(iris)数据集进行训练预测

    本文摘要 · 理论来源:[统计学习方法]第三四章 朴素贝叶斯 · 技术支持:pandas(读csv).numpy.sklearn.naive_bayes.GaussianNB(高斯朴素贝叶斯模型).s ...

  8. 利用sklearn库决策树模型对iris数据多分类并进行评估

    1.导入所需要的库 from sklearn.tree import DecisionTreeClassifier from sklearn.datasets import load_iris 2.加 ...

  9. ML之SVM:基于SVM(sklearn+subplot)的鸢尾花iris数据集的前两个特征(线性不可分的两个样本),判定鸢尾花是哪一种类型

    ML之SVM:基于SVM(sklearn+subplot)的鸢尾花iris数据集的前两个特征(线性不可分的两个样本),判定鸢尾花是哪一种类型 目录 输出结果 实现代码 输出结果 (1).黄色的点为支持 ...

最新文章

  1. 排序算法一:选择排序
  2. 新入公司 问问题 ,快速了解代码的方法
  3. 创建私有CA及私有CA的使用
  4. CompletableFuture源码详解之java.util.concurrent.CompletableFuture#runAsync(java.lang.Runnable)
  5. 同济大学计算机学院徐老师,第十八届同济大学程序设计竞赛暨高校网络友谊赛圆满落幕...
  6. tcp udp区别优缺点_Linux网络编程面试题--tcp和udp的区别
  7. 【Notepad++】Notepad++ 插件 for js 各种插件全介绍
  8. 每天一道LeetCode-----化简路径
  9. leetcode603. 连续空余座位(SQL)
  10. 第四节:HTML5给表单带来的新标签、新属性、新类型
  11. 用c语言编程计算10,计算方法c语言编程.doc
  12. Akka的Actor生命周期《Eight》译
  13. 一行代码下载网页视频!
  14. linux系统声音管理,Mplayer 音量控制详解
  15. 神州数码java面试
  16. 淘宝签到红包商品直达链接,如何转化为自己的链接?
  17. 已知尺寸计算像素公式
  18. 高仿富途牛牛-组件化-优秀的时钟
  19. 20155110王一帆 《远程安防监控系统》课程设计个人报告
  20. 如何关闭打开文件安全警告

热门文章

  1. 华为荣耀20和x10比较_华为和荣耀旗舰该如何选?其实懂手机的朋友只选择前者...
  2. php 统计二维数组次数最多_前端面试题(数组篇)
  3. PHP7 下安装 memcache 和 memcached 扩展
  4. GCC 使用-C语言编译过程
  5. 洛谷 P3258 [JLOI2014]松鼠的新家 解题报告
  6. WPF的几种布局方式
  7. C语言 float、double数据在内存中的存储方式
  8. 分布式缓存-Memcached
  9. foreach 和 for 循环的区别
  10. [Winodows Phone 7控件详解]Silverlight toolkit for Windows Phone 7.1控件-3