机器学习 - 多项式回归

多项式回归(Polynomial Regression)

如果您的数据点显然不适合线性回归(穿过数据点之间的直线),那么多项式回归可能是理想的选择。

像线性回归一样,多项式回归使用变量 x 和 y 之间的关系来找到绘制数据点线的最佳方法。

多项式回归 - 图1

工作原理

Python 有一些方法可以找到数据点之间的关系并画出多项式回归线。我们将向您展示如何使用这些方法而不是通过数学公式。

在下面的例子中,我们注册了 18 辆经过特定收费站的汽车。

我们已经记录了汽车的速度和通过时间(小时)。

x 轴表示一天中的小时,y 轴表示速度:

实例

首先绘制散点图:

  1. import matplotlib.pyplot as plt
  2.  
  3. x = [1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
  4. y = [100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]
  5.  
  6. plt.scatter(x, y)
  7. plt.show()

结果:

多项式回归 - 图2

实例

导入 numpy 和 matplotlib,然后画出多项式回归线:

  1. import numpy
  2. import matplotlib.pyplot as plt
  3.  
  4. x = [1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
  5. y = [100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]
  6.  
  7. mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))
  8.  
  9. myline = numpy.linspace(1, 22, 100)
  10.  
  11. plt.scatter(x, y)
  12. plt.plot(myline, mymodel(myline))
  13. plt.show()

结果:

多项式回归 - 图3

例子解释

导入所需模块:

  1. import numpy
  2. import matplotlib.pyplot as plt

创建表示 x 和 y 轴值的数组:

  1. x = [1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
  2. y = [100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]

NumPy 有一种方法可以让我们建立多项式模型:

  1. mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))

然后指定行的显示方式,我们从位置 1 开始,到位置 22 结束:

  1. myline = numpy.linspace(1, 22, 100)

绘制原始散点图:

  1. plt.scatter(x, y)

画出多项式回归线:

  1. plt.plot(myline, mymodel(myline))

显示图表:

  1. plt.show()

R-Squared

重要的是要知道 x 轴和 y 轴的值之间的关系有多好,如果没有关系,则多项式回归不能用于预测任何东西。

该关系用一个称为 r 平方( r-squared)的值来度量。

r 平方值的范围是 0 到 1,其中 0 表示不相关,而 1 表示 100% 相关。

Python 和 Sklearn 模块将为您计算该值,您所要做的就是将 x 和 y 数组输入:

实例

我的数据在多项式回归中的拟合度如何?

  1. import numpy
  2. from sklearn.metrics import r2_score
  3.  
  4. x = [1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
  5. y = [100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]
  6.  
  7. mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))
  8.  
  9. print(r2_score(y, mymodel(x)))

注释:结果 0.94 表明存在很好的关系,我们可以在将来的预测中使用多项式回归。

预测未来值

现在,我们可以使用收集到的信息来预测未来的值。

例如:让我们尝试预测在晚上 17 点左右通过收费站的汽车的速度:

为此,我们需要与上面的实例相同的 mymodel 数组:

  1. mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))

实例

预测下午 17 点过车的速度:

  1. import numpy
  2. from sklearn.metrics import r2_score
  3.  
  4. x = [1,2,3,5,6,7,8,9,10,12,13,14,15,16,18,19,21,22]
  5. y = [100,90,80,60,60,55,60,65,70,70,75,76,78,79,90,99,99,100]
  6.  
  7. mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))
  8.  
  9. speed = mymodel(17)
  10. print(speed)

该例预测速度为 88.87,我们也可以在图中看到:

多项式回归 - 图4

糟糕的拟合度?

让我们创建一个实例,其中多项式回归不是预测未来值的最佳方法。

实例

x 和 y 轴的这些值会导致多项式回归的拟合度非常差:

  1. import numpy
  2. import matplotlib.pyplot as plt
  3.  
  4. x = [89,43,36,36,95,10,66,34,38,20,26,29,48,64,6,5,36,66,72,40]
  5. y = [21,46,3,35,67,95,53,72,58,10,26,34,90,33,38,20,56,2,47,15]
  6.  
  7. mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))
  8.  
  9. myline = numpy.linspace(2, 95, 100)
  10.  
  11. plt.scatter(x, y)
  12. plt.plot(myline, mymodel(myline))
  13. plt.show()

结果:

多项式回归 - 图5

r-squared 值呢?

实例

您应该得到一个非常低的 r-squared 值。

  1. import numpy
  2.  
  3. from sklearn.metrics import r2_score
  4.  
  5. x = [89,43,36,36,95,10,66,34,38,20,26,29,48,64,6,5,36,66,72,40]
  6. y = [21,46,3,35,67,95,53,72,58,10,26,34,90,33,38,20,56,2,47,15]
  7.  
  8. mymodel = numpy.poly1d(numpy.polyfit(x, y, 3))
  9.  
  10. print(r2_score(y, mymodel(x)))

结果:0.00995 表示关系很差,并告诉我们该数据集不适合多项式回归。