sklearn之线性回归

'''
    线性回归:
            输入        输出
            0.5      5.0
            0.6      5.5
            0.8      6.0
            1.1      6.8
            1.4      7.0
            ...
            y = f(x)

        预测函数:y = w0+w1x
                x: 输入
                y: 输出
                w0和w1: 模型参数

        所谓模型训练,就是根据已知的x和y,找到最佳的模型参数w0 和 w1,尽可能精确地描述出输入和输出的关系。
            如:5.0 = w0 + w1 × 0.5       5.5 = w0 + w1 × 0.6

        单样本误差:根据预测函数求出输入为x时的预测值:y' = w0 + w1x,单样本误差为1/2(y' - y)2。

        总样本误差:把所有单样本误差相加即是总样本误差:1/2 Σ(y' - y)2

        损失函数:loss = 1/2 Σ(w0 + w1x - y)2
            损失函数就是总样本误差关于模型参数w0 w1的函数,该函数属于三维数学模型,即需要找到一组w0 w1使得loss取极小值。

        示例:画图模拟梯度下降的过程
            1>整理训练集数据,自定义梯度下降算法规则,求出w0 , w1 ,绘制回归线。
            2>绘制随着每次梯度下降,w0,w1,loss的变化曲线。
            3>基于三维曲面绘制梯度下降过程中的每一个点。
            4>基于等高线的方式绘制梯度下降的过程。
'''

import numpy as np
import matplotlib.pyplot as mp
from mpl_toolkits.mplot3d import axes3d
import warnings

warnings.filterwarnings('ignore')

train_x = np.array([0.5, 0.6, 0.8, 1.1, 1.4])
train_y = np.array([5.0, 5.5, 6.0, 6.8, 7.0])

# 实现梯度下降的过程
times = 1000  # 迭代次数
lrate = 0.01  # 学习率,取值不应太大
w0, w1 = [1], [1]  # 初始化模型参数,记录每次梯度下降的参数
losses = []  # 保存每次迭代过程中损失函数值
epoches = []  # 保存每次迭代过程的索引
for i in range(1, times + 1):
    # 输出每次下降时:w0,w1,loss值的变化
    epoches.append(i)
    loss = ((w0[-1] + w1[-1] * train_x - train_y) ** 2).sum() / 2
    losses.append(loss)
    print('{:4}> w0={:.6f},w1={:.6f},loss={:.6f}'.format(epoches[-1], w0[-1], w1[-1], losses[-1]))

    # 每次梯度下降过程,需要求出w0和w1的修正值,求修正值需要推导loss函数在w0及w1方向的偏导数
    d0 = (w0[-1] + w1[-1] * train_x - train_y).sum()
    d1 = ((w0[-1] + w1[-1] * train_x - train_y) * train_x).sum()
    # w0和w1的值不断修正
    w0.append(w0[-1] - lrate * d0)
    w1.append(w1[-1] - lrate * d1)
print(w0[-1], w1[-1])

pred_y = w0[-1] + w1[-1] * train_x

# 绘制样本点
mp.figure('Linear Regression', facecolor='lightgray')
mp.title('Linear Regression')
mp.grid(linestyle=':')
mp.scatter(train_x, train_y, s=60, c='orangered', label='Samples', marker='o')
# 绘制回归线
mp.plot(train_x, pred_y, color='dodgerblue', label='Regression Line')
mp.legend()

# 绘制随着每次梯度下降,w0,w1,loss的变化曲线。
mp.figure('BGD Params', facecolor='lightgray')
mp.title('BGD Params')
mp.tick_params(labelsize=10)
mp.subplot(311)
mp.title('w0')
mp.plot(epoches, w0[:-1], color='dodgerblue', label='w0')
mp.grid(linestyle=':')
mp.legend()

mp.subplot(312)
mp.title('w1')
mp.plot(epoches, w1[:-1], color='orangered', label='w1')
mp.grid(linestyle=':')
mp.legend()

mp.subplot(313)
mp.title('loss')
mp.plot(epoches, losses, color='yellowgreen', label='loss')
mp.grid(linestyle=':')
mp.legend()

# 基于三维曲面绘制梯度下降过程中的每一个点。
# 整理网格点坐标矩阵,计算每个点的loss绘制曲面

grid_w0, grid_w1 = np.meshgrid(np.linspace(0, 9, 500), np.linspace(0, 3.5, 500))
grid_loss = np.zeros_like(grid_w0)
for x, y in zip(train_x, train_y):
    grid_loss += ((grid_w0 + grid_w1 * x - y) ** 2) / 2
# 绘制3D损失函数图
mp.figure('Loss Function', facecolor='lightgray')
ax3d = mp.gca(projection='3d')
ax3d.set_xlabel('w0')
ax3d.set_ylabel('w1')
ax3d.set_zlabel('loss')
ax3d.plot_surface(grid_w0, grid_w1, grid_loss, cmap='jet')
# 绘制3D梯度下降曲线图
ax3d.plot(w0[:-1], w1[:-1], losses, 'o-', color='orangered', label='BGD', zorder=3)
mp.tight_layout()

# 基于等高线的方式绘制梯度下降的过程。
mp.figure('BGD Contour', facecolor='lightgray')
mp.title('BGD Contour')
mp.xlabel('w0')
mp.ylabel('w1')
mp.grid(linestyle=':')
cntr = mp.contour(grid_w0, grid_w1, grid_loss, c='black', linewidths=0.5)
mp.clabel(cntr, fmt='%.2f', inline_spacing=0.2, fontsize=8)
mp.contourf(grid_w0, grid_w1, grid_loss, cmap='jet')
mp.plot(w0[:-1], w1[:-1], c='orangered', label='BGD')
mp.legend()

mp.show()

输出结果:
4.065692318299849 2.2634176028710415

  

  

  

   

'''
    sklearn中处理线性回归问题的API:
        import sklearn.linear_model as lm
        # 创建模型
        model = lm.LinearRegression()
        # 训练模型
        # 输入为一个二维数组表示的样本矩阵
        # 输出为每个样本最终的结果
        model.fit(输入, 输出) # 训练模型
        # 预测输出
        # 输入array是一个二维数组,每一行是一个样本,每一列是一个特征。
        result = model.predict(array)

    评估训练结果误差(metrics)---模型评估
        线性回归模型训练完毕后,可以利用测试集评估训练结果误差。sklearn.metrics提供了计算模型误差的几个常用算法:
                import sklearn.metrics as sm
                # 平均绝对值误差:1/m∑|实际输出-预测输出|
                sm.mean_absolute_error(y, pred_y)
                # 平均平方误差:SQRT(1/mΣ(实际输出-预测输出)^2)
                sm.mean_squared_error(y, pred_y)
                # 中位绝对值误差:MEDIAN(|实际输出-预测输出|)
                sm.median_absolute_error(y, pred_y)
                # R2得分,(0,1]区间的分值。分数越高,误差越小。---应用多
                sm.r2_score(y, pred_y)

    模型的保存和加载:---持久化存储
            1>模型训练是一个耗时的过程,一个优秀的机器学习模型是非常宝贵的。
            可以将模型保存到磁盘中,也可以在需要使用的时候从磁盘中重新加载模型即可。不需要重新训练(即model.fit())。
            2>模型保存和加载相关API:
                import pickle
                pickle.dump(model, 磁盘文件) # 保存模型
                model = pickle.load(磁盘文件)  # 加载模型


    示例:基于一元线性回归训练single.txt中的训练样本,使用模型预测测试样本。
        步骤:整理数据----->训练模型----->绘制图像----->评估模型
'''

import numpy as np
import sklearn.linear_model as sl
import matplotlib.pyplot as mp
import sklearn.metrics as sm

# 采集数据
x, y = np.loadtxt('./ml_data/single.txt', delimiter=',', usecols=(0, 1), unpack=True)
print(x.shape)
print(y.shape)
# 把输入变成二维数组,一行一样本,一列一特征
x = x.reshape(-1, 1)  # 变成n行1列
model = sl.LinearRegression()
model.fit(x, y)
pred_y = model.predict(x)  # 把样本x带入模型求出预测y

# 输出模型的评估指标
print('平均绝对值误差:', sm.mean_absolute_error(y, pred_y))
print('平均平方误差:', sm.mean_squared_error(y, pred_y))
print('中位绝对值误差:', sm.median_absolute_error(y, pred_y))
print('R2得分:', sm.r2_score(y, pred_y))

# 绘制图像
mp.figure("Linear Regression", facecolor='lightgray')
mp.title('Linear Regression', fontsize=16)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.xlabel('x')
mp.ylabel('y')

mp.scatter(x, y, s=60, marker='o', c='dodgerblue', label='Points')
mp.plot(x, pred_y, c='orangered', label='LR Line')
mp.tight_layout()
mp.legend()
mp.show()


输出结果:
(50,)
(50,)
平均绝对值误差: 0.5482812185435971
平均平方误差: 0.43606903238180605
中位绝对值误差: 0.5356597030142565
R2得分: 0.736263899848181

  

'''
    模型的保存和加载:---持久化存储
            1>模型训练是一个耗时的过程,一个优秀的机器学习模型是非常宝贵的。
            可以将模型保存到磁盘中,也可以在需要使用的时候从磁盘中重新加载模型即可。不需要重新训练(即model.fit())。
            2>模型保存和加载相关API:
                import pickle
                pickle.dump(model, 磁盘文件) # 保存模型
                model = pickle.load(磁盘文件)  # 加载模型

    示例:把训练好的模型保存到磁盘中。
'''

import numpy as np
import sklearn.linear_model as sl
import matplotlib.pyplot as mp
import sklearn.metrics as sm
import pickle

# 采集数据
x, y = np.loadtxt('./ml_data/single.txt', delimiter=',', usecols=(0, 1), unpack=True)
print(x.shape)
print(y.shape)
# 把输入变成二维数组,一行一样本,一列一特征
x = x.reshape(-1, 1)  # 变成n行1列
model = sl.LinearRegression()
model.fit(x, y)
# 保存模型
with open('./lr.pkl', 'wb') as f:
    pickle.dump(model, f)
print('Dump Success!')

输出结果:
(50,)
(50,)
Dump Success!
'''
    模型的保存和加载:---持久化存储
            1>模型训练是一个耗时的过程,一个优秀的机器学习模型是非常宝贵的。
            可以将模型保存到磁盘中,也可以在需要使用的时候从磁盘中重新加载模型即可。不需要重新训练(即model.fit())。
            2>模型保存和加载相关API:
                import pickle
                pickle.dump(model, 磁盘文件) # 保存模型
                model = pickle.load(磁盘文件)  # 加载模型
    示例:加载模型。
'''
import numpy as np
import sklearn.linear_model as sl
import matplotlib.pyplot as mp
import sklearn.metrics as sm
import pickle

# 采集数据
x, y = np.loadtxt('./ml_data/single.txt', delimiter=',', usecols=(0, 1), unpack=True)

# 从文件中加载模型
with open('./lr.pkl', 'rb') as f:
    model = pickle.load(f)

# 把样本带入模型中求预测y
pred_y = model.predict(x.reshape(-1, 1))

# 输出模型的评估指标
print('平均绝对值误差:', sm.mean_absolute_error(y, pred_y))
print('平均平方误差:', sm.mean_squared_error(y, pred_y))
print('中位绝对值误差:', sm.median_absolute_error(y, pred_y))
print('R2得分:', sm.r2_score(y, pred_y))

# 绘制图像
mp.figure("Linear Regression", facecolor='lightgray')
mp.title('Linear Regression', fontsize=16)
mp.tick_params(labelsize=10)
mp.grid(linestyle=':')
mp.xlabel('x')
mp.ylabel('y')

mp.scatter(x, y, s=60, marker='o', c='dodgerblue', label='Points')
mp.plot(x, pred_y, c='orangered', label='LR Line')
mp.tight_layout()
mp.legend()
mp.show()

输出结果:
平均绝对值误差: 0.5482812185435971
平均平方误差: 0.43606903238180605
中位绝对值误差: 0.5356597030142565
R2得分: 0.736263899848181

  

原文地址:https://www.cnblogs.com/yuxiangyang/p/11180285.html