本示例是乙個簡單的試驗,甚至連資料集都不用額外準備,旨在加深對svm和核函式的理解,並看看如何利用 scikit-learn 中的svm,
編譯環境是 jupyter notebook, 可以通過安裝 anaconda,匯入 scikit-learn 庫可以很容易實現,github示例**。本例中變沒有用外部資料集,而是隨機生成的點,大家在理解演算法和 scikit-learn 熟練使用後,可以嘗試匯入有具體意義的資料集,看看svm的效果。
svm_demo_with_sklearn.ipynb
**中主要分為兩個部分
首先匯入依賴包
%matplotlib inline
import numpy as np
import matplotlib.pyplot as plt
import seaborn;
from sklearn.linear_model import linearregression
from scipy import stats
import pylab as pl
seaborn.set()
支援向量機是解決分類和回歸問題非常強大的有監督學習演算法。簡單說來,linear的svm做的事情就是在不同類別的「資料團」之間劃上一條線,對線性可分集,總能找到使樣本正確劃分的分介面,而且有無窮多個,哪個是最優? 必須尋找一種最優的分界準則,svm試圖找到一條最健壯的線,什麼叫做最健壯的線?其實就是離2類樣本點最遠的線。
from sklearn.datasets.samples_generator import make_blobs
x, y = make_blobs(n_samples=50, centers=2,
random_state=0, cluster_std=0.60)
xfit = np.linspace(-1, 3.5)
plt.scatter(x[:, 0], x[:, 1], c=y, s=50, cmap='spring')
# 其實隨意給定3組引數,就可以畫出3條不同的直線,但它們都可以把圖上的2類樣本點分隔開
for m, b, d in [(1, 0.65, 0.33), (0.5, 1.6, 0.55), (-0.2, 2.9, 0.2)]:
yfit = m * xfit + b
plt.plot(xfit, yfit, '-k')
plt.fill_between(xfit, yfit - d, yfit + d, edgecolor='none', color='#aaaaaa', alpha=0.4)
plt.xlim(-1, 3.5);
from sklearn.svm import svc
clf = svc(kernel='linear')
clf.fit(x, y)
def plot_svc_decision_function(clf, ax=none):
"""plot the decision function for a 2d svc"""
if ax is none:
ax = plt.gca()
x = np.linspace(plt.xlim()[0], plt.xlim()[1], 30)
y = np.linspace(plt.ylim()[0], plt.ylim()[1], 30)
y, x = np.meshgrid(y, x)
p = np.zeros_like(x)
for i, xi in enumerate(x):
for j, yj in enumerate(y):
p[i, j] = clf.decision_function([xi, yj])
# plot the margins
ax.contour(x, y, p, colors='k',
levels=[-1, 0, 1], alpha=0.5,
linestyles=['--', '-', '--'])
sklearn的svm裡面會有乙個屬性support_vectors_,標示「支援向量」,也就是樣本點裡離超平面最近的點,組成的。
咱們來畫個圖,把超平面和支援向量都畫出來。
plt.scatter(x[:, 0], x[:, 1], c=y, s=50, cmap='spring')
plot_svc_decision_function(clf)
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
s=200, facecolors='none');
可以用ipython的interact
函式來看看樣本點的分布,會怎麼樣影響超平面:
from ipython.html.widgets import interact
def plot_svm(n=100):
x, y = make_blobs(n_samples=200, centers=2,
random_state=0, cluster_std=0.60)
x = x[:n]
y = y[:n]
clf = svc(kernel='linear')
clf.fit(x, y)
plt.scatter(x[:, 0], x[:, 1], c=y, s=50, cmap='spring')
plt.xlim(-1, 4)
plt.ylim(-1, 6)
plot_svc_decision_function(clf, plt.gca())
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
s=200, facecolors='none')
interact(plot_svm, n=[10, 200], kernel='linear');
對於非線性可切分的資料集,要做分割,就要借助於核函式了簡單一點說呢,核函式可以看做對原始特徵的乙個對映函式,
不過svm不會傻乎乎對原始樣本點做對映,它有更巧妙的方式來保證這個過程的高效性。
下面有乙個例子,你可以看到,線性的kernel(線性的svm)對於這種非線性可切分的資料集,是無能為力的。
from sklearn.datasets.samples_generator import make_circles
x, y = make_circles(100, factor=.1, noise=.1)
clf = svc(kernel='linear').fit(x, y)
plt.scatter(x[:, 0], x[:, 1], c=y, s=50, cmap='spring')
plot_svc_decision_function(clf);
然後強大的高斯核/radial basis function就可以大顯身手了:
r = np.exp(-(x[:, 0] ** 2 + x[:, 1] ** 2))
from mpl_toolkits import mplot3d
def plot_3d(elev=30, azim=30):
ax = plt.subplot(projection='3d')
ax.scatter3d(x[:, 0], x[:, 1], r, c=y, s=50, cmap='spring')
ax.view_init(elev=elev, azim=azim)
ax.set_xlabel('x')
ax.set_ylabel('y')
ax.set_zlabel('r')
interact(plot_3d, elev=[-90, 90], azip=(-180, 180));
你在上面的圖上也可以看到,原本在2維空間無法切分的2類點,對映到3維空間以後,可以由乙個平面輕鬆地切開了。
而帶rbf核的svm就能幫你做到這一點:
clf = svc(kernel='rbf')
clf.fit(x, y)
plt.scatter(x[:, 0], x[:, 1], c=y, s=50, cmap='spring')
plot_svc_decision_function(clf)
plt.scatter(clf.support_vectors_[:, 0], clf.support_vectors_[:, 1],
s=200, facecolors='none');
MIPS彙編小貼示
各欄位含義 op 指令基本操作,稱為操作碼。rs 第乙個源運算元暫存器。rt 第二個源運算元暫存器。rd 存放操作結果的目的運算元。shamt 位移量 funct 函式,這個字段選擇op操作的某個特定變體。有32個通用暫存器,0到 31 0 即 zero,該暫存器總是返回零,為0這個有用常數提供了乙...
C 介面的顯示實現和隱示實現
介面的實現很多人都知道,但介面的實現方式分顯示實現和隱示實現不知道是不是很多人知道呢!但我覺的公司技術部裡很少提到這個,就想起來寫寫這篇blogs。目前常用的方式 public inte ce ireview public class shopreview ireview 這種方式是隱示實現 ire...
C 介面的顯示實現和隱示實現
介面的實現很多人都知道,但介面的實現方式分顯示實現和隱示實現不知道是不是很多人知道呢!但我覺的公司技術部裡很少提到這個,就想起來寫寫這篇blogs。目前常用的方式 public inte ce ireview public class shopreview ireview 這種方式是隱示實現 ire...