單特徵線性迴歸
單特徵線性迴歸
線性迴歸模型是迴歸模型的一種,通常用於預測資料。
一、模型
二、成本函式的使用
線性迴歸的目標是找到合適的w、b,使成本函式的值最小,讓假設函式直線與訓練集擬合最好。成本函式是衡量預測值與真實值之間的差異,也即誤差,誤差越小,預測的結果自然更接近真實值。
以下將展示成本函式與引數的視覺化圖形。
1.簡化的假設函式,f=wx:
2.完整的假設函式,f=wx+b:
在同一條等高線上,可能有多種不同的引數w、b使成本函式值相等,這樣並不利於預測。在這樣碗狀圖形的最底部或最低點,成本函式的值是最小的,也是唯一的。
三、梯度下降
如何尋找最合適的引數w、b?雖然我們已經理解最低處是使成本函式最小的點,但是直接利用視覺化圖形去讀取,這在複雜的模型中顯然是不可取的。此時,就要利用到梯度下降演算法,它是機器學習中最重要的演算法之一。實際上,梯度下降演算法不僅僅適用於迴歸模型,它適用於幾乎所有多引數模型。
1、思想
從起始點開始梯度下降,每走一步都選擇梯度下降最快的點,直至到達區域性最低點。
2、梯度下降演算法的實現
每下降一次就更新一次引數w、b。到達區域性最低點以後,w、b的值將不再變化。
3、梯度下降的理解
梯度下降的任務是找到最小化成本函式的引數w、b。
以簡化模型為例,只有一個引數w時:
4、學習率的選擇
當學習率過小時,下降的步子過小,導致到達最低點需要很多步,需要的時間也更多;
當學習率過大時,下降的步子較大,可能越過最低點,導致越來越遠,甚至永遠也到達不了最低點。
為什麼我們可以採用固定的學習率?因為越靠近最低點,斜率將會越來越小,等於邁的步子越來越小了,最終也會慢慢靠近最低點。
四、線性迴歸的梯度下降
1、微積分的推導
2、梯度下降
3、差異
在梯度下降中,成本函式可能存在多個區域性最小值,但是對於線性迴歸而言,成本函式只有一個全劇最小點。
所以線上性迴歸模型中,只要學習率選擇得當,成本函式總是會收斂於全域性最小值。
4、批量梯度下降
批量梯度下降指的是在梯度下降的每一步,我們都會考慮所有的訓練樣本,而不是訓練資料的一個子集。事實上,還有其他的梯度下降演算法在下降時僅僅考慮訓練資料的一個子集,在這裡我們採用批量梯度下降的方法處理線性迴歸模型。
五、實現
部分資料集和完整程式碼
6.1101,17.592
5.5277,9.1302
8.5186,13.662
7.0032,11.854
5.8598,6.8233
8.3829,11.886
7.4764,4.3483
8.5781,12
6.4862,6.5987
5.0546,3.8166
5.7107,3.2522
14.164,15.505
5.734,3.1551
.......
"""
在本練習的這一部分,您將使用單變數實現線性迴歸,以預測食品卡車的利潤。
假設你是一家餐飲連鎖店的執行長,正在考慮在不同的城市開設新的分店。這家連鎖店已經在各個城市擁有卡車,你可以從這些城市獲得利潤和人口資料。您希望使用這些資料來幫助您選擇下一步要擴充套件到哪個城市。檔案ex1data1.txt包含線性迴歸問題的資料集。第一列是一個城市的人口,第二列是該城市食品卡車的利潤。利潤為負值表示虧損。
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 匯入資料
path = r'data/ex1data1.txt'
data = pd.read_csv(path, header=None, names=['Population', 'Profit'])
# 在訓練集中索引為0處新增一列,以便我們可以使用向量化的解決方案來計算代價和梯度,值為1,命名為“ones”
data.insert(0, 'ones', 1)
# 取資料集列數:3
cols = data.shape[1] # df.shape返回的是一個元組(97,3),97表示行數,3表示列數
X = data.iloc[:, 0:cols - 1] # 提取資料集除最後一列外的所有資料
y = data.iloc[:, cols - 1:cols] # 提取資料集最後一列的資料
# 轉換成numpy的矩陣格式
X = np.matrix(X.values) # 97x2的矩陣
y = np.matrix(y.values) # 97x1的矩陣
# theta存放參數w、b,初始化為0
theta = np.matrix(np.array([0, 0])) # 一個1x2矩陣(0 0)
alpha = 0.0001 # 學習速率α
iters = 1000 # 下降的步數。
def computeCost(X, y, theta):
"""代價函式"""
linear = np.power(((X * theta.T) - y), 2) # np.power(x,y),計算x的y次方
cost = np.sum(linear) / (2 * len(X))
return cost
def gradientDescent(X, y, theta, alpha, iters):
"""梯度下降法"""
# 存放參數w、b的中間量
temp = np.matrix(np.zeros(theta.shape)) # np.zeros生成一個給定形狀和型別的用0填充的陣列
# 引數的個數
parameters = int(theta.ravel().shape[1]) # ravel:扁平化函式,矩陣變成1行N列
# # 生成一個包含iters個0的陣列,用於存放每一次下降後的成本
cost = np.zeros(iters)
# 迭代iters次
for i in range(iters):
error = (X * theta.T) - y # 表示成本f(w,b) - y
# 更新引數w、b。(j為0時表示更新b,j為1時表示更新w,theta為存放參數w、b的矩陣[b w])
for j in range(parameters):
term = np.multiply(error, X[:, j]) # (f(w,b) - y )* x(j)
temp[0, j] = theta[0, j] - (alpha / len(X)) * np.sum(term)
theta = temp
#計算成本
cost[i] = computeCost(X, y, theta)
# 返回更新iters次後的theta,以及每次下降後的代價值
return theta, cost
print("theta初始值為0的成本值為:",computeCost(X,y,theta))
# 開始梯度下降
g, cost = gradientDescent(X, y, theta, alpha, iters)
print("更新{}次後的成本值為:".format(iters), computeCost(X, y, g))
# 構造假設函式
x = np.linspace(data.Population.min(), data.Population.max(), 100) # 從最小值到最大值之間均勻的取100個值
h = g[0, 0] + (g[0, 1] * x) # 假設函式
# 繪製訓練集散點圖和擬合直線
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(x, h, 'r', label='Prediction') #繪製假設函式擬合的直線
ax.scatter(data.Population, data.Profit, label='Traning Data') # 訓練集散點圖
ax.legend(loc=2)
ax.set_xlabel('Population')
ax.set_ylabel('Profit')
ax.set_title('Predicted Profit VS. Population Size')
plt.show()
# 繪製學習曲線
fig, ax = plt.subplots(figsize=(12, 8))
ax.plot(np.arange(iters), cost, 'r') # 觀察成本函式下降情況
ax.set_xlabel('Iterations')
ax.set_ylabel('Cost')
ax.set_title('Error vs. Training Epoch')
plt.show()
