【ML】逻辑回归(LogisticRegression)原理+实践(基于sklearn)

原理介绍

逻辑回归不是回归问题,而是分类问题,最常用来解决二分类问题。

逻辑回归最核心的便是激活函数,而最常用的便是sigmoid函数:
P ( x ) = 1 1 + e − x P(x)=\frac{1}{1+e^{-x} } P(x)=1+ex1
在这里插入图片描述
sigmoid函数有一个很好的性质,他的值域在[0,1]之间。对于任意值域的函数g(x)都可以通过sigmoid函数压缩到[0,1]之间。
如上图,sigmoid函数在x=0点的值为0.5。而对于分类问题,一组数据 ( x i 1 , . . . y i 1 ) , ( x i 2 , . . . y i 2 ) , ( x i 3 , . . . y i 3 ) , . . . . {(x_{i1},...y_{i1}),(x_{i2},...y_{i2}),(x_{i3},...y_{i3}),....} (xi1,...yi1),(xi2,...yi2),(xi3,...yi3),....,y的值为离散值{1,0}。
所以我们不妨建立模型: g ( x ) = p 0 + p 1 X 1 + p 2 X 2 g(x) = p_0+p_1X_1+p_2X_2 g(x)=p0+p1X1+p2X2(根据实际情况可以调整为更复杂的形式)。用g(x)替换sigmoid函数中的x.当用实际数据代入g(x)时,得到的g(x)值为一个区间在(-∞,∞)的值,代入sigmoid函数便获得一个[0,1]区间内的值,假设当sigmoid函数值大于0.5我们认为值为1,小于0.5我们认为值为0,那么我们只需要调整 p 0 , p 1 , p 2 p_0,p_1,p_2 p0,p1,p2的值,使得g(x)在所有数据上都能尽量呈现此特性即可。此时g(x)便是我们想要的模型。而为了模型尽可能的准确,我们希望sigmoid函数在训练数据集上,每组正例数据计算出的值尽量逼近1. 每组反例数据计算出的值尽量逼近0.

有以下损失函数(注意损失函数前有负号,奈何数学水平有限,详细的推导大家看这里:https://zhuanlan.zhihu.com/p/44591359):
− ∑ n = 1 N ( y n ln ⁡ ( p ) + ( 1 − y n ) ln ⁡ ( 1 − p ) ) -\sum_{n=1}^{N}\left(y_{n} \ln (p)+\left(1-y_{n}\right) \ln (1-p)\right) n=1N(ynln(p)+(1yn)ln(1p))
其中 y n y_{n} yn即每组数据的真实值{0,1},p即sigmoid函数(将x换位g(x)后的),我们知道sigmoid函数值域为[0,1],而 − l n ( x ) -ln(x) ln(x)在[0,1]区间内是单调减函数,所以要取得最小值,要求x越接近1越好。所以有:

  • y n = 1 y_{n}=1 yn=1时,损失函数只有前半段。即 l n ( p ) ln (p) ln(p),要使损失函数最小,则p越接近1越好。
  • y n = 0 y_{n}=0 yn=0时,损失函数只有后半段。即 l n ( 1 − p ) ln(1-p) ln(1p)。同理,p越接近0越好(即1-p越接近1)。

与我们希望的正例尽量接近1,反例尽量接近0一致。后面就是函数求导,梯度下降求最小值了。这里求解过程大家感兴趣可以查看上面给的公式推导链接。

实践

数据集

下载:https://www.kaggle.com/datasets/yuanheqiuye/exam-data

读取数据

import pandas as pd
import numpy as np

data = pd.read_csv('/kaggle/input/exam-data/exam_data.csv')
data.head()

输出:

Exam1Exam2Pass
034.62366078.0246930
130.28671143.8949980
235.84740972.9021980
360.18259986.3085521
479.03273675.3443761

观察数据

from matplotlib import pyplot as plt
plt.figure()
mask=data.loc[:,'Pass'] > 0
plt.scatter(data.loc[:,'Exam1'][mask],data.loc[:,'Exam2'][mask])
plt.scatter(data.loc[:,'Exam1'][~mask],data.loc[:,'Exam2'][~mask])

在这里插入图片描述

模型训练(一次形式)

训练

定义边界函数:p0+p1X1+p2X2=0

# 准备数据
X = data.drop(columns=['Pass'])
y = data.loc[:,'Pass']

# 训练数据
from sklearn.linear_model import LogisticRegression
LR1 = LogisticRegression()
LR1.fit(X,y)
p1,p2 = LR1.coef_[0][0],LR1.coef_[0][1]
p0 = LR1.intercept_
print(p0,p1,p2)

输出:

[-25.05219314] 0.20535491217790386 0.20058380395469053

预测+评估(一次)

#预测
y_predict = LR1.predict(X)

#评估
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y,y_predict)
print(accuracy)

输出:

0.89

通过图形观察

# 根据定义的模型计算分割线
X2_new = -(p1*X1+p0)/p2

plt.figure()
mask=data.loc[:,'Pass'] > 0
plt.scatter(data.loc[:,'Exam1'][mask],data.loc[:,'Exam2'][mask])
plt.scatter(data.loc[:,'Exam1'][~mask],data.loc[:,'Exam2'][~mask])
plt.plot(X1,X2_new)

在这里插入图片描述
从图可以看出,效果不是很好。

模型训练(二次形式)

使用二次建模,定义边界函数:q0+q1X1+q2X2+q3X1X1+q4X2X2+q5X1X2=0

数据处理

X1 = data.loc[:,'Exam1']
X2 = data.loc[:,'Exam2']
X1_2=X1*X1
X2_2=X2*X2
X1_X2=X1*X2
data_new = pd.DataFrame({"X1":X1,'X2':X2,'X1_2':X1_2,'X2_2':X2_2,'X1_X2':X1_X2})

训练

#训练模型
LR_2 = LogisticRegression()
LR_2.fit(data_new,y)

预测+评估(二次)

#预测
y_predict_new = LR_2.predict(data_new)
print(y_predict_new)

# 查看准确率
accuracy_new = accuracy_score(y, y_predict_new)
print(accuracy_new)

输出:

1.0

效果非常好

通过图形观察效果

# 绘制函数图形q0+q1X1+q2X2+q3X1^2+q4X2^2+q5X1X2=0
q0=LR_2.intercept_
q1,q2,q3,q4,q5=LR_2.coef_[0][0],LR_2.coef_[0][1],LR_2.coef_[0][2],LR_2.coef_[0][3],LR_2.coef_[0][4]

#排序,为了绘图
X1_new = X1.sort_values()

#已知X1,求X2,即一元二次方程aX^2+bx+c=0
c=q0+q1*X1_new+q3*X1_new*X1_new
b=(q2+q5*X1_new)
a=q4

#根据方程通解,取正数(得分肯定是正的)
X2_new2 = (-b+np.sqrt(b*b-4*a*c))/(2*a)

# 绘制图形
plt.figure()
mask=data.loc[:,'Pass'] > 0
plt.scatter(data.loc[:,'Exam1'][mask],data.loc[:,'Exam2'][mask])
plt.scatter(data.loc[:,'Exam1'][~mask],data.loc[:,'Exam2'][~mask])
plt.plot(X1_new,X2_new2)

在这里插入图片描述
从图可以看出,分类的非常好。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值