机器学习之线性回归(最小二乘法手写+sklearn实现)

2022-07-29 09:22:43 浏览数 (1)

写在前面

这部分内容在我的CSDN博客中已经有提到,算是比较基础的部分。现在搬到公众号上,不能再像CSDN上那样简略,我尽量把它解释得通俗易懂一点。

一、基本形式

我们用 个属性描述示例 ,其中, 是 在第 个属性上的取值。线性模型(Linear Model)就是试图用一个线性组合来描述一个示例的某种综合得分:

一般我们将其写成向量形式:

其中 。

例如我们用五组属性来描述一个人是否是好的配偶:(性别,性格,年龄,外貌,财富)。

那么每一个人都能用一个向量来表示: 性别性格年龄外貌财富

那么判断一个人是否是好的配偶,我们可以定义以下线性模型:

性别性格年龄外貌财富 最终,得分越高就能表明这个人更有可能是一个好的配偶。

二、线性回归

线性回归试图学习到一个线性模型以尽可能准确地预测实值输出标记。通过在数据集上建立代价函数(loss function),最终以优化代价函数为目标确定模型参数,从而得到模型用于后续的预测。

设想一个情景:现在有一批数据,里面包含10000个人的上述五个属性的值以及它们的得分 ,现在需要我们找出 和 ,进而去预测其他人(只知道属性值)的 。

那么我们最终的目标就是:寻找参数 和 ,使得 和 对这10000人的预测值与真实的回归目标(已经给出的 )之间的均方误差最小。 那么定义:

其中 和 分别表示第 个样本的属性值和标记(得分)。

目标:就是要找到 和 ,使得 最小,这样我们就可以认为找到的 和 对这批数据具有最好的适应性,如果这批样本具有较好的普遍性,我们就能用算出的 和 来预测其他人的分数。

三、求解

为了方便求导,我们对 做进一步的简化,我们令:

再令 这样最终:

然后 对 求导等于0:

进而解得:

那么最终:

如果再给我们一个人的各个属性值,我们就能利用上述公式算出这个人的得分。

四、代码实现

1.导入包

代码语言:javascript复制
from sklearn import linear_model
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import mean_squared_error,r2_score,mean_absolute_error

sklearn中有专门的线性模型包linear_model,matplotlib用于画图,另外导入MSE,R_Square和MAE三个评价指标。

2.构造数据集

可以自动生成数据,也可以寻找现有数据,以下数据是作业中的数据Salary_Data.csv,样本数据只有一个特征。

代码语言:javascript复制
def load_data():
    data=pd.read_csv('Salary_Data.csv',encoding='gbk')
    data=data.values.tolist()
    train_x=[];train_y=[]
    test_x=[];test_y=[]
    #前一半作为训练集,后一半作为测试集
    for i in range(len(data)):
        if i<len(data)/2:
            train_x.append(data[i][0])
            train_y.append(data[i][1])
        else:
            test_x.append(data[i][0])
            test_y.append(data[i][1])
    return train_x,train_y,test_x,test_y

3.模型训练 预测

代码语言:javascript复制
lr = linear_model.LinearRegression()
lr.fit(train_x, train_y)
y_pred = lr.predict(test_x)

4.输出参数以及评价指标

代码语言:javascript复制
# 输出系数和截距
print('w:', lr.coef_, 'b:', lr.intercept_)
# 输出评价指标
print('MSE:', mean_squared_error(test_y, y_pred))
print('MAE:', mean_absolute_error(test_y, y_pred))
print('R2_Squared:', r2_score(test_y, y_pred))

5.画图

代码语言:javascript复制
# 显示
plt.scatter(test_x, test_y, color='black')
plt.plot(test_x, y_pred, color='blue', linewidth=3)
plt.show()

完整代码:

代码语言:javascript复制
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import linear_model
import numpy as np
from sklearn.metrics import mean_squared_error,r2_score,mean_absolute_error

def load_data():
    data=pd.read_csv('Salary_Data.csv',encoding='gbk')
    data=data.values.tolist()
    train_x=[];train_y=[]
    test_x=[];test_y=[]
    #前一半作为训练集,后一半作为测试集
    for i in range(len(data)):
        if i<len(data)/2:
            train_x.append(data[i][0])
            train_y.append(data[i][1])
        else:
            test_x.append(data[i][0])
            test_y.append(data[i][1])
    return train_x,train_y,test_x,test_y

def model():
    print('手写:')
    train_x,train_y,test_x,test_y=load_data()
    #最小二乘法得到参数
    sum=0.0;sum_square=0.0;sum_2=0.0;sum_b=0.0
    for i in range(len(train_x)):
        sum=sum train_x[i]
        sum_square=sum_square train_x[i]**2
    ave_x=sum/len(train_x)
    for i in range(len(train_x)):
        sum_2=sum_2 (train_y[i]*(train_x[i]-ave_x))
    w=sum_2/(sum_square-sum**2/len(train_x))
    for i in range(len(train_x)):
        sum_b=sum_b (train_y[i]-w*train_x[i])
    b=sum_b/len(train_x)
    print('w=',w,'b=',b)
    #测试
    pred_y=[]
    for i in range(len(test_x)):
        pred_y.append(w*test_x[i] b)
    #计算MSE,MAE,r2_score
    sum_mse=0.0;sum_mae=0.0
    sum1=0.0;sum2=0.0
    for i in range(len(pred_y)):
        sum_mae=sum_mae np.abs(pred_y[i]-test_y[i])
        sum_mse=sum_mse (pred_y[i]-test_y[i])**2
    sum_y=0.0
    for i in range(len(test_y)):
        sum_y=sum_y test_y[i]
    ave_y=sum_y/len(test_y)
    for i in range(len(pred_y)):
        sum1=sum1 (pred_y[i]-test_y[i])**2
        sum2=sum2 (ave_y-test_y[i])**2
    print('MSE:',sum_mse/len(pred_y))
    print('MAE:',sum_mae/len(pred_y))
    print('R2_Squared:',1-sum1/sum2)
    #显示
    plt.scatter(test_x, test_y, color='black')
    plt.plot(test_x, pred_y, color='blue', linewidth=3)
    plt.show()
    print('n')

#调包
def sklearn_linearmodel():
    print('调包:')
    train_x, train_y, test_x, test_y = load_data()
    train_x=np.array(train_x).reshape(-1,1)
    train_y = np.array(train_y).reshape(-1, 1)
    test_x = np.array(test_x).reshape(-1, 1)
    test_y = np.array(test_y).reshape(-1, 1)
    # 训练 测试
    lr = linear_model.LinearRegression()
    lr.fit(train_x, train_y)
    y_pred = lr.predict(test_x)

    # 输出系数和截距
    print('w:', lr.coef_, 'b:', lr.intercept_)
    # 输出评价指标
    print('MSE:', mean_squared_error(test_y, y_pred))
    print('MAE:', mean_absolute_error(test_y, y_pred))
    print('R2_Squared:', r2_score(test_y, y_pred))

    # 显示
    plt.scatter(test_x, test_y, color='black')
    plt.plot(test_x, y_pred, color='blue', linewidth=3)
    plt.show()


if __name__=='__main__':
    model()
    sklearn_linearmodel()

0 人点赞