线性归回和Logistc回归原理分析及代码实现
(注:更多关于回归的代码实例,请看我的个人github仓库)
一、线性回归
1.原理介绍
定义:
线性回归在假设特证满足线性关系,根据给定的训练数据训练一个模型,并用此模型进行预测。
为了了解这个定义,我们先举个简单的例子;我们假设一个线性方程 Y=2x+1, x变量为商品的大小,y代表为销售量;当月份x =5时,我们就能根据线性模型预测出 y =11销量;对于上面的简单的例子来说,我们可以粗略把 y =2x+1看到回归的模型;对于给予的每个商品大小都能预测出销量;当然这个模型怎么获取到就是我们下面要考虑的线性回归内容;并且在现实中影响销量(y)的因素好有很多,我们就拿商品大小(x₁),商品价格为例 (x₂)为例:
在机器学习之前,获取数据是第一步(无米难巧妇之炊),假定我们的样本如下:其中x1 为商品的大小,x2 为商品的价格,y 为商品的销量:
X1 | X2 | Y |
---|---|---|
3 | 5 | 10 |
2 | 6 | 14 |
6 | 10 | 28 |
2.模型推导
为了推导模型,在假设数据满足线性模型条件下,可以设定线性模型为;x1特征为商品的大小,X2特征为商品的价格
2.1 建模
第一步:
模型假定好后,我们把训练数据代入上面的设定模型中,可以通过模型预测一个样本最终值.
然后样本真实值 y 和模型训练预测的值之间是有误差 ε ε ,再假设训练样本的数据量很大的时候,根据中心极限定律可以得到
满足 (μ,δ2) ( μ , δ 2 ) 高斯分布的;由于方程有截距项 ,故使用可以 u=0 u = 0 ; 故满足 (0,δ2) ( 0 , δ 2 ) 的高斯分布;
如上面可知,对于每一个样本 x ,代入到 p(y|x;θ) p ( y | x ; θ ) 都会得到一个y 的概率;又因为设定样本是独立同分布的;对其求最大似然函数:
对其化简如下:
以上就得到了回归的损失函数最小二乘法的公式,对于好多介绍一般对线性回归的线性损失函数就直接给出了上面的公式二乘法。
下面我们就对上面做了阶段性的总结:
线性回归,根据大数定律和中心极限定律假定样本无穷大的时候,其真实值和预测值的误差 ϵ ϵ 的加和服从 (μ,δ) ( μ , δ ) 的高斯分布且独立同分布,然后把 ε=y−ϕx ε = y − ϕ x 代入公式,就可以化简得到线性回归的损失函数;
2.1 计算
第二步:对损失函数进行优化也就是求出w,b,使的损失函数最小化;
在这儿提供两种方法
方法一:使用矩阵(需要满足可逆条件)
以上就是按矩阵方法优化损失函数,但上面方法有一定的局限性,就是要可逆
方法二:梯度下降法
于梯度下降法的说明和讲解资料很多,深入的讲解这里不进行,可以参考(http://www.cnblogs.com/ooon/p/4947688.html)这篇博客,博主对梯度下降方法进行了讲解,我们这里就简单的最了流程解说;
总体流程就如上所示,就是求出每个变量的梯度;然后顺着梯度方向按一定的步长a,进行变量更新;下面我们就要求出每个变量的梯度,下面对每个θ进行梯度求解公式如下:
如上我们求出变量的梯度;然后迭代代入下面公式迭代计算就可以了:
3.代码详情
按上面优化步骤就可以求出w,b,就可以获得优化的特征方程:说这么多先上个代码:
#!/usr/bin/python
# -*- coding:utf-8 -*-
import numpy as np
import warnings
from sklearn.exceptions import ConvergenceWarning
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression,RidgeCV,LassoCV,ElasticNetCV
import matplotlib as mpl
import matplotlib.pyplot as plt
if __name__ == "__main__":
warnings.filterwarnings(action='ignore', category=ConvergenceWarning)
np.random.seed(0)
np.set_printoptions(linewidth=1000)
N = 9
x = np.linspace(0, 6, N) + np.random.randn(N)
x = np.sort(x)
y = x**2 - 4*x - 3 + np.random.randn(N)
x.shape = -1, 1
y.shape = -1, 1
p =Pipeline([
('poly', PolynomialFeatures()),
('linear', LinearRegression(fit_intercept=False))])
mpl.rcParams['font.sans-serif'] = [u'simHei']
mpl.rcParams['axes.unicode_minus'] = False
np.set_printoptions(suppress=True)
plt.figure(figsize=(8, 6), facecolor='w')
d_pool = np.arange(1, N, 1) # 阶
m = d_pool.size
clrs = [] # 颜色
for c in np.linspace(16711680, 255, m):
clrs.append('#%06x' % c)
line_width = np.linspace(5, 2, m)
plt.plot(x, y, 'ro', ms=10, zorder=N)
for i, d in enumerate(d_pool):
p.set_params(poly__degree=d)
p.fit(x, y.ravel())
lin = p.get_params('linear')['linear']
output = u'%s:%d阶,系数为:' % (u'线性回归', d)
print output, lin.coef_.ravel()
x_hat = np.linspace(x.min(), x.max(), num=100)
x_hat.shape = -1, 1
y_hat = p.predict(x_hat)
s = p.score(x, y)
z = N - 1 if (d == 2) else 0
label = u'%d阶,$R^2$=%.3f' % (d, s)
plt.plot(x_hat, y_hat, color=clrs[i], lw=line_width[i], alpha=0.75,label=label, zorder=z)
plt.legend(loc='upper left')
plt.grid(True)
# plt.title('线性回归', fontsize=18)
plt.xlabel('X', fontsize=16)
plt.ylabel('Y', fontsize=16)
plt.show()
运行代码后可见打印控制台信息如下:
图像如下:
4.线性回归的推广(linear/Ridge/Lasso/ElasticNet)
从上面图像可以看出,当模型复杂度提高的时候,对训练集的数据拟合很好,但会出现过度拟合现象,为了防止这种过拟合现象的出现,我们在损失函数中加入了惩罚项,根据惩罚项不同分为以下:
最后一个为Elastic Net 回归,把 L1 正则和 L2 正则按一定的比例结合起来
L1会趋向于产生少量的特征,而其他的特征都是0,而L2会选择更多的特征,这些特征都会接近于0。Lasso在特征选择时候非常有用,而Ridge就只是一种规则化而已。在所有特征中只有少数特征起重要作用的情况下,选择Lasso比较合适,因为它能自动选择特征。而如果所有特征中,大部分特征都能起作用,而且起的作用很平均,那么使用Ridge也许更合适。对于各种回归的比较可以看下图:
目前线性回归就写这么多,有时间再慢慢修改和添加更详细的内容。
二、Logistic回归
在正式进入主题之前, 先提前强调一下,logistic回归,又叫对数几率回归(从后文中可以知道这个名字的由来),这是一个分类模型而不是一个回归模型!
,下文开始将从不同方面讲解logistic回归的原理,随后分别使用梯度上升算法和随机梯度上升算法将logistic回归算法应用到实例中.
1.原理介绍
1.1 前言
想必大家也早有疑惑,既然logistic回归名字中都带有“回归”二者,难道和回归模型一点关系都没有!没错,二者是有联系的
,下面我们便来谈一谈.
由上面的讲解,我们已经知道线性回归的模型如下:
写成向量形式:
同时进一步可以写成
广义
线性回归模型:
(注意,其中 g−1(x) g − 1 ( x ) 是单调可微函数。)
1.2 logistic回归和线性回归的关系
注意了,敲黑板了哈!!!
下面我们便从线性回归的回归模型引出logistic回归的分类模型!!!
我们知道上诉线性回归模型只能够进行回归学习,但是若要是做分类任务如何做!答案便是在“广义线性回归”模型中:只需找一个单调可微函数将分类任务的真实标记y与线性回归模型的预测值联系起来便可以了!
logistic回归是处理二分类问题的,所以输出的标记y={0,1},并且线性回归模型产生的预测值z=wx+b是一个实值,所以我们将实值z转化成0/1值便可,这样有一个可选函数便是“单位阶跃函数”:
这种如果预测值大于0便判断为正例,小于0则判断为反例,等于0则可任意判断!
但是单位阶跃函数是非连续的函数,我们需要一个连续的函数,“Sigmoid函数”便可以很好的取代单位阶跃函数:
sigmoid函数在一定程度上近似单位阶跃函数,同时单调可微,图像如下所示:
这样我们在原来的线性回归模型外套上sigmoid函数便形成了logistic回归模型的预测函数,可以用于二分类问题: