多元线性和多项式回归

多元线性和多项式回归

上一个博客 我们说了一元线性回归,那么来看一下多元线性回归
一元函数的公式是
在这里插入图片描述

而多元函数的公式:
在这里插入图片描述
其实就是相当于位置参数的变量都增多了,我们的解决办法依旧可以使用我们一元线性回归当中的代价函数和梯度下降算法。
代价函数依旧是:
在这里插入图片描述

梯度下降算法为:
我们可以看到,有多少个参数变量,我们就都给他构造出来,只是比一元线性回归中多一些参数
在这里插入图片描述
直接上代码:

先导入包:
import numpy as np
from numpy import genfromtxt
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D  

最后一个包是构造3D图像所需要导入的包

处理数据:
# 读入数据
data = genfromtxt(r"Delivery.csv",delimiter=',')
print(data)
# 切分数据
x_data = data[:,:-1]  # 相当于坐标
y_data = data[:,-1]   # 相当于label
print(x_data)
print(y_data)
构造代价函数和梯度下降算法:
# 设置学习率
lr = 0.0001
# 设置参数
theta0 = 0
theta1 = 0
theta2 = 0

#最大迭代次数
epochs = 1000

# 设置代价函数
def compute_error(theta0,theta1,theta2,x_data,t_data):
    totalerror = 0
    for i in range(0,len(x_data)):
        totalerror += (y_data[i] - (theta0 + theta1 * x_data[i,0] + theta2 * x_data[i,1])) ** 2
    return totalerror/float(len(x_data))

def gradient_descent_runner(x_data, y_data, theta0, theta1, theta2, lr, epochs):
    m = float(len(x_data))
    for i in range(epochs):
        theta0_1 = 0
        theta1_1 = 0
        theta2_1 = 0
        for j in range(0,len(x_data)):
            theta0_1 += (1/m) * ((theta0 + theta1 * x_data[j,0] + theta2 * x_data[j,1]) - y_data[j])
            theta1_1 += (1/m) * (x_data[j,0]) * ((theta0 + theta1 * x_data[j,0] + theta2 * x_data[j,1]) - y_data[j])
            theta2_1 += (1/m) * (x_data[j,1]) * ((theta0 + theta1 * x_data[j,0] + theta2 * x_data[j,1]) - y_data[j])
        theta0 = theta0 - (lr*theta0_1)
        theta1 = theta1 - (lr*theta1_1)
        theta2 = theta2 - (lr*theta2_1)
        return theta0, theta1, theta2
最后使用函数回归画出我们想要的图形:
theta0, theta1, theta2 = gradient_descent_runner(x_data, y_data, theta0, theta1, theta2, lr, epochs)

ax = plt.figure().add_subplot(111,projection = '3d')
ax.scatter(x_data[:,0],x_data[:,1],y_data,c='r',marker='o',s=100)
x0 = x_data[:,0]
x1 = x_data[:,1]

x0,x1 = np.meshgrid(x0,x1)
z = theta0 + theta1 * x0 + theta2 * x1

ax.plot_surface(x0,x1,z)

ax.set_xlabel('Miles')  
ax.set_ylabel('Num of Deliveries')  
ax.set_zlabel('Time')  

plt.show()

我们最后画出来的3D模型为:
在这里插入图片描述

用sklearn 实现:

导入包:
import numpy as np
from numpy import genfromtxt
from sklearn import linear_model
import matplotlib.pyplot as plt  
from mpl_toolkits.mplot3d import Axes3D  
读取并处理数据:
# 读入数据 
data = genfromtxt(r"Delivery.csv",delimiter=',')
print(data)
# 切分数据
x_data = data[:,:-1]
y_data = data[:,-1]
创建模型
model = linear_model.LinearRegression()
model.fit(x_data, y_data)

此时model.intercept_存储的相当于截距参数,而model.coef_存储的是含参系数值

画图
ax = plt.figure().add_subplot(111, projection = '3d') 
ax.scatter(x_data[:,0], x_data[:,1], y_data, c = 'r', marker = 'o', s = 100) #点为红色三角形  
x0 = x_data[:,0]
x1 = x_data[:,1]
# 生成网格矩阵
x0, x1 = np.meshgrid(x0, x1)
# z = model.intercept_ + x0*model.coef_[0] + x1*model.coef_[1]
# 画3D图
ax.plot_surface(x0, x1, model.predict(x0,x1))
#设置坐标轴  w
ax.set_xlabel('Miles')  
ax.set_ylabel('Num of Deliveries')  
ax.set_zlabel('Time')  
  
#显示图像  
plt.show()  

多项式回归

我们之前所构造出来的都是直线或者是超平面,但是对于下面的散点集,我们使用直线就不会非常吻合的构造出所有点所要表达的趋势,所以我们这里需要的是一个多项式表达的曲线或者超曲面。
在这里插入图片描述
曲线所达到的效果更好
在这里插入图片描述
所以我们构造是形如下面的函数
在这里插入图片描述
对于多项式问题我们直接使用sklearn运行代码:

导入包:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
导入并处理数据:
data = np.genfromtxt("job.csv", delimiter=",")
x_data = data[1:,1]
y_data = data[1:,2]
x_data = x_data[:,np.newaxis]
y_data = y_data[:,np.newaxis]
创建并拟合模型
model = LinearRegression()
model.fit(x_data, y_data)
此时画出的图像为:

在这里插入图片描述
是一元线性的直线,那么我们想要曲线来表示的话:

# 定义多项式回归,degree的值可以调节多项式的特征
poly_reg  = PolynomialFeatures(degree=9) 
# 特征处理在这里插入图片描述

x_poly = poly_reg.fit_transform(x_data)
# 定义回归模型
lin_reg = LinearRegression()
# 训练模型
lin_reg.fit(x_poly, y_data)

再次画图:

# 画图
plt.plot(x_data, y_data, 'b.')
plt.plot(x_data, lin_reg.predict(poly_reg.fit_transform(x_data)), c='r')  # poly_reg.fit_transform(x_data) 预测前必须得做特征处理
plt.title('Truth or Bluff (Polynomial Regression)')
plt.xlabel('Position level')
plt.ylabel('Salary')
plt.show()

在这里插入图片描述

这个曲线是由一段一段的线段组成的,如果我们想要连续曲折圆滑的曲线就需要np.linspace生成等间隔数列这样就比较圆滑了。

plt.plot(x_data, y_data, 'b.')
x_test = np.linspace(1,10,100)
x_test = x_test[:,np.newaxis]
plt.plot(x_test, lin_reg.predict(poly_reg.fit_transform(x_test)), c='r')
plt.title('Truth or Bluff (Polynomial Regression)')
plt.xlabel('Position level')
plt.ylabel('Salary')
plt.show()

在这里插入图片描述

在这里插入图片描述

  • 2
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值