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

打印 上一主题 下一主题

主题 1015|帖子 1015|积分 3045

喜好的话别忘了点赞、收藏加关注哦(关注即可查看全文),对接下来的教程有兴趣的可以关注专栏。谢谢喵!(=・ω・=)

1.10.1. 一些准备工作

这篇文章我们会在 1.9. 逻辑回归实战(进阶) 的底子上再进一步,讲一下如何找(类)圆形的决策界限。
圆形的回归界限大部分时候都会是二阶的,但有的时候数据很复杂,就会需要更多阶,本文涉及的就是这部分。
接下来,请你确保你的Python情况中有pandas、matplotlib、scikit-learn和numpy这几个包,如果没有,请在终端输入指令以下载和安装:
  1. pip install pandas matplotlib scikit-learn numpy
复制代码
我把.csv数据文件放在GitCode上了,点击链接即可下载。
训练数据有3栏:test1、test2和pass_or_not。test1和test2里填写的是芯片在两次差别的测试中的数值,pass_or_not代表终极芯片是否合格,合格是1,不合格是0。我们的目的就是训练逻辑回归模型去找到pass_or_not的决策界限。
下载好后把它移到你的Python项目文件夹里即可。
1.10.2. 写二阶决策界限的代码

实在这一部分与上一篇文章 1.9. 逻辑回归实战(进阶) 的步骤一样,所以这里我就速讲一遍。
Step 1: 读取数据

  1. # 读取数据  
  2. import pandas as pd  
  3. data = pd.read_csv('exam_results.csv')  
  4.   
  5. print(data.head())
复制代码
输出:
  1.        test1      test2  pass_or_not
  2. 0  62.472407  81.889703            1
  3. 1  97.042858  72.165782            1
  4. 2  83.919637  58.571657            1
  5. 3  75.919509  88.827701            1
  6. 4  49.361118  81.083870            1
复制代码
然后我们还可以利用matplotlib对数据举行可视化:
  1. # 读取数据  
  2. import pandas as pd  
  3. data = pd.read_csv('Chip_Test_Data.csv')  
  4.   
  5. # 可视化  
  6. import matplotlib.pyplot as plt  
  7.   
  8. x1 = data.loc[:, 'test1'].to_numpy()  
  9. x2 = data.loc[:, 'test2'].to_numpy()  
  10. y = data.loc[:, 'pass_or_not'].to_numpy()  
  11.   
  12. class0 = (y == 0)  
  13. class1 = (y == 1)  
  14.   
  15. plt.scatter(x1[class0], x2[class0], c='r', marker='o')  
  16. plt.scatter(x1[class1], x2[class1], c='b', marker='x')  
  17. plt.xlabel('test1')  
  18. plt.ylabel('test2')  
  19. plt.show()
复制代码
输出图片:

Step 2: 给x和y赋值

我们要首先明确x和y代表什么:


  • y是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​+θ1​X1​+θ2​X2​+θ3​X12​+θ4​X22​+θ5​X1​X2​=0
有x_12、`x_2`2、X_1 * x_2这些项。所以我们得把这些项打包在字典里,再转为模型能利用的DataFrame格式给它利用。
  1. # 给x和y赋值  
  2. y = data.loc[:, 'pass_or_not']  
  3. x1 = data.loc[:, 'test1']  
  4. x2 = data.loc[:, 'test2']  
  5. x = {  
  6.     'x1': x1,  
  7.     'x2': x2,  
  8.     'x1^2': x1 ** 2,  
  9.     'x2^2': x2 ** 2,  
  10.     'x1*x2': x1 * x2,  
  11. }  
  12.   
  13. x = pd.DataFrame(x)  
  14. print(x.head())
复制代码
输出:
  1.           x1         x2         x1^2         x2^2        x1*x2
  2. 0  62.472407  81.889703  3902.801653  6705.923431  5115.846856
  3. 1  97.042858  72.165782  9417.316363  5207.900089  7003.173761
  4. 2  83.919637  58.571657  7042.505392  3430.639001  4915.312163
  5. 3  75.919509  88.827701  5763.771855  7890.360497  6743.755464
  6. 4  49.361118  81.083870  2436.520012  6574.594031  4002.390527
复制代码
我们也可以利用上一篇文章说过的简单的方法来生成这个字典:
  1. from sklean.preprocessing import PolynomialFeatures
  2. poly = PolynomialFeatures(degree = 2)
  3. x = data.drop(['exam3_pass_or_not'], axis = 1)
  4. x = poly.fit_transform(x)
复制代码
Step 3: 训练模型

  1. # 训练模型  
  2. from sklearn.linear_model import LogisticRegression  
  3. model = LogisticRegression()  
  4. model.fit(x, y)
复制代码
Step 4: 获取决策界限

  1. # 获取决策边界  
  2. theta1, theta2, theta3, theta4, theta5 = model.coef_[0]  
  3. theta0 = model.intercept_[0]
  4. 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​+θ1​X1​+θ2​X2​+θ3​X12​+θ4​X22​+θ5​X1​X2​=0
输出:
  1. Decision Boundary: -1.55643301596937 + 0.0687019597360078x1 + 0.04589152052058807x2 + -0.001380801702595371x1^2 + -0.0012980632178920715x2^2 + 0.0018080315329989266x1*x2
复制代码
Step 5: 获取预测值与计算准确率

  1. # 获取预测值与计算准确率  
  2. prediction = model.predict(x)  
  3. from sklearn.metrics import accuracy_score  
  4. print(f"accuracy: {accuracy_score(y, prediction)}")
复制代码
输出:
  1. accuracy: 0.842
复制代码
Step 6: 可视化决策界限

  1. # 可视化  
  2. import matplotlib.pyplot as plt  
  3. import numpy as np  
  4.   
  5. x1 = x1.to_numpy()  
  6. x2 = x2.to_numpy()  
  7. y = y.to_numpy()  
  8.   
  9. class0 = (y == 0)  
  10. class1 = (y == 1)  
  11.   
  12. plt.scatter(x1[class0], x2[class0], c='r', marker='o')  
  13. plt.scatter(x1[class1], x2[class1], c='b', marker='x')  
  14. plt.xlabel('exam1')  
  15. plt.ylabel('exam2')  
  16.   
  17. # 可视化二阶决策边界  
  18.   
  19. # 定义exam1和exam2的范围,为了画网格  
  20. x1_min, x1_max = x1.min() - 1, x1.max() + 1  
  21. x2_min, x2_max = x2.min() - 1, x2.max() + 1  
  22.   
  23. # 生成网格数据  
  24. xx1, xx2 = np.meshgrid(np.linspace(x1_min, x1_max, 500),  
  25.                        np.linspace(x2_min, x2_max, 500))  
  26.   
  27. # 计算每个点的决策边界值  
  28. z = (theta0 +  
  29.      theta1 * xx1 +  
  30.      theta2 * xx2 +  
  31.      theta3 * xx1 ** 2 +  
  32.      theta4 * xx2 ** 2 +  
  33.      theta5 * xx1 * xx2)  
  34.   
  35. # 绘制样本点  
  36. plt.scatter(x1[class0], x2[class0], c='r', label='Not Pass', marker='o')  
  37. plt.scatter(x1[class1], x2[class1], c='b', label='Pass', marker='x')  
  38.   
  39. # 绘制决策边界  
  40. plt.contour(xx1, xx2, z, levels=[0], colors='g')  
  41.   
  42. # 添加标签和图例  
  43. plt.xlabel('Test1 Score')  
  44. plt.ylabel('Test2 Score')  
  45. plt.legend()  
  46. plt.title('Decision Boundary')  
  47. plt.show()
复制代码
输出图片:

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

实在写三阶决策界限的代码与写二阶的思绪基本同等,就是在给x赋成字典然后转为DataFrame这一块多添加几个字段以符合更高阶的特征:
  1. # 给 x 和 y 赋值  
  2. y = data.loc[:, 'pass_or_not']  
  3. x1 = data.loc[:, 'test1']  
  4. x2 = data.loc[:, 'test2']  
  5.   
  6. # 手动创建高阶特征字典  
  7. x = {  
  8.     'x1': x1,  
  9.     'x2': x2,  
  10.     'x1^2': x1 ** 2,  
  11.     'x2^2': x2 ** 2,  
  12.     'x1*x2': x1 * x2,  
  13.     'x1^3': x1 ** 3,  
  14.     'x2^3': x2 ** 3,  
  15.     'x1^2*x2': (x1 ** 2) * x2,  
  16.     'x1*x2^2': x1 * (x2 ** 2),  
  17. }  
  18.   
  19. # 将特征字典转换为 DataFrame
  20. 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​+θ1​X1​+θ2​X2​+θ3​X12​+θ4​X22​+θ5​X1​X2​+θ6​X13​+θ7​X23​+θ8​X12​X2​+θ9​X1​X22​=0
也可以利用PolynomialFeatures创建字典:
  1. from sklean.preprocessing import PolynomialFeatures
  2. poly = PolynomialFeatures(degree = 3)
  3. x = data.drop(['pass_or_not'], axis = 1)
  4. x = poly.fit_transform(x)
复制代码
别的的部分基本稳定,我把三阶的完整代码贴出来:
  1. # 导入必要模块  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 赋值  
  2. y = data.loc[:, 'pass_or_not']  
  3. x1 = data.loc[:, 'test1']  
  4. x2 = data.loc[:, 'test2']  
  5.   
  6. # 手动创建高阶特征字典  
  7. x = {  
  8.     'x1': x1,  
  9.     'x2': x2,  
  10.     'x1^2': x1 ** 2,  
  11.     'x2^2': x2 ** 2,  
  12.     'x1*x2': x1 * x2,  
  13.     'x1^3': x1 ** 3,  
  14.     'x2^3': x2 ** 3,  
  15.     'x1^2*x2': (x1 ** 2) * x2,  
  16.     'x1*x2^2': x1 * (x2 ** 2),  
  17. }  
  18.   
  19. # 将特征字典转换为 DataFrame
  20. x = pd.DataFrame(x)
  21.     # 第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()
复制代码
输出:
  1. Accuracy: 1.0
复制代码
图片输出:

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

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

吴旭华

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表