轉自:http://www.cnblogs.com/luyaoblog/p/6775342.html
除了在Matlab中使用PRTools工具箱中的svm算法,Python中一樣可以使用支持向量機做分類。因爲Python中的sklearn庫也集成了SVM算法,本文的運行環境是Pycharm。
一、導入sklearn算法包
Scikit-Learn庫已經實現了所有基本機器學習的算法,具體使用詳見官方文檔說明:http://scikit-learn.org/stable/auto_examples/index.html#support-vector-machines。
skleran中集成了許多算法,其導入包的方式如下所示,
邏輯迴歸:from sklearn.linear_model import LogisticRegression
樸素貝葉斯:from sklearn.naive_bayes import GaussianNB
K-近鄰:from sklearn.neighbors import KNeighborsClassifier
決策樹:from sklearn.tree import DecisionTreeClassifier
支持向量機:from sklearn import svm
二、sklearn中svc的使用
(1)使用numpy中的loadtxt讀入數據文件
loadtxt()的使用方法:
fname:文件路徑。eg:C:/Dataset/iris.txt。
dtype:數據類型。eg:float、str等。
delimiter:分隔符。eg:‘,’。
converters:將數據列與轉換函數進行映射的字典。eg:{1:fun},含義是將第2列對應轉換函數進行轉換。
usecols:選取數據的列。
以Iris蘭花數據集爲例子:
由於從UCI數據庫中下載的Iris原始數據集的樣子是這樣的,前四列爲特徵列,第五列爲類別列,分別有三種類別Iris-setosa, Iris-versicolor, Iris-virginica。
當使用numpy中的loadtxt函數導入該數據集時,假設數據類型dtype爲浮點型,但是很明顯第五列的數據類型並不是浮點型。
因此我們要額外做一個工作,即通過loadtxt()函數中的converters參數將第五列通過轉換函數映射成浮點類型的數據。
首先,我們要寫出一個轉換函數:
1
2
3
|
def iris_type(s): it = { 'Iris-setosa' : 0 , 'Iris-versicolor' : 1 , 'Iris-virginica' : 2 } return it[s] |
接下來讀入數據,converters={4: iris_type}中“4”指的是第5列:
1
2
|
path = u 'D:/f盤/python/學習/iris.data' #
數據文件路徑 data = np.loadtxt(path,
dtype = float ,
delimiter = ',' ,
converters = { 4 :
iris_type}) |
讀入結果:
(2)將Iris分爲訓練集與測試集
1
2
3
|
x,
y = np.split(data,
( 4 ,),
axis = 1 ) x = x[:,
: 2 ] x_train,
x_test, y_train, y_test = train_test_split(x,
y, random_state = 1 ,
train_size = 0.6 ) |
1. split(數據,分割位置,軸=1(水平分割) or 0(垂直分割))。
2. x = x[:, :2]是爲方便後期畫圖更直觀,故只取了前兩列特徵值向量訓練。
3. sklearn.model_selection.train_test_split隨機劃分訓練集與測試集。train_test_split(train_data,train_target,test_size=數字, random_state=0)
參數解釋:
train_data:所要劃分的樣本特徵集
train_target:所要劃分的樣本結果
test_size:樣本佔比,如果是整數的話就是樣本的數量
random_state:是隨機數的種子。
隨機數種子:其實就是該組隨機數的編號,在需要重複試驗的時候,保證得到一組一樣的隨機數。比如你每次都填1,其他參數一樣的情況下你得到的隨機數組是一樣的。但填0或不填,每次都會不一樣。隨機數的產生取決於種子,隨機數和種子之間的關係遵從以下兩個規則:種子不同,產生不同的隨機數;種子相同,即使實例不同也產生相同的隨機數。
(3)訓練svm分類器
1
2
3
|
#
clf = svm.SVC(C=0.1, kernel='linear', decision_function_shape='ovr') clf = svm.SVC(C = 0.8 ,
kernel = 'rbf' ,
gamma = 20 ,
decision_function_shape = 'ovr' ) clf.fit(x_train,
y_train.ravel()) |
kernel='linear'時,爲線性核,C越大分類效果越好,但有可能會過擬合(defaul C=1)。
kernel='rbf'時(default),爲高斯核,gamma值越小,分類界面越連續;gamma值越大,分類界面越“散”,分類效果越好,但有可能會過擬合。
decision_function_shape='ovr'時,爲one v rest,即一個類別與其他類別進行劃分,
decision_function_shape='ovo'時,爲one v one,即將類別兩兩之間進行劃分,用二分類的方法模擬多分類的結果。
(4)計算svc分類器的準確率
1
2
3
4
5
6
|
print clf.score(x_train,
y_train) #
精度 y_hat = clf.predict(x_train) show_accuracy(y_hat,
y_train, '訓練集' ) print clf.score(x_test,
y_test) y_hat = clf.predict(x_test) show_accuracy(y_hat,
y_test, '測試集' ) |
結果爲:
如果想查看決策函數,可以通過decision_function()實現
1
2
|
print 'decision_function:\n' ,
clf.decision_function(x_train) print '\npredict:\n' ,
clf.predict(x_train) |
結果爲:
decision_function中每一列的值代表距離各類別的距離。
(5)繪製圖像
1.確定座標軸範圍,x,y軸分別表示兩個特徵
1
2
3
4
5
|
x1_min,
x1_max = x[:, 0 ]. min (),
x[:, 0 ]. max () #
第0列的範圍 x2_min,
x2_max = x[:, 1 ]. min (),
x[:, 1 ]. max () #
第1列的範圍 x1,
x2 = np.mgrid[x1_min:x1_max: 200j ,
x2_min:x2_max: 200j ] #
生成網格採樣點 grid_test = np.stack((x1.flat,
x2.flat), axis = 1 ) #
測試點 #
print 'grid_test = \n', grid_testgrid_hat = clf.predict(grid_test) # 預測分類值grid_hat = grid_hat.reshape(x1.shape) # 使之與輸入的形狀相同 |
這裏用到了mgrid()函數,該函數的作用這裏簡單介紹一下:
假設假設目標函數F(x,y)=x+y。x軸範圍1~3,y軸範圍4~6,當繪製圖像時主要分四步進行:
【step1:x擴展】(朝右擴展):
[1 1 1]
[2 2 2]
[3 3 3]
【step2:y擴展】(朝下擴展):
[4 5 6]
[4 5 6]
[4 5 6]
【step3:定位(xi,yi)】:
[(1,4) (1,5) (1,6)]
[(2,4) (2,5) (2,6)]
[(3,4) (3,5) (3,6)]
【step4:將(xi,yi)代入F(x,y)=x+y】
因此這裏x1, x2 = np.mgrid[x1_min:x1_max:200j, x2_min:x2_max:200j]後的結果爲:
再通過stack()函數,axis=1,生成測試點
2.指定默認字體
1
2
|
mpl.rcParams[ 'font.sans-serif' ] = [u 'SimHei' ] mpl.rcParams[ 'axes.unicode_minus' ] = False |
3.繪製
1
2
3
4
5
6
7
8
9
10
11
12
|
cm_light = mpl.colors.ListedColormap([ '#A0FFA0' , '#FFA0A0' , '#A0A0FF' ]) cm_dark = mpl.colors.ListedColormap([ 'g' , 'r' , 'b' ]) plt.pcolormesh(x1,
x2, grid_hat, cmap = cm_light) plt.scatter(x[:, 0 ],
x[:, 1 ],
c = y,
edgecolors = 'k' ,
s = 50 ,
cmap = cm_dark) #
樣本 plt.scatter(x_test[:, 0 ],
x_test[:, 1 ],
s = 120 ,
facecolors = 'none' ,
zorder = 10 ) #
圈中測試集樣本 plt.xlabel(u '花萼長度' ,
fontsize = 13 ) plt.ylabel(u '花萼寬度' ,
fontsize = 13 ) plt.xlim(x1_min,
x1_max) plt.ylim(x2_min,
x2_max) plt.title(u '鳶尾花SVM二特徵分類' ,
fontsize = 15 ) #
plt.grid() plt.show() |
pcolormesh(x,y,z,cmap)這裏參數代入x1,x2,grid_hat,cmap=cm_light繪製的是背景。
scatter中edgecolors是指描繪點的邊緣色彩,s指描繪點的大小,cmap指點的顏色。
xlim指圖的邊界。
最終結果爲:
源碼:
#
-*- coding:utf-8 -*-
#
-*- coding:utf-8 -*-
from
sklearn
import
svm
import
numpy
as np
import
matplotlib.pyplot
as plt
import
matplotlib
as mpl
from
matplotlib
import
colors
from
sklearn.model_selection
import
train_test_split
def
iris_type(s):
it
=
{
'Iris-setosa'
:
0
,
'Iris-versicolor'
:
1
,
'Iris-virginica'
:
2
}
return
it[s]
def
show_accuracy(y_hat,
y_test, param):
pass
path
=
'F:\\Test\\iris.data'
#
數據文件路徑
data
=
np.loadtxt(path,
dtype
=
float
,
delimiter
=
','
,
converters
=
{
4
:
iris_type})
x,
y
=
np.split(data,
(
4
,),
axis
=
1
)
x
=
x[:,
:
2
]
x_train,
x_test, y_train, y_test
=
train_test_split(x,
y, random_state
=
1
,
train_size
=
0.6
)
#
clf = svm.SVC(C=0.1, kernel='linear', decision_function_shape='ovr')
clf
=
svm.SVC(C
=
0.8
,
kernel
=
'rbf'
,
gamma
=
20
,
decision_function_shape
=
'ovr'
)
clf.fit(x_train,
y_train.ravel())
print
clf.score(x_train,
y_train)
#
精度
y_hat
=
clf.predict(x_train)
show_accuracy(y_hat,
y_train,
'訓練集'
)
print
clf.score(x_test,
y_test)
y_hat
=
clf.predict(x_test)
show_accuracy(y_hat,
y_test,
'測試集'
)
print
'decision_function:\n'
,
clf.decision_function(x_train)
print
'\npredict:\n'
,
clf.predict(x_train)
x1_min,
x1_max
=
x[:,
0
].
min
(),
x[:,
0
].
max
()
#
第0列的範圍
x2_min,
x2_max
=
x[:,
1
].
min
(),
x[:,
1
].
max
()
#
第1列的範圍
x1,
x2
=
np.mgrid[x1_min:x1_max:
200j
,
x2_min:x2_max:
200j
]
#
生成網格採樣點
grid_test
=
np.stack((x1.flat,
x2.flat), axis
=
1
)
#
測試點
mpl.rcParams[
'font.sans-serif'
]
=
[u
'SimHei'
]
mpl.rcParams[
'axes.unicode_minus'
]
=
False
cm_light
=
mpl.colors.ListedColormap([
'#A0FFA0'
,
'#FFA0A0'
,
'#A0A0FF'
])
cm_dark
=
mpl.colors.ListedColormap([
'g'
,
'r'
,
'b'
])
#
print 'grid_test = \n', grid_test
grid_hat
=
clf.predict(grid_test)
#
預測分類值
grid_hat
=
grid_hat.reshape(x1.shape)
#
使之與輸入的形狀相同
alpha
=
0.5
plt.pcolormesh(x1,
x2, grid_hat, cmap
=
cm_light)
#
預測值的顯示
#
plt.scatter(x[:, 0], x[:, 1], c=y, edgecolors='k', s=50, cmap=cm_dark) # 樣本
plt.plot(x[:,
0
],
x[:,
1
],
'o'
,
alpha
=
alpha,
color
=
'blue'
,
markeredgecolor
=
'k'
)
plt.scatter(x_test[:,
0
],
x_test[:,
1
],
s
=
120
,
facecolors
=
'none'
,
zorder
=
10
)
#
圈中測試集樣本
plt.xlabel(u
'花萼長度'
,
fontsize
=
13
)
plt.ylabel(u
'花萼寬度'
,
fontsize
=
13
)
plt.xlim(x1_min,
x1_max)
plt.ylim(x2_min,
x2_max)
plt.title(u
'鳶尾花SVM二特徵分類'
,
fontsize
=
15
)
#
plt.grid()
plt.show()