''' 線性回歸: 輸入 輸出 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

