当前位置: 首页 > article >正文

【Python机器学习】1.9. 逻辑回归实战(进阶):建立二阶边界模型

喜欢的话别忘了点赞、收藏加关注哦(关注即可查看全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)
在这里插入图片描述

1.9.1. 一些准备工作

接下来,请你确保你的Python环境中有pandasmatplotlibscikit-learnnumpy这几个包,如果没有,请在终端输入指令以下载和安装:

pip install pandas matplotlib scikit-learn numpy

我把.csv数据文件放在GitCode上了,点击链接即可下载。

训练数据有3栏:exam1exam2exam3_pass_or_notexam1exam2里填写的是学生在两次考试中的成绩(可以是浮点数,满分100),exam3_pass_or_not代表第三次考试有没有通过,通过是1,没通过是0。我们的目标就是训练逻辑回归模型去找到exam3_pass_or_not的决策边界。

下载好后把它移到你的Python项目文件夹里即可。

1.9.2. 建立一阶边界模型

在上一篇文章中我们介绍了如何建立简单的一阶边界模型,这里就不再详细讲解了,我就直接把代码和输出贴在这里:

# 读取数据  
import pandas as pd  
data = pd.read_csv('exam_results.csv')  
  
# 给x和y赋值  
x = data.drop(['exam3_pass_or_not'], axis=1)  
y = data.loc[:, 'exam3_pass_or_not']  
  
# 训练模型  
from sklearn.linear_model import LogisticRegression   
model = LogisticRegression()  
model.fit(x, y)  
  
# 获取决策边界  
theta1, theta2 = model.coef_[0]  
theta0 = model.intercept_[0]  
  
# 获取预测值  
prediction = model.predict(x)  
  
# 可视化  
import matplotlib.pyplot as plt  
import numpy as np

x1 = data.loc[:, 'exam1'].to_numpy()  
x2 = data.loc[:, 'exam2'].to_numpy()  
y = data.loc[:, 'exam3_pass_or_not'].to_numpy()  
  
class0 = (y == 0)  
class1 = (y == 1)  
  
plt.scatter(x1[class0], x2[class0], c='r', marker='o')  
plt.scatter(x1[class1], x2[class1], c='b', marker='x')  
plt.xlabel('exam1')  
plt.ylabel('exam2')  
  
# 计算 x1 的范围  
x1_min, x1_max = x1.min() - 1, x1.max() + 1  
x1_range = np.linspace(x1_min, x1_max, 100)  
  
# 使用决策边界公式计算 x2x2_boundary = -(theta1 * x1_range + theta0) / theta2  
  
# 绘制决策边界  
plt.plot(x1_range, x2_boundary, color='green', label="Decision Boundary")  
  
# 展示  
plt.legend()  
plt.show()  
  
# 计算准确率  
from sklearn.metrics import accuracy_score  
accuracy = accuracy_score(y, prediction)  
print(f'Accuracy: {accuracy}')

输出:

Accuracy: 0.972

输出图片:
请添加图片描述

可以看到,有一些数据确实呗决策曲线错分类了,这是一阶决策边界(一条直线)的极限了。如果还要提升准确率就需要建立二阶的决策边界(一条曲线)。

1.9.3.建立二阶决策边界

Step 1: 读取数据

一样的使用pandas库来读取csv文件,顺便使用head方法来查看一下数据的前几项:

# 读取数据  
import pandas as pd  
data = pd.read_csv('exam_results.csv')  
  
print(data.head())

输出:

       exam1      exam2  exam3_pass_or_not
0  37.454012  69.816171                  0
1  95.071431  53.609637                  1
2  73.199394  30.952762                  1
3  59.865848  81.379502                  1
4  15.601864  68.473117                  0

我们还可以使用上一篇文章 1.8. 逻辑回归实战(基础) 中教过的画有分类的散点图方法来直观的看看数据:

# 可视化原始数据  
import matplotlib.pyplot as plt  
x1 = data.loc[:, 'exam1'].to_numpy()  
x2 = data.loc[:, 'exam2'].to_numpy()  
y = data.loc[:, 'exam3_pass_or_not'].to_numpy()  
  
class0 = ( y == 0 )  
class1 = ( y == 1 )  
  
plt.scatter(x1[class0], x2[class0], c='r', marker='o')  
plt.scatter(x1[class1], x2[class1], c='b', marker='x')  
plt.xlabel('exam1')  
plt.ylabel('exam2')  
plt.show()

输出图片:
请添加图片描述

Step 2: 给xy赋值

我们要首先明确xy代表什么:

  • yexam3_pass_or_not这一栏的数据

x有些特别,由于我们建立的是二阶模型,所以方程的项跟原来比更复杂:
θ 0 + θ 1 X 1 + θ 2 X 2 + θ 3 X 1 2 + θ 4 X 2 2 + θ 5 X 1 X 2 = 0 \theta_0 + \theta_1 X_1 + \theta_2 X_2 + \theta_3 X_1^2 + \theta_4 X_2^2 + \theta_5 X_1 X_2 = 0 θ0+θ1X1+θ2X2+θ3X12+θ4X22+θ5X1X2=0
x_12、`x_2`2、X_1 * x_2这些项。所以我们得把这些项打包在字典里,再转为模型能使用的DataFrame格式给它使用。

# 给x和y赋值  
y = data.loc[:, 'exam3_pass_or_not']  
x1 = data.loc[:, 'exam1']  
x2 = data.loc[:, 'exam2']  
x = {  
    'x1': x1,  
    'x2': x2,  
    'x1^2': x1 ** 2,  
    'x2^2': x2 ** 2,  
    'x1*x2': x1 * x2,  
}  
  
x = pd.DataFrame(x)  
print(x.head())

输出:

          x1         x2         x1^2         x2^2        x1*x2
0  37.454012  69.816171  1402.803006  4874.297789  2614.895713
1  95.071431  53.609637  9038.576924  2873.993140  5096.744851
2  73.199394  30.952762  5358.151308   958.073452  2265.723399
3  59.865848  81.379502  3583.919807  6622.623341  4871.852929
4  15.601864  68.473117   243.418162  4688.567787  1068.308266

这是最基础的一种方法,还有一种简单的方法来生成这个字典:

from sklean.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree = 2)
x = data.drop(['exam3_pass_or_not'], axis = 1)
x = poly.fit_transform(x)
  • poly = PolynomialFeatures(degree = 2)中先创建了一个PolynomialFeatures实例,然后通过degree参数来调整是几次的多项式,我写的是2生成的就会是2次多项式。
  • 使用data.drop(['exam3_pass_or_not'], axis = 1)来去掉最后一列的数据,保留前两列
  • 使用poly上的fit_transform方法来生成字典

Step 3: 训练模型

把数据喂给scikit-learn下的逻辑回归模型进行训练即可:

# 训练模型  
from sklearn.linear_model import LogisticRegression  
model = LogisticRegression()  
model.fit(x, y)

Step 4: 获取决策边界

我们可以通过coef_intercept_两个方法分别获得截距和系数:

# 获取决策边界  
theta1, theta2, theta3, theta4, theta5 = model.coef_[0]  
theta0 = model.intercept_[0]

print(f'Decision Boundary: {theta0} + {theta1}x1 + {theta2}x2 + {theta3}x1^2 + {theta4}x2^2 + {theta5}x1*x2')

这里面的每个变量都对应着方程中的参数:
θ 0 + θ 1 X 1 + θ 2 X 2 + θ 3 X 1 2 + θ 4 X 2 2 + θ 5 X 1 X 2 = 0 \theta_0 + \theta_1 X_1 + \theta_2 X_2 + \theta_3 X_1^2 + \theta_4 X_2^2 + \theta_5 X_1 X_2 = 0 θ0+θ1X1+θ2X2+θ3X12+θ4X22+θ5X1X2=0

输出:

Decision Boundary: -204.44094927587327 + -1.0566693402530631x1 + 1.3772537803356335x2 + 0.057584352318122055x1^2 + 0.006716600903162952x2^2 + 0.010830701167147672x1*x2

Step 5: 获取预测值

# 获取预测值  
prediction = model.predict(x)

由于我们有500个数据,打出来太多了,这里就不进行打印了。

Step 6: 可视化决策边界

这里可视化决策边界稍微有点复杂,因为是二阶的项变多了,但是思路是暴力且简单的:我们都知道了所有的theta值,就是把解析式得出来了。接着根据x_1x_2值和直接算对应的点即可。

# 可视化  
import matplotlib.pyplot as plt  
import numpy as np  
  
x1 = x1.to_numpy()  
x2 = x2.to_numpy()  
y = y.to_numpy()  
  
class0 = (y == 0)  
class1 = (y == 1)  
  
plt.scatter(x1[class0], x2[class0], c='r', marker='o')  
plt.scatter(x1[class1], x2[class1], c='b', marker='x')  
plt.xlabel('exam1')  
plt.ylabel('exam2')  
  
# 可视化二阶决策边界  
  
# 定义exam1和exam2的范围,为了画网格  
x1_min, x1_max = x1.min() - 1, x1.max() + 1  
x2_min, x2_max = x2.min() - 1, x2.max() + 1  
  
# 生成网格数据  
xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max, 500),  
                       np.linspace(x2_min, x2_max, 500))  
  
# 计算每个点的决策边界值  
z = (theta0 +  
     theta1 * xx1 +  
     theta2 * xx2 +  
     theta3 * xx1 ** 2 +  
     theta4 * xx2 ** 2 +  
     theta5 * xx1 * xx2)  
  
# 绘制样本点  
plt.scatter(x1[class0], x2[class0], c='r', label='Not Pass', marker='o')  
plt.scatter(x1[class1], x2[class1], c='b', label='Pass', marker='x')  
  
# 绘制决策边界  
plt.contour(xx1, xx2, z, levels=[0], colors='g')  
  
# 添加标签和图例  
plt.xlabel('Exam1 Score')  
plt.ylabel('Exam2 Score')  
plt.legend()  
plt.title('Decision Boundary')  
plt.show()
  • 网格生成 (np.meshgrid):生成 exam1exam2 值的坐标网格,用于计算每一个点的决策值
  • 决策值计算 (z)z 是决策函数的值,基于 logistic 回归的系数和截距
  • 等高线画图 (plt.contour)plt.contour() 方法可以绘制出特定值(比如 0 对应决策边界)的等高线

输出图片:
请添加图片描述

可以看到,这个决策边界的误判率低了很多。下面我们通过计算准确率来定量分析。

Step 7: 计算准确率

# 计算准确率  
from sklearn.metrics import accuracy_score  
accuracy = accuracy_score(y, prediction)  
print(f'Accuracy: {accuracy}')

输出:

Accuracy: 1.0

百分百的正确率说明我们这个模型很成功。


http://www.kler.cn/a/578876.html

相关文章:

  • 批量合并 Word 文档,支持合并成一个 Word,也支持按文件夹合并
  • 【贪心算法】柠檬水找零
  • 6.聊天室环境安装 - Ubuntu22.04 - elasticsearch(es)的安装和使用
  • 智科 机器学习毕业设计题目指导
  • 通义万相2.1开源版本地化部署攻略,生成视频再填利器
  • MongoDB winx64 msi包安装详细教程
  • 深入剖析Android Service:原理、生命周期与实战应用
  • 点云从入门到精通技术详解100篇-基于深度学习的三维点云分类分割
  • 实战1. 利用Pytorch解决 CIFAR 数据集中的图像分类为 10 类的问题
  • Codeforces Round 305 (Div. 1) C. Mike and Foam 容斥原理、质因数分解
  • ACE协议学习1
  • 【python爬虫】酷狗音乐爬取
  • JavaWeb后端基础(7)AOP
  • 用K8S部署Milvus服务
  • 2025-3-9 leetcode刷题情况(贪心算法--序列问题)
  • 【QT5 Widgets示例】记事本:(一)项目创建
  • 基于PyTorch的深度学习3——非标量反向传播
  • Linux下的shell指令(二)
  • 计算机三级网络技术知识点汇总【7】
  • 打破界限!家电行业3D数字化营销,线上线下无缝对接