iT邦幫忙

2018 iT 邦幫忙鐵人賽
DAY 6
0

昨天最後說到了,我們應該要最小化這個E(w)

才不會得到太過於overfitting的曲線,那在前Curve Fitting第一篇的時候我們有提到
最小化原本的E(w)

就是解這個式子

熟悉線性代數的朋友,一定會想說,萬一反矩陣不存在呢?
所以這邊通常我們會使用虛反矩陣(pseudo inverse)來解決這個問題。

不過這畢竟還是比較容易得到overfitting的曲線,那對於新的E(w),我們要怎麼最小化呢?

其實跟我們Curve Fitting第一篇的手法一樣,我們同樣的令E(w)對於w的微分等於0,然後解w

為了表示方便我們把原本式子中的加總換掉,改成以向量與矩陣的方式表示!

其中
,而,phi則是之前提到的

那個很像phi但是比較大的,他就是phi的大寫,我們叫他大phi!他是一個 N * M 的矩陣,也就是有N筆資料他就有N列,每筆資料有M維他就有M行。

接著我們對他微分!

,其中 I 是單位矩陣,也就是只有對角線是一剩下都是零。
所以我們就可得到

這就是我們寫程式要用到的式子!

而這邊呢,我們就不需要擔心他會沒有反矩陣了,所以不需要用虛反矩陣去計算!


為什麼不會沒有反矩陣呢?(這段稍微需要一點背景知識,跳過不會影響我們的實做!)

首先我們要知道,他一定會是對稱矩陣,也就是他取轉置還是他自己。
接著根據定義,只要是實對稱矩陣,他的特徵值(eigenvalue)一定大於等於零,也就是一定是正半定矩陣。

再來依照eigenvalue表現定理,加上單位矩陣等價於使原來矩陣的eigenvalue加上單位矩陣的倍率,這邊也就是我們的lambda,那由於lambda一定會大於零,所以我們新的矩陣eigenvalue就皆大於零了!

eigenvalue的相乘總和不等於零 等價於 此矩陣可逆

因此這邊我們不需要考慮反矩陣不存在的情況,如果電腦算出來是沒有反矩陣,那一定是數值上近似有錯誤!


有了這個式子我們就可以開始實做了!
我們只需要使用python numpy這個library
不過如果你想要看一下作圖的效果的話建議可以用matplotlib這個library!

import numpy as np
from numpy.linalg import pinv, inv
import matplotlib.pyplot as plt

def phi(x, order):
    X = [1.]
    out = float(x)
    for o in range(order):
        X += [float(out)]
        out *= float(x)
    X = np.asarray(X).reshape(order+1, 1)
    return X

#feature 就是我們的x, target就是我們的t, order就是我們希望到幾維
#lambda就是L2 regularization係數,因為lambda是預設關鍵字,所以我打lamda

def regression(feature, target, order, lamda): 
    target = np.asarray(target).reshape(len(target),1)
    PHI = phi(feature[0], order).T
    for n in range(1, len(feature)):
        PHI = np.vstack((PHI, phi(feature[n], order).T))
    if lamda == 0:
        tmp = pinv(PHI)
    else:
        tmp = inv(PHI.T.dot(PHI) + lamda * np.identity(order + 1)).dot(PHI.T)
    return tmp.dot(target)
    
#function定義好之後,來生產資料,我們以sin為我們真正的曲線,並且加上一些雜訊
def f(x):
    return np.sin(x) + np.random.normal(0,1,len(x))

train = np.linspace(0,10,5) #範圍從0~10,生五個點
target = f(train) #拿到五個曲線上的點加上雜訊

order = 10 #控制你要用幾維去fit

#接著就可以使用我們剛剛寫好的regression function
#lambda要用多少才好呢?這就是需要靠測試得到的!
w = regression(train, target, order, 1)

#接著把我們的w描出來
line = np.linspace(0,10,100)
lx = []
for point in line:
    lx += [w.T.dot(phi(point, order)).reshape(1)]

#接著就畫圖!
plt.plot(train, target, 'bo') #畫點點
plt.plot(line, lx, linestyle = '--') #畫你推測的出來的曲線
plt.show() #show出來!

這樣子就簡單的完成Regression了!
有個要注意的地方是,我們的例子都是輸入一個x,然後我們利用多項式轉換讓他變成很多x的幾次方這樣!
但是如果今天你輸入的x有兩個特徵,例如

那你的多項式轉換的結果應該要變成這樣,以轉換為二次為例子

這樣的功能在python中其實是有提供的,自己寫也不會太困難,不過因為不是我們這邊的主題,所以就不多說,如果大家對於寫法有興趣的話,可以再問我!

那我們在概論的Regression就先告一個段落,我們將在講到線性模型的時候再跟大家提其他方式!
我們明天就先跟大家討論機率!


上一篇
概論 - 曲線擬合 Curve Fitting (2) Overfitting!
下一篇
機率 - 基礎概念
系列文
機器學習你也可以 - 文組帶你手把手實做機器學習聖經30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
Wenchun
iT邦新手 5 級 ‧ 2024-04-17 12:02:31

您好,我有看了您關於linear regression的文章
在文章中有介紹到單一特徵的狀況
那我想知道假如我今天的資料有11維,我該如何寫呢

我要留言

立即登入留言