【Python机器学习】1.10. 逻辑回归实战(高阶):超多阶(大于2)的逻辑回归

devtools/2025/3/11 8:24:26/

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

1.10.1. 一些准备工作

这篇文章我们会在 1.9. 逻辑回归实战(进阶) 的基础上再进一步,讲一下如何找(类)圆形的决策边界。

圆形的回归边界大部分时候都会是二阶的,但有的时候数据很复杂,就会需要更多阶,本文涉及的就是这部分。

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

pip install pandas matplotlib scikit-learn numpy

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

训练数据有3栏:test1test2pass_or_nottest1test2里填写的是芯片在两次不同的测试中的数值,pass_or_not代表最终芯片是否合格,合格是1,不合格是0。我们的目标就是训练逻辑回归模型去找到pass_or_not的决策边界。

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

1.10.2. 写二阶决策边界的代码

其实这一部分与上一篇文章 1.9. 逻辑回归实战(进阶) 的步骤一样,所以这里我就速讲一遍。

Step 1: 读取数据

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

输出:

       test1      test2  pass_or_not
0  62.472407  81.889703            1
1  97.042858  72.165782            1
2  83.919637  58.571657            1
3  75.919509  88.827701            1
4  49.361118  81.083870            1

然后我们还可以使用matplotlib对数据进行可视化:

python"># 读取数据  
import pandas as pd  
data = pd.read_csv('Chip_Test_Data.csv')  # 可视化  
import matplotlib.pyplot as plt  x1 = data.loc[:, 'test1'].to_numpy()  
x2 = data.loc[:, 'test2'].to_numpy()  
y = data.loc[:, '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('test1')  
plt.ylabel('test2')  
plt.show()

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

Step 2: 给xy赋值

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

  • ypass_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格式给它使用。

python"># 给x和y赋值  
y = data.loc[:, 'pass_or_not']  
x1 = data.loc[:, 'test1']  
x2 = data.loc[:, 'test2']  
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  62.472407  81.889703  3902.801653  6705.923431  5115.846856
1  97.042858  72.165782  9417.316363  5207.900089  7003.173761
2  83.919637  58.571657  7042.505392  3430.639001  4915.312163
3  75.919509  88.827701  5763.771855  7890.360497  6743.755464
4  49.361118  81.083870  2436.520012  6574.594031  4002.390527

我们也可以使用上一篇文章说过的简单的方法来生成这个字典:

python">from sklean.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree = 2)
x = data.drop(['exam3_pass_or_not'], axis = 1)
x = poly.fit_transform(x)

Step 3: 训练模型

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

Step 4: 获取决策边界

python"># 获取决策边界  
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: -1.55643301596937 + 0.0687019597360078x1 + 0.04589152052058807x2 + -0.001380801702595371x1^2 + -0.0012980632178920715x2^2 + 0.0018080315329989266x1*x2

Step 5: 获取预测值与计算准确率

python"># 获取预测值与计算准确率  
prediction = model.predict(x)  
from sklearn.metrics import accuracy_score  
print(f"accuracy: {accuracy_score(y, prediction)}")

输出:

accuracy: 0.842

Step 6: 可视化决策边界

python"># 可视化  
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('Test1 Score')  
plt.ylabel('Test2 Score')  
plt.legend()  
plt.title('Decision Boundary')  
plt.show()

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

你会发现这个图只画了左上和右下的两条线,而左下和右上应该有决策边界的地方却没有。这就是阶数太少导致的拟合不到位,如果我们继续增阶,就会拟合的更好。

1.10.3. 三阶的决策边界

其实写三阶决策边界的代码与写二阶的思路基本一致,就是在给x赋成字典然后转为DataFrame这一块多添加几个字段以符合更高阶的特征:

python"># 给 x 和 y 赋值  
y = data.loc[:, 'pass_or_not']  
x1 = data.loc[:, 'test1']  
x2 = data.loc[:, 'test2']  # 手动创建高阶特征字典  
x = {  'x1': x1,  'x2': x2,  'x1^2': x1 ** 2,  'x2^2': x2 ** 2,  'x1*x2': x1 * x2,  'x1^3': x1 ** 3,  'x2^3': x2 ** 3,  'x1^2*x2': (x1 ** 2) * x2,  'x1*x2^2': x1 * (x2 ** 2),  
}  # 将特征字典转换为 DataFrame
x = pd.DataFrame(x)

这样字典里的每个字段都能对应到3阶g(x)的每一项:
g ( x ) = θ 0 + θ 1 X 1 + θ 2 X 2 + θ 3 X 1 2 + θ 4 X 2 2 + θ 5 X 1 X 2 + θ 6 X 1 3 + θ 7 X 2 3 + θ 8 X 1 2 X 2 + θ 9 X 1 X 2 2 = 0 g(x) = \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 + \theta_6 X_1^3 + \theta_7 X_2^3 + \theta_8 X_1^2 X_2 + \theta_9 X_1 X_2^2 = 0 g(x)=θ0+θ1X1+θ2X2+θ3X12+θ4X22+θ5X1X2+θ6X13+θ7X23+θ8X12X2+θ9X1X22=0

也可以使用PolynomialFeatures创建字典:

python">from sklean.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree = 3)
x = data.drop(['pass_or_not'], axis = 1)
x = poly.fit_transform(x)

其余的部分基本不变,我把三阶的完整代码贴出来:

python"># 导入必要模块  
import numpy as np  
import pandas as pd  
import matplotlib.pyplot as plt  
from sklearn.linear_model import LogisticRegression  
from sklearn.metrics import accuracy_score  # 第1部分:读取数据  
file_path = "Chip_Test_Data.csv"  
data = pd.read_csv(file_path)  # 给 x 和 y 赋值  
y = data.loc[:, 'pass_or_not']  
x1 = data.loc[:, 'test1']  
x2 = data.loc[:, 'test2']  # 手动创建高阶特征字典  
x = {  'x1': x1,  'x2': x2,  'x1^2': x1 ** 2,  'x2^2': x2 ** 2,  'x1*x2': x1 * x2,  'x1^3': x1 ** 3,  'x2^3': x2 ** 3,  'x1^2*x2': (x1 ** 2) * x2,  'x1*x2^2': x1 * (x2 ** 2),  
}  # 将特征字典转换为 DataFrame
x = pd.DataFrame(x)  # 第3部分:训练逻辑回归模型  
model = LogisticRegression(max_iter=10000)  
model.fit(x, y)  # 获取模型的系数与截距  
theta = model.coef_[0]  
theta0 = model.intercept_[0]  # 获取预测值并计算准确率  
prediction = model.predict(x)  
accuracy = accuracy_score(y, prediction)  
print(f"Accuracy: {accuracy}")  # 第4部分:生成网格,计算决策边界  
# 定义 x1 和 x2 的范围,用于绘制网格决策边界  
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))  # 使用生成网格计算多项式特征  
grid_x = {  'x1': xx1.ravel(),  'x2': xx2.ravel(),  'x1^2': xx1.ravel() ** 2,  'x2^2': xx2.ravel() ** 2,  'x1*x2': xx1.ravel() * xx2.ravel(),  'x1^3': xx1.ravel() ** 3,  'x2^3': xx2.ravel() ** 3,  'x1^2*x2': (xx1.ravel() ** 2) * xx2.ravel(),  'x1*x2^2': xx1.ravel() * (xx2.ravel() ** 2),  
}  grid_x = pd.DataFrame(grid_x)  # 计算每个网格点的预测值  
z = model.predict(grid_x)  
z = z.reshape(xx1.shape)  # 第5部分:可视化  
# 绘制样本点  
class0 = (y == 0)  
class1 = (y == 1)  plt.figure(figsize=(8, 6))  # 绘制 Not Pass 和 Pass 样本点  
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.5], colors='g')  # 添加标签和标题  
plt.xlabel('Test 1 Score')  
plt.ylabel('Test 2 Score')  
plt.legend()  
plt.title('Polynomial Logistic Regression (Degree=3)')  
plt.show()

输出:

Accuracy: 1.0

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

这已经是一个完美的决策边界了!准确率百分百!


http://www.ppmy.cn/devtools/166236.html

相关文章

【愚公系列】《Python网络爬虫从入门到精通》045-Charles的SSL证书的安装

标题详情作者简介愚公搬代码头衔华为云特约编辑,华为云云享专家,华为开发者专家,华为产品云测专家,CSDN博客专家,CSDN商业化专家,阿里云专家博主,阿里云签约作者,腾讯云优秀博主&…

Python可视化——地理空间型图表(自用)

地图信息可视化的实现就是将不可展开的曲面上的地理坐标信息转化为二维平面进行显示,这个过程也叫地图投影(空间三维投影到平面二维) 地图投影的要求:等面积、等角度、等距离。总的来说就是映射到二维平面中的任何点通过比例尺放大…

MAC电脑常用操作

环境:M3芯片 ,macOS15.2 🚀 快捷键 🖥️ 窗口管理 ✅ 退出/进入全屏模式 • 浏览器等应用:⌘ Command Ctrl F ✅ 最小化当前窗口 • ⌘ Command M • 💡 隐藏窗口但保留应用在后台运行 ✅ 关闭当前标…

Kafka×DeepSeek:智能决策破取经八十一难!

《西游记》的故事中,唐僧师徒四人历经九九八十一难,从东土大唐前往西天取经。一路上,火焰山酷热难耐、通天河水位忽高忽低、妖怪神出鬼没…… 现在,唐僧师徒取经路上的种种难题,在KafkaDeepSeek双引擎加持下有了全新解…

统信UOS上AI辅助绘图:用DeepSeek+draw.io生成流程图

原文链接:统信UOS上AI辅助绘图:用DeepSeekdraw.io生成流程图 Hello,大家好啊!今天给大家带来一篇 在统信 UOS 上使用 DeepSeek 生成流程图语法并通过 draw.io 绘制流程图 的文章。在日常开发、运维和文档编写过程中,流…

Python通过RS485串口控制码垛机器人

先看代码,再看后面的说明 import serial import time class PalletizingRobot: def __init__(self, port, baudrate9600, timeout1): self.port port self.baudrate baudrate self.timeout timeout self.serial_conn Non…

【报错】微信小程序预览报错”60001“

1.问题描述 我在微信开发者工具写小程序时,使用http://localhost:8080是可以请求成功的,数据全都可以无报错,但是点击【预览】,用手机扫描二维码浏览时,发现前端图片无返回且报错60001(打开开发者模式查看日…

2025年03月07日Github流行趋势

项目名称:ai-hedge-fund 项目地址url:https://github.com/virattt/ai-hedge-fund项目语言:Python历史star数:12788今日star数:975项目维护者:virattt, seungwonme, KittatamSaisaard, andorsk, arsaboo项目…