内容简介:在之前的《常见线性回归模型》一文中,介绍了机器学习中比较简单但又非常常用的线性回归模型,今天来介绍另外一个模型:Logistic Regression,这又是机器学习中用的非常多的一个模型。虽然Logistic Regression(后简称LR)里面带了回归字样(Regression),但它实际是一个分类模型(关于回归和分类的区别见《机器学习介绍》),更准确的说是一个先回顾一下线性回归的公式:$$ { \hat y=\omega_0+\omega_1x_1+...+\omega_px_p =\omega_
在之前的《常见线性回归模型》一文中,介绍了机器学习中比较简单但又非常常用的线性回归模型,今天来介绍另外一个模型:Logistic Regression,这又是机器学习中用的非常多的一个模型。虽然Logistic Regression(后简称LR)里面带了回归字样(Regression),但它实际是一个分类模型(关于回归和分类的区别见《机器学习介绍》),更准确的说是一个 二分类模型 (0、1或者true、false之类,当然通过一些手段也可以实现多分类),比如预测一份邮件是不是垃圾垃圾邮件、一个人是否患了某种病等。它的基本思想是:假设一份邮件为垃圾邮件的概率为$p$,我们根据一些特征计算出这个$p$,如果$p$大于0.5,那么就认为是垃圾邮件,否则就不是垃圾邮件。下面我们就看看是如何计算这个概率p的。
先回顾一下线性回归的公式:
$$ { \hat y=\omega_0+\omega_1x_1+...+\omega_px_p =\omega_0+X\omega } $$
线性回归预测出来的结果y属于整个实数域,而概率只能是0~1之间的数。有没有什么方法可以将整个实数域映射到0~1之间呢?当然有, Logit 函数就可以,我们看下Logit函数:
$$ { logit(x) = \frac{1}{1+e^{-x}} } $$
我们看下函数图像:
从函数公式和图像可以看出来自变量x的定义域为整个实数域,而因变量的值则为0~1之间的实数,正好符合我们上面的要求。其实除了logit函数,还有一些其它函数也可以实现该功能,因为这些函数的图形都呈S型,所以也称之为 Sigmoid (英文含义为“S型函数”)函数,我们看看除了logit函数之外的其他sigmoid函数:
当然最常用的sigmoid函数还是logit函数,所以很多地方提到sigmoid函数指的就是logit函数。
言归正传,现在我们已经解决了从实数域映射到0~1之间的问题了。然后我们将线性回归公式和logit函数合并一下:
$$ p = y(w,x) = \frac{1}{1+e^{-(\omega_0+X\omega)}} $$
$X$依旧是特征,所以现在和线性回归就一样了,我们只要根据已有的数据计算出$\omega_i$的值,也就是构建出了预测模型了。当有一条新的数据之后,我们带到上面的公式里面,计算出$y$的值,如果大于0.5就认为是某个类别,否则就属于另外一个类别。可以看到,LR模型是通过将线性模型与Sigmoid函数组合而实现的,这也是为什么里面带了回归的字样。
现在的问题就成了如何计算$\omega_i$了,也就是参数估计。常用的两种参数估计方法为: (普通)最小二乘法(Ordinary Least Squares, OLS) 和 最大似然估计(Maximum Likehood Estimation, MLE) 。前者基于距离,后者基于概率,当误差满足正态分布的时候,虽然两种估计原理和方式不一样,但结果是一样的。而之前线性回归模型中我们使用的就是最小二乘法,而LR是基于概率的,所以一般使用最大似然估计来计算参数$\omega_i$的值。如果你还不知道什么是最大似然估计,可以看下知乎上面马同学的回答: 如何通俗地理解概率论中的极大似然估计法?
网上关于LR算法参数估计详细的数学推导很多,这里就简单推导一下。使用MLE做参数估计的核心就是计算似然函数。现在假设有n个样本,观测值分别为$y_1,y_2,…,y_n$($y_i$的取值为0或1)。设$p_i=p(y=1|x_i)$为给定$x_i$ (第i条样本或第i个观测值)的条件下得到$y_i=1$的条件概率;这样,在同样条件下得到结果$y_i=0$的条件概率为$p(y=0|x_i)=1-p_i$。从而,我们得到一个观测值的概率为:
$$ { p(y_i) = p_i^{y_i}(1-p_i)^{1-y_i} } $$
因为各项观测值相互独立,所以他们的联合分布就是各边缘分布的乘积:
$$ { L(\theta)=\prod_{i=1}^n p_i^{y_i}(1 - p_i)^{1-y_i} } $$
这就是我们要求的n个观测值的似然函数(前面加一个负号就是Logistic Regression的损失函数)。MLE就是要求出能够使这一似然函数值最大的参数估计。为了简化,一般将其转换为对数形式(这里不打公式了,直接截图之前在word里面打的公式了):
接下来的问题就是求上面对数似然函数的极大值了。根据高数的理论,讨论就是求倒数,然后另倒数等于0,计算出来的点就是极值点了。我们分别对$\omega_0$和$\omega_i(i=1,...,n)$求偏导:
上面两个式子称为似然方程(likehood equations)。如果模型中有$n$个自变量,那么就有$n+1$个联立方程来估计$\omega_0$和$\omega_i(i=1,...,n)$的值。在线性回归中,似然方程是通过把偏差平方和分别对$\omega_0$和$\omega_i(i=1,...,n)$求偏导所得到的(即之前说的OLS),它对于未知参数都是线性的,因此很容易求解。但对于LR,上面两个似然方程都是$\omega_0$和$\omega_i(i=1,...,n)$的非线性函数,所以求解十分困难。对于这种非线性函数的极值问题,一般是通过迭代的方式求解的,最常用的就是梯度上升(求极大值)和梯度下降(求极小值)算法了。这里我们是要求最大值。而梯度上升的基本思想就是:要找某函数的最大值,最好的方法是沿着该函数的梯度方向探查,即沿着梯度的方向移动,每移动一次称之为一次迭代。梯度记为$\nabla$,$f(\omega,\omega_0)$的梯度为:
沿梯度方向每次移动的大小称之为步长,记为$\alpha$。这样梯度上升算法的迭代公式为:
$$ { \omega := \omega + \alpha \nabla_\omega f(\omega) } $$
我们不停的迭代该公式,直到达到某个停止条件位置迭代次数到达某个指定值。此时的$\omega$和$\omega_0$就是我们要求的回归系数和截距。
原生的Logistic Regression模型是处理二分类问题的,但通过一些技术手段也可以处理多分类,目前LR一般有三种类型:
- Binary Logistic Regression :即原生的二分类模型。
- Multinomial Logistic Regression :多分类模型,即要预测的目标变量多于两个。
- Ordinal Logistic Regression :序数多分类模型,目标变量多于两个,且有序,比如1到5.
另外简单总结下LR模型的优缺点:
优点:
- 高效、直观易懂,容易实现、结果容易解释,不需要耗费非常高的计算能力;
- 不需要对特征做归一化(一把基于概率的模型不需要做归一化,而基于距离的模型需要做归一化);
- 给出了观测值的概率,这一点在实际应用中非常重要,像很多评分模型的分数就是基于概率计算的。
缺点:
- 不太能处理特征特别多的场景,容易过拟合;
- 如果特征和目标变量相关性很小的话,模型性能也不好;
- 如果特征之间存在相关性的话,模型性能表现不好。
以上便是Logistic Regression的理论知识,实际中我们基本上不会自己实现LR模型,都是使用各种库,所以那些优(fan)美(ren)的数学公式的计算对我们都是不可见的。
最后我们使用scikit-learn这个 Python 的机器学习库中提供的LR模型做一个简单的二分类预测:有一个糖尿病的数据,数据中前8列为特征变量,最后一列为目标变量。我们按照通用的套路构建模型:
- 读入数据集,划分训练集和测试集;
- 划分训练集和测试集;
- 创建并训练模型;
- 在测试集上面进行预测;
- 探索模型性能
需要注意的是,第5步探索模型性能的时候用到了机器学习里面的一些专业东西,比如准确率、精确度、召回率等,如果你还不了解这些的含义,可以阅读我之前的文章《 confusion matrix,precision,recall,F1-score,ROC,AUC,p-value概念总结 》。
下面是完整的代码:
import pandas as pd from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from sklearn import metrics import matplotlib.pyplot as plt # 读入数据 df = pd.read_csv("https://raw.githubusercontent.com/niyanchun/AI_Learning/master/SampleData/diabetes.csv") X = df.values[:, :-1] y = df.values[:, -1] # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25,random_state=1024) # 创建模型并训练 lr = LogisticRegression() lr.fit(X_train, y_train) # 在测试集上面预测 predictions = lr.predict(X_test) # 求混淆矩阵、准确率、精确率、召回率 print("Confusion Matrix: ", metrics.confusion_matrix(y_test, predictions)) print("Accuracy: ", metrics.accuracy_score(y_test, predictions)) print("Precision: ", metrics.precision_score(y_test,predictions)) print("Recall: ", metrics.recall_score(y_test, predictions)) # 画ROC图 pred_proba = lr.predict_proba(X_test)[::,1] fpr, tpr, _ = metrics.roc_curve(y_test, pred_proba) auc = metrics.roc_auc_score(y_test, pred_proba) plt.plot(fpr,tpr,label="data 1, auc="+str(auc)) plt.legend(loc=4) plt.show()
这是总结的之前自己做的一些笔记,当时查阅的资料已经不记得有哪些已经出处了,本文就不附 References 了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 通俗易懂--决策树算法、随机森林算法讲解(算法+案例)
- 限流算法之漏桶算法、令牌桶算法
- 什么是Paxos算法?Paxos算法是区块链核心算法之一
- 一文读懂对称加密算法、非对称加密算法和Hash算法
- 算法(六):图解贪婪算法
- 算法篇03:排序算法
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。