基本形式

上文中,大叔说道了线性回归,线性回归是个非常直观又简单的模型,但是很多时候,数据的分布并不是线性的,如:

如果我们想用高次多项式拟合上面的数据应该如何实现呢?其实很简单,设假设函数为

\[y = \theta_0 + \theta_1x + \theta_2x^2 \tag{1}
\]

与之相像的线性函数为

\[y = \theta_0 + \theta_1x_1 + \theta_2x_2 \tag{2}
\]

观察(1)式和(2)式,其实我们只要把(1)式中的\(x\)看作是(2)式中的\(x_1\),(1)式中的\(x^2\)看作是(2)式中的\(x_2\),就可以把拟合一个关于\(x\)的二次函数的任务转换为拟合一个关于\(x_1\)和\(x_2\)的线性函数的任务,这样问题就简单了,关于如何拟合一个线性函数请参考大叔学ML第二:线性回归

现在,我们用正规方程来拟合线性函数,正规方程形如:\(\vec\theta=(X^TX)^{-1}X^T\vec{y}\),关键在于构建特征矩阵\(X\),显然,特征矩阵的第一列\(\vec x_0\)全为1,第二列\(\vec x_1\)由样本中的属性\(x\)构成,第三列\(\vec x_2\)由样本中的属性\(x\)的平方构成。

小试牛刀

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. ''' 创建样本数据如下:'''
  4. X = np.arange(0, 10, 0.1) # 产生100个样本
  5. noise = np.random.randint(-5, 5, (1, 100))
  6. Y = 10 + 2 * X + 3 * X * X + noise # 100个样本对应的标记
  7. '''下面用正规方程求解theta'''
  8. X0 = np.ones((100, 1)) # x0赋值1
  9. X1 = X.reshape(100, 1) # x1
  10. X2 = X1 * X1 #x2为x1的平方
  11. newX = np.hstack((X0, X1, X2)) # 构建一个特征矩阵
  12. newY = Y.reshape(100, 1) # 把标记转置一下
  13. theta = np.dot(np.dot(np.linalg.pinv(np.dot(newX.T, newX)), newX.T), newY)
  14. print(theta)
  15. '''绘制'''
  16. plt.xlabel('$X$')
  17. plt.ylabel('$Y$')
  18. plt.scatter(X, Y, marker='.') # 原始数据
  19. plt.plot(X, theta[0] + theta[1] * X + theta[2] * X * X, color = 'r') # 绘制我们拟合得到的函数
  20. plt.show()

运行结果:

简直完美。

再试牛刀

上面我们只是拟合了一个一元函数(样本数据仅包含一个元素),下面我们来尝试拟合一个二元函数。假设我们有一堆样本,每个样本有两个元素,看起来大概是这样:

我们欲拟合一个函数形式如下:

\[y = \theta_0 + \theta_1x_1 + \theta_2x_2 + \theta_3x_1^2 + \theta_4x_1x_2 + \theta_5x_2^2
\]

同样,对比与之相像的线性函数:

\[y = \theta_0 + \theta_1x_1 + \theta_2x_2 + \theta_3x_3 + \theta_4x_4+ \theta_5x_5
\]

我们建立如下对应关系:

高次多项式 线性式
\(x_0=1\) \(x_0=1\)
\(x_1\) \(x_1\)
\(x_2\) \(x_2\)
\(x_1^2\) \(x_3\)
\(x_1x_2\) \(x_4\)
\(x_2^2\) \(x_5\)

编程如下:

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from mpl_toolkits.mplot3d import Axes3D
  4. # 测试用多项式
  5. def ploy(X1, X2, *theta):
  6. noise = np.random.randint(-5, 5, (1, 10))
  7. Y = theta[0] + theta[1] * X1 + theta[2] * X2 + theta[3] * X1**2 + theta[4] * X1 * X2 + theta[5] * X2**2 + noise # 10个样本对应的标记
  8. return Y
  9. ''' 创建样本数据如下 '''
  10. X1 = np.arange(0, 10, 1) # 产生10个样本的第一个属性
  11. X2 = np.arange(5, 15, 1) # 产生10个样本的第二个属性
  12. Y = ploy(X1, X2, 1, 2, 3, 4, 5, 6)
  13. '''构建特征矩阵 '''
  14. newX0 = np.ones((10, 1))
  15. newX1 = np.reshape(X1, (10, 1))
  16. newX2 = np.reshape(X2, (10, 1))
  17. newX3 = np.reshape(X1**2, (10, 1))
  18. newX4 = np.reshape(X1 * X2, (10, 1))
  19. newX5 = np.reshape(X2**2, (10, 1))
  20. newX = np.hstack((newX0, newX1, newX2, newX3, newX4, newX5)) # 特征矩阵
  21. '''用正规方程拟合 '''
  22. newY = Y.reshape(10, 1) #把标记转置一下
  23. result = np.dot(np.dot(np.linalg.pinv(np.dot(newX.T, newX)), newX.T), newY)
  24. theta = tuple(result.reshape((1, 6))[0].tolist())
  25. print(theta)
  26. '''绘制 '''
  27. fig = plt.figure()
  28. ax = Axes3D(fig)
  29. ax.set_xlabel('$X_1$')
  30. ax.set_ylabel('$X_2$')
  31. ax.set_zlabel('$Y$')
  32. AxesX1, AxesX2 = np.meshgrid(X1, X2)
  33. AxesY = ploy(AxesX1, AxesX2, 1, 2, 3, 4, 5, 6) # 原始数据
  34. ax.scatter(AxesX1, AxesX2, AxesY)
  35. regressionY = ploy(AxesX1, AxesX2, *theta) # 用拟合出来的theta计算数据
  36. ax.plot_surface(AxesX1, AxesX2, regressionY, color='r', alpha='0.5')
  37. plt.show()

运行结果:

调用类库

我们可以调用sklean中模块PolynomialFeatures自动生成特征矩阵,而无需自己创建,计算参数\(\vec\theta\)也不用自己写,而是使用sklean中的模块linear_model

  1. import numpy as np
  2. import matplotlib.pyplot as plt
  3. from sklearn.preprocessing import PolynomialFeatures
  4. from sklearn import linear_model
  5. from mpl_toolkits.mplot3d import Axes3D
  6. # 测试用多项式
  7. def ploy(X1, X2, *theta):
  8. noise = np.random.randint(-5, 5, (1, 10))
  9. Y = theta[0] + theta[1] * X1 + theta[2] * X2 + theta[3] * X1**2 + theta[4] * X1 * X2 + theta[5] * X2**2 + noise # 10个样本对应的标记
  10. return Y
  11. ''' 创建样本数据如下 '''
  12. X1 = np.arange(0, 10, 1) # 产生10个样本的第一个属性
  13. X2 = np.arange(5, 15, 1) # 产生10个样本的第二个属性
  14. Y = ploy(X1, X2, 1, 2, 3, 4, 5, 6)
  15. X = np.vstack((X1, X2)).T
  16. Y = Y.reshape((10, 1))
  17. '''构建特征矩阵 '''
  18. poly = PolynomialFeatures(2)
  19. features_matrix = poly.fit_transform(X)
  20. names = poly.get_feature_names()
  21. ''' 拟合'''
  22. regr = linear_model.LinearRegression()
  23. regr.fit(features_matrix, Y)
  24. theta = tuple(regr.intercept_.tolist() + regr.coef_[0].tolist())
  25. print(theta)
  26. '''绘制 '''
  27. fig = plt.figure()
  28. ax = Axes3D(fig)
  29. ax.set_xlabel('$X_1$')
  30. ax.set_ylabel('$X_2$')
  31. ax.set_zlabel('$Y$')
  32. AxesX1, AxesX2 = np.meshgrid(X1, X2)
  33. AxesY = ploy(AxesX1, AxesX2, 1, 2, 3, 4, 5, 6) # 原始数据
  34. ax.scatter(AxesX1, AxesX2, AxesY)
  35. regressionY = ploy(AxesX1, AxesX2, *theta) # 用拟合出来的theta计算数据
  36. ax.plot_surface(AxesX1, AxesX2, regressionY, color='r', alpha='0.5')
  37. plt.show()

运行结果如下:

感觉还不让自己写的代码拟合的好,可能是大叔的样本太少?或者是其他什么原因导致。大叔现在功力还不深,等有空了会看看这些类库的源码。

至于何时必须自己编码而不是调用类库,大叔在上文末尾做了一点总结,不一定对,欢迎指正。祝大家周末愉快。

大叔学ML第三:多项式回归的更多相关文章

  1. 大叔学ML第五:逻辑回归

    目录 基本形式 代价函数 用梯度下降法求\(\vec\theta\) 扩展 基本形式 逻辑回归是最常用的分类模型,在线性回归基础之上扩展而来,是一种广义线性回归.下面举例说明什么是逻辑回归:假设我们有 ...

  2. 大叔学ML第四:线性回归正则化

    目录 基本形式 梯度下降法中应用正则化项 正规方程中应用正则化项 小试牛刀 调用类库 扩展 正则:正则是一个汉语词汇,拼音为zhèng zé,基本意思是正其礼仪法则:正规:常规:正宗等.出自<楚 ...

  3. 大叔学ML第二:线性回归

    目录 基本形式 求解参数\(\vec\theta\) 梯度下降法 正规方程导法 调用函数库 基本形式 线性回归非常直观简洁,是一种常用的回归模型,大叔总结如下: 设有样本\(X\)形如: \[\beg ...

  4. 大叔学ML第一:梯度下降

    目录 原理 实践一:求\(y = x^2 - 4x + 1\)的最小值 实践二:求\(z = x^2 + y^2 + 5\)的最小值 问答时间 原理 梯度下降是一个很常见的通过迭代求解函数极值的方法, ...

  5. 跟vczh看实例学编译原理——三:Tinymoe与无歧义语法分析

    文章中引用的代码均来自https://github.com/vczh/tinymoe.   看了前面的三篇文章,大家应该基本对Tinymoe的代码有一个初步的感觉了.在正确分析"print ...

  6. [老老实实学WCF] 第三篇 在IIS中寄存服务

    老老实实学WCF 第三篇 在IIS中寄宿服务 通过前两篇的学习,我们了解了如何搭建一个最简单的WCF通信模型,包括定义和实现服务协定.配置服务.寄宿服务.通过添加服务引用的方式配置客户端并访问服务.我 ...

  7. 从零开始学Xamarin.Forms(三) Android 制作启动画面

    原文:从零开始学Xamarin.Forms(三) Android 制作启动画面     Xamarin.Forms 在启动的时候相当慢,必须添加一个启动界面,步骤如下: 1.将启动画面的图片命名为:s ...

  8. 跟我学SpringCloud | 第三篇:服务的提供与Feign调用

    跟我学SpringCloud | 第三篇:服务的提供与Feign调用 上一篇,我们介绍了注册中心的搭建,包括集群环境吓注册中心的搭建,这篇文章介绍一下如何使用注册中心,创建一个服务的提供者,使用一个简 ...

  9. 2017-2018-1 我爱学Java 第三周 作业

    Team Presentation 团队展示 队员学号 队名 团队项目描述 队员风采 团队首次合照 团队的特色描述 团队初步合作 前两周合作过程中的优缺点 如何改进 团队选题 确立,建立和初步熟悉团队 ...

随机推荐

  1. python添加post请求

    1.进入python的安装目录下的Scripts目录 ,利用pip install requests安装第三方模块 2.火狐浏览器自带firebug,打开http://10.148.111.111/q ...

  2. C#使用CefSharp开源库开发Chrome 浏览器

    一.介绍        这个东西我以前没有接触过,但是公司项目里面有用到这个东西,所以就顺便研究一下.今天只是做了 WinForm 的测试,有时间了在试试 WPF 是如何实现的.刚开始一塌糊涂,有点麻 ...

  3. Bar 柱状图

    1.生成基本图形 向上向下分别生成12个数据,X为 0 到 11 的整数 ,Y是相应的均匀分布的随机数据. 使用的函数是plt.bar,参数为X和Y: import matplotlib.pyplot ...

  4. File初识和练习

    目录 File类 File对象的构建 File文件名.路径的获取 文件的状态 文件的其他操作 创建文件夹 列出下一级 实战练习1:列出子孙级目录及名称 实战练习2:列出文件及其子孙文件的总大小 实战练 ...

  5. Hishop数据库根据产品ProductID取产品规格

    #region 产品规格 public static string GetSku(int ProductId) { DataTable skus =GetSkus(ProductId); // Res ...

  6. BFC和清除浮动

    1.清浮动(不考虑兼容的话这一项够用了): .clear:after{ content:''; display:block; clear:both; } 兼容ie6或7 加一个 .clear{ *zo ...

  7. 解决win系统无法安装.NET Framework 4.0 4.6 原因是HRESULT0xc8000222

    1.开始----- 运行------- cmd ----- 键入net stop WuAuServ回车(停止windows update服务) 2.开始----- 运行----键入%windir%回车 ...

  8. IEC2017级_1-2班2次博客作业成绩说明

    一.博客作业内容 2018上IEC计算机高级语言(C)作业 第2次作业 二.评分规则说明 1.程序调试题,要描述出调试所遇到问题及修改内容,并表述清楚程序功能.流程图不规范的会减1-2分: 2.知识点 ...

  9. mongodb分组排序

    @Override public MessageDto getCheckInMembersByFlight(String fltDt, String fltNr, String channel,Str ...

  10. Effective C++ 笔记:条款 33 避免继承导致的名称遮掩

    Avoid hiding inherited names 作用域(scopes)所带来的名称二义性,c++编译器会寻找指涉(refer to)的对象并实现名称遮掩规则(name-hiding rule ...