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

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM