一.线性回归

1.一元线性回归模型

现在有这样一堆数据,x,y是它的数据集                                                  

在坐标轴上是这样表示

我想找到它的规律,看看x,y是否相互依赖,是否存在定量关系。从坐标轴上可以看出,x,y应该存在某种线性关系,那么我应该如何找到这条线来衡量x,y的关系呢?那么引入一元线性回归模型来解决这个问题。

一元线性回归模型公式:y = \beta _{0}+\beta_{1}x+\epsilon

其中\beta _{0 }\beta _{1}是模型参数,\epsilon是误差项 除线性因素外的随机因素所产生的误差

2.多元线性回归模型

在一元线性回归模型的基础上再加上几个自变量就成了多元线性回归模型如:x1,x2,....y

多元线性回归模型公式:y = \beta _{0}+\beta_{1}x_{1}+ \beta_{2}x_{2}+\epsilon

其中\beta _{0 }\beta _{1}\beta _{2}是模型参数,\epsilon是误差项

误差项分析

误差项不可忽略,误差是必然产生的。并且由于产生了误差项,我们便可以基于误差的特点来进行对线性回归的参数估计的。误差项满足标准正态分布,其概率密度函数为:

                                                f(x)=\frac{1}{\sqrt{2\pi }\sigma }exp(-\frac{(x-\mu )^{2}}{2\sigma ^{2}})

对参数问题的估计就转化成了对误差项的分析。

线性回归的转化:

y = \beta _{0}+\beta_{1}x_{1}+ \beta_{2}x_{2}+\epsilon

矩阵计算:y=\beta _{0}x_{0}+\beta _{1}x_{1}+\beta _{2}x_{2}+\epsilon

x是样本项为列向量,此处要对\beta参数进行转置,转为行向量:

                                                      y^{i}=\beta ^{T}X^{i}+\epsilon ^{i}

误差项满足高斯分布:

                                                       p(\epsilon ^{i})=\frac{1}{\sqrt{2\pi }\sigma }exp(-\frac{(\epsilon ^{i})^{2}}{2\sigma ^{2}})

                                        p(y^{(i)}|X^{(i)};\beta ) = \frac{1}{\sqrt{2\pi }\sigma }exp(-\frac{(y^{(i)}-\beta ^{T}X^{i})^{2}}{2\sigma ^{2}})

极大似然估计

极大似然估计是统计学中最核心的参数估计方法之一,简单概括来讲就是“既然事情已经发生了,我们就假设它是所有可能情况中发生的概率最大的那一种”。举个例子,

        假设你和一个朋友去买菜,菜贩子告诉你“这筐苹果只有 10% 是坏的”。结果你随手拿了 5 个,发现全是坏的。你会相信菜贩子说的“坏果率只有 10%”吗?显然不会。你更愿意相信“坏果率接近 100%”,因为只有在坏果率极高的前提下,随手拿 5 个全坏的概率才最大。

        这种“用观测到的结果(样本)来反推最可能的参数(坏果率)”的过程,就是极大似然估计。

似然函数:                        

                                                    L(\theta )=\prod_{i=1}^{n}f(x_{i};\theta )

因为我们假设各个样本发生的概率是相互独立的,且误差是满足独立同分布的,那么所有的样本同时发生的概率就是它们各个概率连乘,这时我们需要求出一个\theta,使得L(\theta )最大,当它最大时表示当前样本发生的概率最大。这就是极大似然估计

将误差项的概率密度函数代入到似然函数:

                            L(\beta )=\prod_{i=1}^{m}p(y^{i}|X^{i};\beta ) = \prod_{i=1}^{m}\frac{1}{\sqrt{2\pi }\sigma }exp(-\frac{(y^{i}-\beta ^{T}X^{i})^{2}}{2\sigma ^{2}})

取对数得:

                           logL(\theta )=m*log\frac{1}{\sqrt{2\pi }\sigma }-\frac{1}{2\sigma ^{2}}\sum_{i=1}^{m}(y^{i}-\beta ^{T}X^{i})^{2}

把常数项删除:

                                                     J(\theta )=\frac{1}{2}\sum_{i=1}^{m}(y^{i}-\beta ^{T}X^{i})^{2}

保留1/2是后面求导时可以把系数化为1

最小二乘法求解

                                          J(\theta )=\frac{1}{2}(y-X\beta )^{T}(y-X\beta )

这一步是换成了矩阵运算,为了让机器并行运算

求导:        

                                            \Delta _{\beta }J(\beta )=X^{T}X\beta -X^{T}y

令偏导等于0:

                                                \beta =(X^{T}X)^{-1}X^{T}y

这样就能够得到我们的参数\beta

实例

现有三列数据分别是体重,年龄,血压收缩程度,我们需要探究体重,年龄对血压收缩的影响

下面是代码实现:

1.导入需要的包

import pandas as pd
from sklearn.linear_model import LinearRegression

2.加载数据

data = pd.read_csv("D://pythoncode/Sklearn_code/sklearn/多元线性回归.csv",encoding="gbk",engine='python')
X = data[["体重","年龄"]]
y = data["血压收缩"]

我这里的文件编码格式是gbk,读入时注意传递参数encoding="gbk",划分X,y数据集,选择体重,年龄两列数据为X,血压收缩这一列为y

3.创建对象,训练模型

我们来看看LinearRegression里面的参数

fit_intercept:表示是否有截距,如果没有则直接过原点,默认是True
normalize:表示是否将数据归一化,默认是False
copy_X:是否对x复制,如果选择False则直接对原数据覆盖(即经过中心化,标准化后,是否把新数据覆盖到原数据上)默认是True
n_jobs:计算时设置的任务个数(number of jobs)。如果选择-1则代表使用所有的CPU。这一参数的对于目标个数>1(n_targets>1)且足够大规模的问题有加速作用。
# 创建对象
liner_model = LinearRegression()
# 训练模型
liner_model.fit(X,y)

创建类对象liner_model,用对象里面的fit方法训练模型

4.查看拟合优度

# 拟合优度
score = liner_model.score(X,y)


print("拟合优度结果是:",score)

LinearRegression这个类继承父类的一个score方法,返回的是R^{2}

从结果来看拟合优度效果不错。

拟合优度

拟合优度是用来评判回归模型的准确率

判定系数R^{2}公式:

                                              R^{2}=\frac{SSR}{SSE}=\frac{\sum_{i=1}^{n}(y_{i}\hat{}-y\bar{})^{2}}{\sum_{i=1}^{n}(y_{i}-y\bar{})^{2}}

SSR:回归平方和

SSE:离差平方和

     · 反映了回归直线的拟合程度。

     · 取值范围在[0,1]之间。

     · R方越接近1,说明拟合效果越好;R方越接近0,说明拟合效果越差。

     · R方的平方根是相关系数。

二.逻辑回归

1.逻辑回顾的原理

线性回归是做回归的,而逻辑回归是做分类的。

  • 线性回归做的是:输入特征 XX,输出连续值(如预测房价 100万)。

  • 逻辑回归做的是:输入特征 XX,输出的是概率(如这封邮件是垃圾邮件的概率为 0.9)

还是这个坐标轴,不过数据的分布如上图所示,我现在想要做一个分类,我找到一条直线将数据划分为上下两部分,将上半部分的数据标记为1,下半部分的数据标记为0,现在来了一个新数据,判断这个数据属于0还是1,这就是逻辑回归。因此逻辑回归的关键就变成了如何得到这条直线。

从线性回归那里我们知道      y=\beta _{0}x_{0}+\beta _{1}x_{1}+\beta _{2}x_{2}+.....+\epsilon

这样算出来的数值在(-\propto ,+\propto )范围内,但概率必须在0-1之间。

核心武器:Sigmoid函数(把“任意值”压缩成“概率”)

2.Sigmoid函数

逻辑回归引入了Sigmoid函数(Logistic):

                                                 p(x) = \frac{1}{1+e^{-z}}

当z趋于正无穷,值趋于1,当z趋于负无穷,值趋于0

将线性函数带入Sigmoid函数得到:

                                        P(y=1|x;\beta ) = \frac{1}{1+e^{-\theta^ {T} x}}

这里的参数怎么求呢?这里又用到极大似然函数

3.损失函数

        在用Sigmoid函数压缩成概率下有这么个情况,当z趋于正无穷,p趋于1,这个p可直接当作概率,而当z趋于负无穷,p趋于0,这个p不能直接当作概率,要用(1-p)当作概率。将这两种情况合并:

                                            P(y_{i}|x_{i})=p_{i}^{y_{i}}\cdot (1-p_{i})^{1-y_{i}}

再用极大似然估计求解参数:

                                         L(\beta )=\prod_{i=1}^{n}p_{i}^{y_{i}}\cdot (1-p_{i})^{1-y_{i}}

取对数:

                                        \rho(\beta )=\sum_{i=1}^{n}[y_{i}log(p_{i})+(1-y_{i})log(1-p_{i})]

在机器学习中,我们习惯把求最大值转化成求最小值,所以给它加个负号,这就变成了大名鼎鼎的交叉熵损失函数(Log Loss):

                                    J(\beta )=-\frac{1}{n}\sum_{i=1}^{n}[y_{i}log(p_{i})+(1-y_{i})log(1-p_{i})]

怎么求解这个函数的最小值呢?引入梯度下降法

4.梯度下降

批量梯度下降,随机梯度下降,小批量梯度下降

梯度下降法(Gradient Descent),像下山一样,一步步往导数下降最快的方向迭代,直到找到损失最小的那组参数。

想象一下,你半夜被空投到一座完全陌生的山上(这是损失函数的“地形”),四周漆黑一片,你的目标是走到山脚下最低洼的地方(也就是损失最小的那个点)。

你看不见全貌,只能摸到脚下土地的坡度(这就是梯度)。

为了最快下山,你会怎么做?朝脚下最陡峭的向下方向,迈出一小步。

走完一步后,再次感受脚下的新坡度,再朝新的最陡方向迈一步。

重复这个过程,直到你走到平地(坡度为零),恭喜你,这就到达了“局部最低点”(在凸函数中也就是全局最低点)。

梯度下降法在计算机里干的,就是这件事。

我们要找损失函数J(\theta )里的最小值,其中\theta是模型里的参数(逻辑回归里的权重\beta),更新参数的公式为:

                                                     \theta _{new}=\theta _{old}-\eta \triangledown J(\theta _{old})
 \theta _{old } :你当前站的位置(当前的参数值)。
\bigtriangledown J(\theta )(梯度):就是脚下最陡的坡度。在数学上,它是损失函数对参数\theta的偏导数。它指明了上升最快的方向。

减号(-):因为是下山,所以要反着梯度的方向走。梯度朝上,我们就朝负梯度方向(向下)走。
\eta(学习率 / 步长):你每一步迈多大。这是人为设定的超参数,非常重要。

5.找到最优参数

当你用逻辑回归算出交叉熵损失函数后:

计算机随机给\beta赋初始值(比如全是 0)。计算当前\beta下的损失值,并对每个\beta求偏导(得到梯度)。执行更新公式:β=β−η⋅梯度。拿着新的\beta重新计算损失,再求导...直到损失值几乎不再下降(收敛),此时的\beta就是我们要找的最优参数。

6.正则化

正则化就是在极大似然函数所求的损失函数后面加了个惩罚,它降低了模型的拟合精度,提高了模型在未知数据上的泛化能力。公式:

                                                    L1正则化:\frac{1}{2}\cdot \lambda \cdot |\theta |                    

                                                    L2正则化:\frac{1}{2}\cdot \lambda \cdot |\theta |^{2}

其中\lambda为惩罚系数

加入到损失函数里面:

                 J(\theta )=-\frac{1}{m}\sum_{i=1}^{m}[y_{i}log(p_{i})+(1-y_{i})log(1-p_{i})]+\frac{1}{2m}\cdot \lambda \cdot \sum_{j=1}^{n}\theta _{j}^{2}

\theta_{j }求偏导:

                                \frac{\partial }{\partial \theta _{j}}[\cdot \cdot \cdot] =\frac{1}{m}\sum_{i=1}^{m}(p(x^{(i)})-y^{(i)})\cdot x_{j}^{(i)}+\frac{\lambda }{m}\cdot \theta _{j}

7.正则化后更新参数

                                              \theta _{new}=\theta _{old}-\eta \triangledown J(\theta _{old})     

即:

                             \theta_{new}=\theta _{old}-\eta \cdot \frac{1}{m}\sum_{i=1}^{m}(p(x^{(i)})-y^{(i)})\cdot x_{j}^{(i)}-\eta \cdot \frac{\lambda }{m}\cdot \theta _{j}  

化简得:

                             \theta _{new}=\theta _{old}\cdot (1-\eta \cdot \frac{\lambda }{m})-\eta \cdot \frac{1}{m}\sum_{i=1}^{m}(p(x^{(i)})-y^{(i)})\cdot x_{j}^{(i)}

7.实列分析

1.导入我们需要的包

除了导入LogisticRegression之外,这里面多了train_test_split和StanderScaler这两个包。

from sklearn.linear_model import LogisticRegression
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

train_test_split是用来划分数据集用的,它能将你的原始数据按照比例划分成训练集数据,测试集数据,训练集标签,测试集标签。下面是train_test_split里面的一些参数:

test_size:测试集所占的比例,可以直接输入具体的数字,也可以输入百分比(比如0.3,代表所占30%)

random_state:随机数种子,输入一个随机数种子,那么下次运行代码时计算机不会再次重新随机划分数据集而是按照随机数种子划分数据集(即两次运行代码时数据集划分是一致的,不会使你每次训练的模型都不一样)

StanderScaler是用来标准化数据的,具体是用其下的fit方法标准化数据集

2.读入数据与处理数据

data = pd.read_csv("D:\pythoncode\Sklearn_code\sklearn\逻辑回归\creditcard.csv")
print(data.head())
scaler = StandardScaler()
data["Amount"] = scaler.fit_transform(data[["Amount"]])
data = data.drop("Time",axis=1)

这里我们标准化了数据集中的“Amount”这一列的数据,并且删除了“Time”这一列的数据

上面是原始数据,下面是处理过的数据。

3.划分数据集

将X,y划分好后,还需要分出训练集与测试集,注意train_test_split返回的值严格按照训练集数据,测试集数据,训练集标签,测试集标签这一顺序。

X = data.drop("Class",axis=1)
y = data["Class"]
# 划分数据集
X_train_data,X_test_data,y_train_label,y_test_label = \
    train_test_split(X,y,train_size=0.3,random_state=1000)

4.建立模型与预测结果

  LogisticRegression里面有一些参数比较不同

  C :惩罚因子,它是正则化中惩罚系数\lambda的倒数C越小表示对模型的复杂度容忍值越低,惩罚力度越大

max_iter:最大迭代次数默认100

solver:默认梯度下降算法

# 创建对象
lr = LogisticRegression(C=0.01)
lr.fit(X_train_data,y_train_label)

# 预测结果
predict = lr.predict(X_test_data)
score = lr.score(X_test_data,y_test_label)
print("预测结果是:",score)

更多推荐