多元线性回归原理
多元线性回归表示有多个特征,如X1,X2……
梯度下降法实现多元线性回归
因为是多元线性回归,所以有多个特征,此处用于多元线性回归的数据集(以2个特征为例,该数据集与代码脚本放在同一个目录下)如下:
链接:https://pan.baidu.com/s/1kq31lbZoeqK6m1Pd3l__1g
提取码:drlx
下面用梯度下降法实现多元线性回归,代码如下:
import numpy as np
from numpy import genfromtxt
import matplotlib.pyplot as plt
# 导入Axes3D,用来画3D图
from mpl_toolkits.mplot3d import Axes3D
# 读入数据
data = genfromtxt(r"Delivery.csv",delimiter=',')
print(data)
该段代码是从指定路径中提取文件中的数据,并以逗号为分隔符,提取数据后,输出数据如下:
[[100. 4. 9.3]
[ 50. 3. 4.8]
[100. 4. 8.9]
[100. 2. 6.5]
[ 50. 2. 4.2]
[ 80. 2. 6.2]
[ 75. 3. 7.4]
[ 65. 4. 6. ]
[ 90. 3. 7.6]
[ 90. 2. 6.1]]
接下来对取得的数据进行切分,x_data取所有行,第0个列到最后一个列 (不包括最后一列);y_data取所有行的最后一个列。输出可以看到x_data和y_data里面存放的数据,代码与结果如下:
# 切分数据
x_data = data[:,:-1]
y_data = data[:,-1]
print(x_data)
print(y_data)
x_data表示我们训练的数据,y_data表示我们的标签,输出结果如下:
[[100. 4.]
[ 50. 3.]
[100. 4.]
[100. 2.]
[ 50. 2.]
[ 80. 2.]
[ 75. 3.]
[ 65. 4.]
[ 90. 3.]
[ 90. 2.]]
[9.3 4.8 8.9 6.5 4.2 6.2 7.4 6. 7.6 6.1]
可以看到x_data有2列数据,所以它有2个特征,则有3个参数:theta0,theta1,theta2。根据梯度下降法和代价函数公式来迭代求解三个参数最终的更新值以及最终的代价值,输出结果为:
Staring theta0 = 0,theta1 = 0,theta2 = 0,error = 47.279999999999994
Running…
After1000 iterations theta0 = 0.006971416196678632,theta1 = 0.08021042690771771,theta2 = 0.07611036240566814,error = 0.7731271432218118
代码如下:
# 学习率learning rate
lr = 0.0001
# 参数
theta0 = 0
theta1 = 0
theta2 = 0
# 最大迭代次数
epochs = 1000
# 最小二乘法
def compute_error(theta0,theta1,theta2,x_data,y_data):
totalError = 0
for i in range(0,len(x_data)):
totalError += (y_data[i] - (theta1 * x_data[i,0] + theta2 * x_data[i,1] + theta0)) ** 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))
# 循环epochs次
for i in range(epochs):
theta0_grad = 0
theta1_grad = 0
theta2_grad = 0
# 计算梯度的总和再求平均
for j in range(0,len(x_data)):
theta0_grad += -(1/m) * (y_data[j] - (theta1 * x_data[j,0] + theta2 * x_data[j,1] + theta0))
theta1_grad += -(1/m) * x_data[j,0] * (y_data[j] - (theta1 * x_data[j,0] + theta2 * x_data[j,1] + theta0))
theta2_grad += -(1/m) * x_data[j,1] * (y_data[j] - (theta1 * x_data[j,0] + theta2 * x_data[j,1] + theta0))
# 更新参数
theta0 = theta0 - (lr * theta0_grad)
theta1 = theta1 - (lr * theta1_grad)
theta2 = theta2 - (lr * theta2_grad)
return theta0,theta1,theta2
print("Staring theta0 = {0},theta1 = {1},theta2 = {2},error = {3}".format(theta0,theta1,theta2,compute_error(theta0,theta1,theta2,x_data,y_data)))
print("Running…")
theta0,theta1,theta2 = gradient_descent_runner(x_data,y_data,theta0,theta1,theta2,lr,epochs)
print("After{0} iterations theta0 = {1},theta1 = {2},theta2 = {3},error = {4}".format(epochs,theta0,theta1,theta2,compute_error(theta0,theta1,theta2,x_data,y_data)))
定义一个figure,表示一个新的图像,然后画一个3D的图像,在3D里面画散点图,传入坐标,两列x特征分别为x,y轴,y值为z轴,最后设置坐标轴并画网格图,代码与运行结果如下图:
ax = plt.figure().add_subplot(111,projection = '3d')
# 点为红色圆形,大小为100
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 + x0 * theta1 + x1 * theta2
# 画3D图
ax.plot_surface(x0,x1,z)
# 设置坐标轴
ax.set_xlabel('Miles')
ax.set_ylabel('Num of Deliveries')
ax.set_zlabel('Time')
# 显示图像
plt.show()
sklearn实现多元线性回归
需要导入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]
print(x_data)
print(y_data)
# 创建模型
model = linear_model.LinearRegression()
model.fit(x_data,y_data)
# 系数(有几个特征,model.coef_就有几个系数)
print("coefficients:",model.coef_)
# 截距(偏置值只有一个就是截距)
print("intercept:",model.intercept_)
# 测试(导入一个数据,该数据有2个特征值,用predict做预测,打印出预测值
x_test = [[102,4]]
predict = model.predict(x_test)
print("predict:",predict)
ax = plt.figure().add_subplot(111,projection = '3d')
# 点为红色圆形,大小为100
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,z)
# 设置坐标轴
ax.set_xlabel('Miles')
ax.set_ylabel('Num of Deliveries')
ax.set_zlabel('Time')
# 显示图像
plt.show()
运行结果如下:
[[100. 4. 9.3]
[ 50. 3. 4.8]
[100. 4. 8.9]
[100. 2. 6.5]
[ 50. 2. 4.2]
[ 80. 2. 6.2]
[ 75. 3. 7.4]
[ 65. 4. 6. ]
[ 90. 3. 7.6]
[ 90. 2. 6.1]]
[[100. 4.]
[ 50. 3.]
[100. 4.]
[100. 2.]
[ 50. 2.]
[ 80. 2.]
[ 75. 3.]
[ 65. 4.]
[ 90. 3.]
[ 90. 2.]]
[9.3 4.8 8.9 6.5 4.2 6.2 7.4 6. 7.6 6.1]
coefficients: [0.0611346 0.92342537]
intercept: -0.868701466781709
predict: [9.06072908]