# 淺入淺出瞭解機器學習_01_Linear Regression(上)
###### tags: `淺入淺出瞭解機器學習`
Linear Regression,線性迴歸,屬監督式學習,適用於數值型的預測,ex:PM2.5、房價、溫度..。
機器學習的學習目標就是學到一個function或稱hypothesis來預測你想要的目標~(說明中可能會交替使用)~,或者更明白的說是從一個function set或一個hypothesis class中找到一個最好的那一個hypothesis來做為你的目標函數。
因為是hypothesis,因此會以$h(x)$來表示這個學習目標,而過程中我們要學習參數$\theta$讓$h(x)$擬合資料,因此會以$h_\theta(x)$來做為完整的表示,下標$\theta$表示這個$h(x)$是取決於$\theta$,也就是$\theta$會影響我們的輸出結果。
$h_\theta(x)$的功能就是將我們的輸入資料$x$轉換為預測資料$\hat{y}$,舉例來說,我們的輸入或許會是前5天的溫度與相關大氣資料,那輸出的$\hat{y}$就會明天或$n$天之後溫度,通常以$\hat{y}$,多個帽子來表示預測值,但也會有書或線上課程是以此為實際值,過程中記得注意符號約定的說明。
線性迴歸就是我們國中所學的線性方程式,$y=ax+b$,只是在這邊我們會用$h_\theta(x)=\theta_1 x_1 + \theta_0$,下標1代表第1個特徵,因此如果有多個特徵的話,表示方式就會是$h_\theta(x)=\theta_1 x_1 + \theta_2 x_2 + \cdots + \theta_n x_n + \theta_0$。
通常以$n$來表示資料所擁有特徵數量,以$m$表示資料集的大小,舉例來說,我們希望以前5天的溫度預測第6天的溫度,那代表我們的每一筆資料會有著5個特徵分別代表這5天的溫度,那如果我們的資料集的筆數有100筆,那我們的資料維度就會是100x5。
## 簡單線性迴歸
單一個變數的線性迴歸又稱單變量線性迴歸或簡單線性迴歸,也就是目標函數為$h_\theta(x) = \theta_1 x + \theta_0$。
下圖說明為什麼$h_\theta(x)$的結果是取決於$\theta$:
![](https://i.imgur.com/pfJFsxT.jpg)
上面兩張圖可以看的出來,不同的$\theta$會有不同的線,而這條線又稱為迴歸線,我們的目標就是要讓所有的資料點到這條線的距離最短。
![](https://i.imgur.com/RkB79E8.jpg)
點到線的量測方式是取垂直$x$軸到線的距離,這段距離又稱偏移值或殘差,又或者每一個點到線的距離也可以稱為cost,而計算這個cost的函數則稱為cost function或loss function,也就是成本函數或稱損失函數。
## 成本函數
成本函數計算的是$h_\theta(x)$的output與實際值之間的差距,以一個資料點來看就是$(h_\theta(x) - y)^2$,或寫為$(\hat{y} - y)^2$,假設我們的training set的資料有$m$筆,那整體的loss就是$\dfrac{1}{2m}\sum_{i=1}^m(h_\theta(x)^{(i)} - y^{(i)})^2$,上標$i$表示第$i$筆資料,除$2m$是取平均,不然整體的cost會太大,不好收斂,把它視為約定俗成就好了。
上面提到,我們的$h_\theta(x)$是取決於$\theta$,成本函數則是計算在這個$\theta$下所得的output與實際值之間的距離,因此寫為$L(\theta_0, \theta_1) = \dfrac{1}{2m}\sum_{i=1}^m(h_\theta(x)^{(i)} - y^{(i)})^2$,我們的目標就是找到一組$\theta$來最小化整體的cost。
基本上$\theta_0$影響的是迴歸線是否過原點,為了說明上的方便,先不看$\theta_0$,因此我們只有$\theta_1$要學習,也就是$h_\theta(x) = \theta_1 x$,然後假設輸入的$x$就只是很簡單的經過一個線性函數,什麼都沒有變,也就是$(x=1, y=1), (x=2, y=2), (x=3, y=3)$,現在我們可以來計算整體的cost。
可以看的到,當$\theta_1=1$的時候,$h_\theta(x) = 1 \cdot x$,因此得到整體的cost為0,見下計算:
* $x=1$,$\hat{y} = 1 \cdot 1, y = 1$,其誤差為$(1 - 1)^2=0$
* $x=2$,$\hat{y} = 1 \cdot 2, y = 2$,其誤差為$(2 - 2)^2=0$
* $x=3$,$\hat{y} = 1 \cdot 3, y = 3$,其誤差為$(3 - 3)^2=0$
相同的,我們可以帶入不同的$\theta_1$來觀察成本函數的變化:
* $\theta=0.5$
* $x=1$,$\hat{y} = 0.5 \cdot 1, y = 1$,其誤差為$(0.5 - 1)^2=0.25$
* $x=2$,$\hat{y} = 0.5 \cdot 2, y = 2$,其誤差為$(1 - 2)^2=1$
* $x=3$,$\hat{y} = 0.5 \cdot 3, y = 3$,其誤差為$(1.5 - 3)^2=2.25$
* $\dfrac{1}{2*3}*(0.25 + 1 + 2.25)=0.58$
* $\theta=0$
* $x=1$,$\hat{y} = 0 \cdot 1, y = 1$,其誤差為$(0 - 1)^2=1$
* $x=2$,$\hat{y} = 0 \cdot 2, y = 2$,其誤差為$(0 - 2)^2=4$
* $x=3$,$\hat{y} = 0 \cdot 3, y = 3$,其誤差為$(0 - 3)^2=9$
* $\dfrac{1}{2*3}*(1 + 4 + 9)=2.33$
* $\theta=1.5$
* $x=1$,$\hat{y} = 1.5 \cdot 1, y = 1.5$,其誤差為$(1.5 - 1)^2=0.25$
* $x=2$,$\hat{y} = 1.5 \cdot 2, y = 3$,其誤差為$(3 - 2)^2=1$
* $x=3$,$\hat{y} = 1.5 \cdot 3, y = 4.5$,其誤差為$(4.5 - 3)^2=2.25$
* $\dfrac{1}{2*3}*(0.25 + 1 + 2.25)=0.58$
* $\theta=2$
* $x=1$,$\hat{y} = 2 \cdot 1, y = 1$,其誤差為$(2 - 1)^2=1$
* $x=2$,$\hat{y} = 2 \cdot 2, y = 2$,其誤差為$(4 - 2)^2=4$
* $x=3$,$\hat{y} = 2 \cdot 3, y = 3$,其誤差為$(6 - 3)^2=9$
* $\dfrac{1}{2*3}*(1 + 4 + 9)=2.33$
這個圖畫出來大概就是下面這樣子:
![](https://i.imgur.com/5nRZ7ih.jpg)
上面可以看的到不同的$\theta$得到的不同的迴歸線與資料點之間的距離就有所不同,其loss就有所不同。
## Gradient Descent
現在我們已經知道成本函數在計算什麼,那問題就是,我們應該怎麼找到一個$\theta$讓整個loss function的值最小,這就是我們的目標,先回想現在我們手上有什麼東西:
* hypothesis $h_\theta(x)=\theta_1 x$
* loss function $\dfrac{1}{2m}\sum_{i=1}^m(h_\theta(x^{(i)}) - y^{(i)})^2$
我們要用來求解的作法就是gradient descent,也就是梯度下降,或者有些書會寫著梯度下降求解法,直接給出公式:
* $\theta := \theta - \alpha\dfrac{\partial L}{\partial \theta}$
其中$\alpha$即為learning rate,學習效率,這屬超參數(hyper parameter),因為目標函數內已經有著學習參數$\theta$,因此其它需調校的統稱為超參數,避免誤會。learning rate控制的是每次的更新迭代,其步幅有多大,過大會造成振盪而無法收斂,過小則會造成收斂過慢。
gradient descent要計算的就是各參數$\theta$對於成本函數的影響,直觀來看就是求其斜率。值得注意的是,每一次的迭代必需等到所有參數都計算完新的參數值之後再一次性更新,否則會造成異常,以下圖為例:
![](https://i.imgur.com/QgxfvOo.jpg)
左邊的圖說明的是負斜率,因此負負得正,更新後$\theta$會往右移動,而右邊的圖說明的是正斜率,因此負正得負,更新後的$\theta$會往左移動。
回頭說明梯度下降的求解,我們要求$\theta$對loss function $L$的偏微分,展開我們的loss function:
* $\dfrac{1}{2m}\sum_{i=1}^m(h_\theta(x)^{(i)} - y^{(i)})^2$
* $=\dfrac{1}{2m}\sum_{i=1}^m(\theta_1 x_1^{(i)} - y^{(i)})^2$
求微分,記得一個公式,$(ax + b)^2=2(ax + b) \cdot a$,因此上面的式子我們可以得到:
* $\dfrac{1}{2m} \cdot 2 \sum_{i=1}^m(\theta_1 x_1^{(i)} - y^{(i)}) x_1^{(i)}$
## Update Parameters
更新參數的步驟並不難,見步驟說明:
1. 初始化參數$\theta=0$
2. 求$\theta$對loss function $L$的偏微分
3. 更新參數
4. 重覆2~4直到收斂或迭代結束
以剛才的範例說明,我們有3筆輸入,$m=3$,分別為$1, 2, 3$,初始化$\theta=0$,得到total loss = 2.33,計算梯度,$\dfrac{1}{m} \sum_{i=1}^m(\theta_1 x_1^{(i)} - y^{(i)}) x_1^{(i)} =((-1*1) + (-2*2) + (-3*3)) * 1/3 = -4.67$,假設learning rate $\alpha = 0.01$,那$\theta := \theta - \alpha\dfrac{\partial L}{\partial \theta}$就是$0 - 0.01 * (-4.67) = 0.0467$,$\theta: 0 \to 0.0467$
以tensoflow來計算:
```python
import tensorflow as tf
X = tf.constant([[1.], [2.], [3.]]) # input
y = tf.constant([[1.], [2.], [3.]]) # output
w = tf.Variable(initial_value=[[0.]]) # theta
# 計算gradient
with tf.GradientTape() as tape:
# 定義loss function
L = tf.reduce_sum(tf.square(tf.matmul(X, w) - y)) / (X.shape[0] * 2)
# 計算L(w, b)關於w, b的偏導數
w_grad = tape.gradient(L, [w])
print(f'total loss: {L.numpy()}, gradient of w: {w_grad[0].numpy()}')
>>> total loss: 2.3333332538604736, gradient of w: [[-4.666667]]
```
如果你用新的參數$\theta$去計算loss會得到2.12,這比第一次迭代的2.33還要小,再多幾次的迭次就可以逐步的收斂loss。
## 結論
這邊給的範例是一個簡單線性迴歸的學習過程,演算法利用梯度下降在每次的迭代過程中不斷的更新參數$\theta$,以此來最佳化total loss。這個過程就好比從一個function set或hypothesis class找出可以讓total loss最小的那一個解。有了這個概念就可以延伸至多變量線性迴歸,這留著下一次說明。
## 參考
吳恩達老師機器學習課程
李宏毅老師機器學習課程
Sebastian Raschka機器學習