機器學習:支持向量機2

本文來自同步博客

P.S. 不知道簡書怎么顯示數學公式以及更好的排版內容。所以如果覺得文章下面格式亂的話請自行跳轉到上述鏈接。后續我將不再對數學公式進行截圖,畢竟行內公式截圖的話排版會很亂。看原博客地址會有更好的體驗。

上一篇文章介紹了機器學習中支持向量機的基本原理,并且在文章末尾介紹了一種利用Python求解二項規劃問題極值的方法。這篇文章我將利用這種方法一步步求解上文中提及的-\vec{\alpha}--\vec{w}--b-,借此復習和驗證支持向量機的知識點。

數據

下面看一組測試數據:

data = {
    '+': [
        [1, 7],
        [2, 8],
        [3, 8],
        [2, 6.5]
    ],
    '-': [
        [5, 1],
        [6, -1],
        [7, 3]
    ]
}

數據data是擁有兩種已經分好類的數據,每種類型的數據的元素都是二維向量,可以在笛卡爾坐標系中表示。

依照上一篇文章講述的原理,我們需要利用這些數據求解一個-\vec{\alpha}-向量。也就是我們需要求解使得二項規劃方程值最小時的-\vec{\alpha}-向量:
F(\vec{\alpha}) = \frac{1}{2}\vec{\alpha}\_{T}H\vec{\alpha} + \vec{c}\vec{\alpha} + c_0, \vec{y}^{T}\vec{\alpha} = 0, \vec{\alpha} \ge 0

很明顯,在支持向量機中,-c_0 = 0-

參數求解

首先利用輸入的測試data準備上述方程中出現的變量-H,c,c_0-。參考下面代碼:

def parseXYC(d):
    X = []
    y = []
    c = []
    for _, v in enumerate(d['+']):
        X.append(np.array(v))
        y.append(1)
        c.append(-1)
    for _, v in enumerate(d['-']):
        X.append(np.array(v))
        y.append(-1)
        c.append(-1)
    return X, y, c, 0

X, y, c, c0 = parseXYC(data)

parseXYC函數把data格式化成-X, y, c, c_0-

然后計算-H-矩陣的值。比較簡單,一行代碼就可以得到:

H = np.array([y[i] * y[j] * np.dot(X[i], X[j]) for i in range(len(X)) for j in range(len(X))]).reshape(len(X), len(X))

求解-\vec{\alpha}-

所有數據都準備好了,接下來就是帶入optimize.minimize函數中計算結果。

這里有幾個超出本文描述范圍的難點需要簡單提及一下:

  1. optimize.minimize函數求解二項規劃使用的SLSQP方法既需要用到二項方程的雅各比導函數,也需要用到約束條件函數的雅各比導函數。不清楚這點導致我在測試過程中一直無法求解到正確的值。
  2. 不等式約束條件-\vec{\alpha} \ge 0-無法在作為約束條件參數constraints傳遞給optimize.minimize函數。我猜測是因為我構造的不等式參數是錯誤的,因此無法讓不等式約束條件生效。我尚無法解決這個問題,希望了解該問題的同學能留言賜教。作為一種補救方法,我利用邊界約束參數bounds描述-\vec{\alpha} \ge 0-這個不等式。
  3. 求解出來的-\vec{\alpha}-向量中,部分應該為0的元素無法完整精確到0。我觀察測試結果總結出來的精確度應該在1e-16,因此在負16次方這個精確度下的值我都假設它就是0。經過繪圖驗證,我發現這個假設是合理的。

下面開代碼實現:

# 定義二項規劃方程fun及其雅各比方程jac
def fun(x, sign=1.):
    return sign * (0.5 * np.dot(x.T, np.dot(H, x))+ np.dot(c, x) + c0)
def jac(x, sign=1.):
    return sign * (np.dot(x.T, H) + c)

# 定義等式約束條件方程feq及其雅各比方程jeq
def feq(x):
    return np.dot(y, x)
def jeq(x):
    return np.array(y)

# 生成相關參數
diff = 1e-16
bounds = [(0, None) for _ in range(len(y))] # x >= 0
constraints = [{ 'type': 'eq', 'fun': feq, 'jac': jeq }]# y*x = 0
options = { 'ftol': diff, 'disp': True }
guess = np.array([0 for _ in range(len(X))])

# 計算結果
res_cons = optimize.minimize(fun, guess, method='SLSQP', jac=jac, bounds=bounds, constraints=constraints, options=options)
alpha = [ 0 if abs(x - 0) <= diff else x for x in res_cons.x ]

# 輸出結果與校驗y*alpha的值是否為0
print('raw alpha: ', res_cons.x)
print('fmt alpha: ', alpha)
print('check y*alpha: ', 'is 0'if (abs(np.dot(y, res_cons.x) - 0) < diff ) else 'is not 0')

求解-\vec{w}--b-

# 計算w = sum(xi*yi*Xi)
w = np.sum([ np.array([0, 0]) if alpha[i] == 0 else (alpha[i] * y[i] * X[i]) for i in range(len(alpha))], axis=0)
print('w: ', w)

# 計算b,對support vector有:yi(w*xi + b) = 1,既有:b = 1/yi - w*xi
B = [( 0 if alpha[i] == 0 else ( 1 / y[i] - np.dot(w, X[i]) ) ) for i in range(len(alpha))]
B = list(filter(lambda x: x != 0, B))
b = 0 if len(B) <= 0 else B[0]
print('b: ', b)

至此支持向量機的參數求解過程完畢。

運行結果如下圖所示:


運行結果

繪圖

最后把數據繪制成圖像。

limit = 11
plt.xlim(-2, limit)
plt.ylim(-2, limit)
# 繪制數據點
[plt.scatter(X[i][0],X[i][1], s=100, color=('r' if y[i] > 0 else 'y')) for i in range(len(X))]
# 繪制分割超平面L: wx + b = 0
plt.plot([i for i in range(limit)], [(-b - w[0]*i)/w[1] for i in range(limit)])
# 繪制上下邊: wx + b = 1/-1
plt.plot([i for i in range(limit)], [(1-b - w[0]*i)/w[1] for i in range(limit)])
plt.plot([i for i in range(limit)], [(-1-b - w[0]*i)/w[1] for i in range(limit)])
plt.show()

效果如下圖。其中紅點為'+'樣本,綠點為'-'樣本。中間的藍色線為分類的標準線。邊界線,即紅色線和綠色線分別穿過各自類別中最靠近分類標準線的點。這些點就是支持向量,只有這些向量所對應的-vec{\alpha}-分量才為非零值。

圖像

本文源碼

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,362評論 6 544
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,577評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,486評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,852評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,600評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,944評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,944評論 3 447
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,108評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,652評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,385評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,616評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,111評論 5 364
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,798評論 3 350
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,205評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,537評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,334評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,570評論 2 379

推薦閱讀更多精彩內容