回归模型

要求1:根据数据集dataset_regression.csv,求最⼩⼆乘解,画出回归曲线,给出训练误差

编写一元线性回归模型所用到的公式如下图所示:

回归方程的误差方差 回归误差怎么算_MSE

回归方程的误差方差 回归误差怎么算_算法_02

同时要求我们需要计算出训练误差MSE,训练误差的定义以及公式如下所示:

回归方程的误差方差 回归误差怎么算_机器学习_03

计算均方误差MSE的代码如下:

def computer_cost(w,b,x,y):#均方误差MSE计算公式
    total_cost=0
    m=len(x)

    for i in range(m):
        total_cost+=(y[i]-w*x[i]-b)**2
    
    return total_cost/m

利用最小二乘法进行回归分析的代码如下:

def ave(da):#平均数
    sum=0
    num=len(da)
    for i in range(num):
        sum+=da[i]
    return sum/num

def fit(x,y):#进行回归分析,利用最小二乘法计算θ1,θ2
    m=len(x)
    x_ave=ave(x)

    sum_xy=0
    sum_x2=0
    sum_delta=0

    for i in range(m):
        sum_xy+=y[i]*(x[i]-x_ave)
        sum_x2+=x[i]**2
    
    w=sum_xy/(sum_x2-m*(x_ave**2))

    for i in range(m):
        sum_delta+=(y[i]-w*x[i])

    b=sum_delta/m
    return w,b

散点图为:

回归方程的误差方差 回归误差怎么算_回归_04

回归曲线为:

回归方程的误差方差 回归误差怎么算_回归_05

预测结果以及回归分析结果为:

θ1 is :  1.976666666666667
θ0 is :  -2.4671622769447922e-17
训练误差为 :  0.9257592592592595
-1.25 -2.4708333333333337
-0.75 -1.4825000000000004 
-0.25 -0.49416666666666675
0.25 0.49416666666666675
0.75 1.4825000000000004
1.25 2.4708333333333337

要求2:将数据集winequality-white.csv按照4:1划分为训练集和测试集,构造线性回归模型,采⽤批量梯度下降或者随机梯度下降均可;输出训练集和测试集的均⽅误差(MSE),画出MSE收敛曲线。

实验中级要求:尝试不同的学习率并进⾏MSE曲线展示,分析选择最佳的学习率。(要求二与中级要求的代码合并)

这里我们要用到多元线性回归的方法。多元线性回归模型以及公式如下图所示:

回归方程的误差方差 回归误差怎么算_MSE_06

学习率的定义如下图所示:

回归方程的误差方差 回归误差怎么算_算法_07

在本次实验中,我采用了批量梯度下降的方法构造线性回归模型。批量梯度下降的定义如下:

回归方程的误差方差 回归误差怎么算_回归方程的误差方差_08

批量梯度下降法构造线性回归模型的代码如下图所示:

def h_predict(nums, x_data, i):#最小二乘目标函数
    h_pre=nums[0]
    for j in range(0,len(nums)-1):
        h_pre+=nums[j+1]*x_data.iloc[i,j]
    return h_pre

# 最小二乘法,计算MSE
def MSE(nums, x_data, y_data):
    totalError = 0
    for i in range(0,len(x_data)):
        totalError += (h_predict(nums, x_data, i)-y_data.iloc[i]) ** 2
    return totalError / len(x_data)

def gradient_descent_runner(x_data, y_data, nums, lr, epochs):#我们采用批量梯度下降的方法构造线性回归模型
    # 计算总数据量
    mse=[]
    m = float(len(x_data))
    # 循环epochs次
    for i in range(epochs):
        nums_grad= [0,0,0,0,0,0,0,0,0,0,0,0]
        # 求偏导
        for j in range(0, len(x_data)):#计算出回归表达式各个系数
            nums_grad[0] += (1/m) * (h_predict(nums, x_data, j) - y_data.iloc[j])
            for h in range(len(nums_grad)-1):
                nums_grad[h+1]+=(1/m) * x_data.iloc[j,h] * (h_predict(nums, x_data, j) - y_data.iloc[j])
        # 更新b和k
        for h in range(len(nums)):
            nums[h]=nums[h]-(lr*nums_grad[h])
        mse.append(MSE(nums, x_data, y_data))
    return nums,mse

绘制MSE收敛曲线的代码如下图所示:

nums=[0,0,0,0,0,0,0,0,0,0,0,0]
nums,mse = gradient_descent_runner(x_train, y_train, nums, lr, max)
print("学习率=",lr,"MSE_train=",MSE(nums,x_train,y_train),"MSE_test=",MSE(nums,x_test,y_test))
ax1.plot(range(len(mse)),mse,'b',label="mse")
ax1.set_title('alpha=0.0000001')

运行结果如下:

After 15 iterations:
学习率= 1e-07 MSE_train= 44.808124067227155 MSE_test= 45.1075542129084
学习率= 1e-06 MSE_train= 26.186213217500523 MSE_test= 26.627784475867195
学习率= 1e-05 MSE_train= 4.418365639952903 MSE_test= 4.5931670016826365
学习率= 0.0001 MSE_train= 45045.76710769818 MSE_test= 43971.582490925444
学习率= 0.001 MSE_train= 4.712982757502355e+41 MSE_test= 4.604144272112028e+41
学习率= 0.01 MSE_train= 1.6032501015942668e+72 MSE_test= 1.5662257113646107e+72

在不同的学习率下,绘制的不同的收敛曲线如下图所示:

回归方程的误差方差 回归误差怎么算_机器学习_09

根据比较不同的学习率所构造的线性回归模型的训练误差和线性误差,我们可以得到,当学习率alpha=1e-05时,误差最小,MSE_train= 4.418365639952903 MSE_test= 4.5931670016826365。