(二)逻辑回归(LogisticRegression)原理及代码实现

逻辑回归

本系列重点在浅显易懂,快速上手。不进行过多的理论讲解:也就是不去深究what,而是关注how。全文围绕以下三个问题展开:

1)长什么样?

2)解决什么问题?

3)怎么实现?

3.1)从数学讲,原理

3.2)从代码上讲,如何掉包实现

长什么样

上节讲了线性回归,解决回归问题的方式。回归问题的y值是连续的,例如:房价。线性回归模型的输出是连续的,值域范围是(-∞,+∞)可以解决回归问题不难理解,但如何用线性回归解决分类问题呢?

因为分类问题(例如预测明天是晴天还是下雨,1表示晴天,0表示下雨)的值域是0或者1。或者说分类问题的值域应该是[0,1]之间的值,表示事情发生的概率,例如0.8,表示明天晴天的概率是0.8,但仍然对接不上线性回归模型(-∞,+∞)的值域范围。

这里就需要引入几率的概念,即:odds=\frac{p}{1-p},odds的取值范围是[0,+∞],再取对数log,即:log(odds)=log(\frac{p}{1-p}),取值范围就是(-∞,+∞)了。所以用线性回归解决分类问题,实际上是,去拟合log(odds)。

即:

$$
θ^Tx=log(odds)=log(\frac{p}{1-p})\\ p=\frac{1}{1+e^{-θ^Tx}},这就是大名鼎鼎的sigmoid函数了
$$

所以逻辑回归,实际上就是再线性回归的基础上,经过一层sigmoid函数,就可以解决分类问题了。

解决什么问题

先看一组数据(一组sklearn中公开的数据集,鸢尾花的种类预测,共有4个特征,最后一列y是花的种类,逻辑回归只能解决二分类问题,所以这里只取y=0或者1两种类型,下面展示了5条数据,实际数据有100条):

采用逻辑建模,最终的目的就是为了找到一组θ_1,θ_2,θ_3,θ_4,θ_0(除了4个系数,还包含一个常数项θ_0),使得下式成立。

$$
\frac{1}{1+e^{-(θ_1*x1+θ_2*x2+θ_3*x3+θ_4*x4+θ_0)}} =y
$$

最后就通过下面的式子,来预测鸢尾花的类型。

怎么实现

数学理论

设我们最终得到的模型如下

$$
h_θ(x)=\frac{1}{1+e^{-θ^Tx}}
$$

h_θ(x)实际上预测的是,取1的概率,即:

取0的概率,即

建立似然函数如下:

很明显这应该求似然函数的最大值,

转换为对数似然函数为

求导,

转换为矩阵形式,

$$
\frac{\partial l(θ)}{\partial θ} = X^T(Y-\frac{1}{1+e^{-Xθ}})
$$

既然要求l(θ)的最大值,就是梯度提升的方式,即:

$$
θ = θ+α*\frac{1}{m}*\frac{\partial l(θ)}{\partial θ} \\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ = θ+α*\frac{1}{m}*X^T(Y-\frac{1}{1+e^{-Xθ}})
$$

逻辑回归的损失函数为交叉熵损失函数(也叫对数损失函数):

手写代码实现

 
#_*_coding:utf-8_*_
 import numpy as np
 import pandas as pd
 from sklearn import datasets
 from tqdm import tqdm, trange
 import matplotlib.pyplot as plt
 ​
 class Logistic():
     def __init__(self,X,Y,theta):
         self.theta = theta
         self.X = X
         self.Y = Y
         
     
     def H(self):
         result = 1/(1+np.exp(-1*np.dot(self.X,self.theta)))
         return  result
     
     def R(self):
         predict = self.H()
         result = np.dot(self.X.T,(self.Y-predict))
         return result
     
     def L(self):
         predict = self.H()
         predict[self.Y==0] = 1-predict[self.Y==0]
         result = -1*np.sum(np.log(predict))
         return result
     
     def train(self,epoch,learn_rate):
         for i in range(epoch):
             loss = self.L()
             self.theta = self.theta + learn_rate*self.R()
             print(loss)
         print(self.H())
         
     
 if __name__ == '__main__':
     
     data = datasets.load_iris()
     X = data.data[data.target<2]
     Y = data.target[data.target<2].reshape(-1,1)
     theta = np.random.random((X.shape[1],1))
     
     LR = Logistic(X, Y,theta)
     LR.train(epoch = 1000000,learn_rate=0.0001)
     
     print('Done')

sklearn调包实现

这里直接讲解,如何调用sklearn实现。

 from sklearn.linear_model import LogisticRegression #sklearn中,线性回归模型在linear_model模块中
 # 调取sklearn中自带的数据集
 from sklearn.datasets import load_iris #调用上文一开始提到大波士顿房价数据集
 ​
 X, y = load_boston(return_X_y=True) #获取X,y数据
 ndarray = np.c_[X,y]
 X = ndarray[np.where(ndarray[:,-1:]<2)[0]] #逻辑回归做2分类,只筛选y值为0和1的样本
 LR = LogisticRegression() #初始化一个线性回归模型
 LR.fit(X,y) #fit函数用于训练
 ​
 LR.predict(X) #predict函数用于预测
 LR.coef_ #coef_用于返回θ的值
 LR.intercept_ #intercept_用于返回常数项的值(截距)
 ​

更多内容可以参考sklearn的官方文档

sklearn.linear_model.LogisticRegression — scikit-learn 1.3.0 documentation

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值