Python機(jī)器學(xué)習(xí)4-線性規(guī)劃手撕SVM

一瞬雹、簡(jiǎn)介

支持向量機(jī)(SVM)是經(jīng)典的監(jiān)督學(xué)習(xí)模型,這篇博文中哈打,將通過線性規(guī)劃(cvxopt包)展示SVM求解時(shí)的過程塔逃。數(shù)據(jù)集采用鳶尾花數(shù)據(jù)集進(jìn)行二分類任務(wù)。

import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from cvxopt import matrix, solvers
from sklearn.datasets import load_iris

iris = load_iris()
iris_df = pd.DataFrame(data= np.c_[iris["data"], iris["target"]], columns= iris["feature_names"] + ["target"])
 
# 二分類
iris_df = iris_df[iris_df["target"].isin([0,1])]             ##找出0-1類
iris_df["target"] = iris_df[["target"]].replace(0,-1)      ##0替換為-1
#選兩個(gè)特征
iris_df = iris_df[["petal length (cm)", "petal width (cm)", "target"]]
 
##將數(shù)據(jù)轉(zhuǎn)為numpy 可視化
X = iris_df[["petal length (cm)", "petal width (cm)"]].to_numpy()
y = iris_df[["target"]].to_numpy()

x_min = 0
x_max = 5.5
y_min = 0
y_max = 2

plt.figure(figsize=(8, 8))
colors = ["steelblue", "orange"]
plt.scatter(X[:, 0], X[:, 1], c=y.ravel(), alpha=0.5, cmap=matplotlib.colors.ListedColormap(colors), edgecolors="black")
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.show()

數(shù)學(xué)來了

  1. SVM最終的表達(dá)式化簡(jiǎn)如下


  2. 由拉格朗日定理料仗,引入拉格朗日乘子α


  3. 因?yàn)镴(w,b,α)是凸的湾盗,我們對(duì)其中的變量求微分如下
  1. 兩個(gè)微分結(jié)果帶入可得:
  1. 還是由微分結(jié)果,第二項(xiàng)為0了立轧,最終結(jié)果如下:


  2. 我們用線性規(guī)劃重新定義上試格粪,定義一個(gè)矩陣H,Hij = yiyjxixj, 最終結(jié)果可改寫成如下形式:


#取n個(gè)訓(xùn)練樣本氛改,定義矩陣H
n = X.shape[0]
H = np.dot(y*X, (y*X).T)
##第二項(xiàng)我們定于-1的列向量
q = np.repeat([-1.0], n)[..., None]

##第一個(gè)約束條件帐萎,我們定義A是1×n的矩陣,種類只有2類胜卤,令b=0
A = y.reshape(1, -1)
b = 0.0

##第二個(gè)約束條件疆导,我們構(gòu)造一個(gè)n×n單位矩陣G,和零向量h
G = np.negative(np.eye(n))
h = np.zeros(n)

##所有條件轉(zhuǎn)為CVXOPT對(duì)象
P = matrix(H)
q = matrix(q)
G = matrix(G)
h = matrix(h)
A = matrix(A)
b = matrix(b)
##調(diào)用線性規(guī)劃求解器
sol = solvers.qp(P, q, G, h, A, b)
alphas = np.array(sol["x"])  ##求出α

微分求解結(jié)果


我們定義支持向量,加入松弛因子,松弛因子的作用就是讓約束條件不要太過絕對(duì)化葛躏。澈段。。舰攒。



兩個(gè)公式代碼如下:

w = np.dot((y * alphas).T, X)[0]
S = (alphas > 1e-5).flatten()
b = np.mean(y[S] - np.dot(X[S], w.reshape(-1,1)))
##打印下結(jié)果
print("W:", w)
print("b:", b)

##可視化一下
xx = np.linspace(x_min, x_max)
a = -w[0]/w[1]
yy = a*xx - (b)/w[1]
 
margin = 1 / np.sqrt(np.sum(w**2))
yy_neg = yy - np.sqrt(1 + a**2) * margin
yy_pos = yy + np.sqrt(1 + a**2) * margin
 
plt.figure(figsize=(8, 8))
 
plt.plot(xx, yy, "b-")
plt.plot(xx, yy_neg, "m--")
plt.plot(xx, yy_pos, "m--")
 
colors = ["steelblue", "orange"]

plt.scatter(X[:, 0], X[:, 1], c=y.ravel(), alpha=0.5, cmap=matplotlib.colors.ListedColormap(colors), edgecolors="black")
 
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
 
plt.show()

第二方法調(diào)Sklearn包就很簡(jiǎn)單了

from sklearn import svm

clf = svm.SVC(kernel="linear", C=10.0)
clf.fit(X, y.ravel())
w = clf.coef_[0]
b = clf.intercept_

print("W:", w)
print("b:", b)
#W: [1.29411744 0.82352928]
#b: [-3.78823471]

完整代碼如下:

import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from cvxopt import matrix, solvers
from sklearn.datasets import load_iris

iris = load_iris()
iris_df = pd.DataFrame(data= np.c_[iris["data"], iris["target"]], columns= iris["feature_names"] + ["target"])
 
# 二分類
iris_df = iris_df[iris_df["target"].isin([0,1])]             ##找出0-1類
iris_df["target"] = iris_df[["target"]].replace(0,-1)      ##0替換為-1
#選兩個(gè)特征
iris_df = iris_df[["petal length (cm)", "petal width (cm)", "target"]]
 
##將數(shù)據(jù)轉(zhuǎn)為numpy 可視化
X = iris_df[["petal length (cm)", "petal width (cm)"]].to_numpy()
y = iris_df[["target"]].to_numpy()

x_min = 0
x_max = 5.5
y_min = 0
y_max = 2

plt.figure(figsize=(8, 8))
colors = ["steelblue", "orange"]
plt.scatter(X[:, 0], X[:, 1], c=y.ravel(), alpha=0.5, cmap=matplotlib.colors.ListedColormap(colors), edgecolors="black")
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
plt.show()

#取n個(gè)訓(xùn)練樣本败富,定義矩陣H
n = X.shape[0]
H = np.dot(y*X, (y*X).T)
##第二項(xiàng)我們定于-1的列向量
q = np.repeat([-1.0], n)[..., None]

##第一個(gè)約束條件,我們定義A是1×n的矩陣摩窃,種類只有2類兽叮,令b=0
A = y.reshape(1, -1)
b = 0.0

##第二個(gè)約束條件,我們構(gòu)造一個(gè)n×n單位矩陣G猾愿,和零向量h
G = np.negative(np.eye(n))
h = np.zeros(n)

##所有條件轉(zhuǎn)為CVXOPT對(duì)象
P = matrix(H)
q = matrix(q)
G = matrix(G)
h = matrix(h)
A = matrix(A)
b = matrix(b)
##調(diào)用線性規(guī)劃求解器
sol = solvers.qp(P, q, G, h, A, b)
alphas = np.array(sol["x"])  ##求出α

w = np.dot((y * alphas).T, X)[0]
S = (alphas > 1e-5).flatten()
b = np.mean(y[S] - np.dot(X[S], w.reshape(-1,1)))
##打印下結(jié)果
print("W:", w)
print("b:", b)

##可視化一下
xx = np.linspace(x_min, x_max)
a = -w[0]/w[1]
yy = a*xx - (b)/w[1]
 
margin = 1 / np.sqrt(np.sum(w**2))
yy_neg = yy - np.sqrt(1 + a**2) * margin
yy_pos = yy + np.sqrt(1 + a**2) * margin
 
plt.figure(figsize=(8, 8))
 
plt.plot(xx, yy, "b-")
plt.plot(xx, yy_neg, "m--")
plt.plot(xx, yy_pos, "m--")
 
colors = ["steelblue", "orange"]

plt.scatter(X[:, 0], X[:, 1], c=y.ravel(), alpha=0.5, cmap=matplotlib.colors.ListedColormap(colors), edgecolors="black")
 
plt.xlim(x_min, x_max)
plt.ylim(y_min, y_max)
 
plt.show()

##sklearn方法
from sklearn import svm

clf = svm.SVC(kernel="linear", C=10.0)
clf.fit(X, y.ravel())
w = clf.coef_[0]
b = clf.intercept_

print("W:", w)
print("b:", b)
#W: [1.29411744 0.82352928]
#b: [-3.78823471]

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末鹦聪,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蒂秘,更是在濱河造成了極大的恐慌椎麦,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,607評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件材彪,死亡現(xiàn)場(chǎng)離奇詭異观挎,居然都是意外死亡琴儿,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門嘁捷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來造成,“玉大人,你說我怎么就攤上這事雄嚣∩故海” “怎么了?”我有些...
    開封第一講書人閱讀 164,960評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵缓升,是天一觀的道長鼓鲁。 經(jīng)常有香客問我,道長港谊,這世上最難降的妖魔是什么骇吭? 我笑而不...
    開封第一講書人閱讀 58,750評(píng)論 1 294
  • 正文 為了忘掉前任淫半,我火速辦了婚禮圣贸,結(jié)果婚禮上盹舞,老公的妹妹穿的比我還像新娘你虹。我一直安慰自己,他們只是感情好必搞,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,764評(píng)論 6 392
  • 文/花漫 我一把揭開白布绩脆。 她就那樣靜靜地躺著刘莹,像睡著了一般顷链。 火紅的嫁衣襯著肌膚如雪目代。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,604評(píng)論 1 305
  • 那天嗤练,我揣著相機(jī)與錄音榛了,去河邊找鬼。 笑死潭苞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的真朗。 我是一名探鬼主播此疹,決...
    沈念sama閱讀 40,347評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼遮婶!你這毒婦竟也來了蝗碎?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,253評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤旗扑,失蹤者是張志新(化名)和其女友劉穎蹦骑,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體臀防,經(jīng)...
    沈念sama閱讀 45,702評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡眠菇,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,893評(píng)論 3 336
  • 正文 我和宋清朗相戀三年边败,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捎废。...
    茶點(diǎn)故事閱讀 40,015評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笑窜,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出登疗,到底是詐尸還是另有隱情排截,我是刑警寧澤,帶...
    沈念sama閱讀 35,734評(píng)論 5 346
  • 正文 年R本政府宣布辐益,位于F島的核電站断傲,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏智政。R本人自食惡果不足惜认罩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,352評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望女仰。 院中可真熱鬧猜年,春花似錦、人聲如沸疾忍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽一罩。三九已至杨幼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間聂渊,已是汗流浹背差购。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留汉嗽,地道東北人欲逃。 一個(gè)月前我還...
    沈念sama閱讀 48,216評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像饼暑,于是被迫代替她去往敵國和親稳析。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,969評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容