《集體智慧編程》關於婚介數據集的SVM分類
轉自:http://muilpin.blog.163.com/blog/static/165382936201131875249123/
作者寫這本書的年代已經很久遠了,於是里面使用到的LIBSVM接口與現在也非常不一樣:
1.書本上提高的官方下載svm已經更新至3.x版本,不適合(研究了很久,發現接口很大不一樣,建議閱讀者不要使用最新版本,如果實在需要請參考本文第4點)
2.網上有人用libsvm2.89在Python2.6成功。(一定要libsvm2.89搭配python2.6,其他版本都不能成功,我就是浪費了大量時間在這里!)
兩步:
1.將libsvm-2.89\windows\python目錄下的svmc.pyd文件復制到C:\Python26\DLLs;
2.將libsvm-2.89\python目錄下的svm.py放到C:\Python26\Lib目錄里。
from svm import * 成功(本點非本人總結,但附上libsvm2.89的下載地址:http://ishare.iask.sina.com.cn/f/6344231.html)
from svm import * prob = svm_problem([1,-1] ,[[1,0,1] , [-1,0,-1]] ) param = svm_parameter(kernel_type = LINEAR , C = 10) ## training the model m = svm_model(prob ,param) #testing the model m.predict( [1, 1 , 1] )
3.如果想要超級簡單的了解關於SVM的知識,可以參考書籍提供下載svm官網中的guide文件,寫的挺精辟的;
4.本人花了一個下午的時間使用了svm3.19版本,如果你實在堅持使用3.x版本,可以參考以下的方法:
(1)下載libsvm代碼包,解壓后將文件夾Window下的libsvm\window\libsvm.dll文件 復制到C:\WINDOWS\System32路徑下;
(2)將代碼包里面的文件夾Python中的svmutil.py文件復制到你的工作目錄(如果想用svm.py,同理操作,以下以svmutil.py舉例,區別請看python文件夾下的README!)
即把svmutil.py和svm.py兩個文件拉到eclipse工程目錄里
(3)與書上不同的地方在於:svm_parameter()函數的使用方法更新了,方法如下說明:
用法:
param = svm_parameter('Training Opition')
實例:param = svm_parameter('-s 3 -c 5 -h 0')
其中里面的參數如下詳細說明:
options:
-s svm_type : set type of SVM (default 0)
0 -- C-SVC
1 -- nu-SVC
2 -- one-class SVM
3 -- epsilon-SVR
4 -- nu-SVR
-t kernel_type : set type of kernel function
(default 2)
0 -- linear: u'*v
1 -- polynomial: (gamma*u'*v + coef0)^degree
2 -- radial basis function: exp(-gamma*|u-v|^2)
3 -- sigmoid: tanh(gamma*u'*v + coef0)
4 -- precomputed kernel (kernel values in training_set_file)
-d degree : set degree in kernel function (default 3)
-g gamma : set gamma in kernel function (default 1/num_features)
-r coef0 : set coef0 in kernel function (default 0)
-c cost : set the parameter C of C-SVC, epsilon-SVR, and nu-SVR (default 1)
-n nu : set the parameter nu of nu-SVC, one-class SVM, and nu-SVR (default 0.5)
-p epsilon : set the epsilon in loss function of epsilon-SVR (default 0.1)
-m cachesize : set cache memory size in MB (default 100)
-e epsilon : set tolerance of termination criterion (default 0.001)
-h shrinking : whether to use the shrinking heuristics, 0 or 1 (default 1)
-b probability_estimates : whether to train a SVC or SVR model for probability estimates, 0 or 1 (default 0)
-wi weight : set the parameter C of class i to weight*C, for C-SVC (default 1)
-v n: n-fold cross validation mode
-q : quiet mode (no outputs)
(4)svm_model已經成為一個類,不能直接調用,但可以通過以下兩種方法實現對數據集的建模:
>>> model = svm_train(prob, param)
>>> model = svm_load_model('model_file_name') #從保存的model中獲取模型
from svm import * from svmutil import * #構造svm訓練數據和svm參數(包括核函數和交叉驗證) data = svm_problem([1,-1] ,[[1,0,1] , [-1,0,-1]] ) #元組第一個列表表示分類種類,第二個列表表示數據 # param = svm_parameter(kernel_type = 'LINEAR' ,C = 10) #使用線性核函數,交叉驗證用10 #對svm模型訓練 ''' 參數-t表示kernel函數,-c表示交叉驗證用多少 -t kernel_type : set type of kernel function (default 2) 0 -- linear: u'*v 1 -- polynomial: (gamma*u'*v + coef0)^degree 2 -- radial basis function: exp(-gamma*|u-v|^2) ''' param = svm_parameter('-c 10 -h 0') #默認選擇RBF核函數 model = svm_train(data, param) #測試 svm_predict([1],[[1,1,1]],model) #predict有三個參數,第一個參數是你預測的類型,第二個是你輸入要預測的數據,最后一個參數就是訓練模型
結果是:
optimization finished, #iter = 1 nu = 0.107467 obj = -1.074672, rho = 0.000000 nSV = 2, nBSV = 0 Total nSV = 2 Accuracy = 100% (1/1) (classification)
(5)另外有一定需要特別注意的是,書本上的這種寫法已經不合適了:
>>> newrow=[28.0,-1,-1,26.0,-1,1,2,0.8] # Man doesn't want children, woman does
>>> m.predict(scalef(newrow))
可以更新為:
>>>newrow=[(28.0,-1,-1,26.0,-1,1,2,0.8)]
#注意里面多了一個元組符號'()'
>>>svm_predict([0]*len(newrow),newrow,
m) #注意m代表svm_train出來的模型,第一個參數的解釋如下:
a list/tuple of l true labels (type must be int/double). It is used for calculating the accuracy. Use [0]*len(x) if true labels are unavailable. 即第一個參數表示你對newrow的預測值。
5.如果你下載了svm3.x版本,就需要詳細看下載包里面的README文件,里面有提到各種函數的用法,但解釋感覺不全面;
6.另外書中第9章還有一些錯誤如下:
def scaledata(rows):
low=[999999999.0]*len(rows[0].data)
high=[-999999999.0]*len(rows[0].data)
# Find the lowest and highest values
for row in rows:
d=row.data
for i in range(len(d)):
if d[i]<low[i]: low[i]=d[i]
if d[i]>high[i]: high[i]=d[i]
# Create a function that scales data
def scaleinput(d):
return [(d.data[i]-low[i])/(high[i]-low[i])for i in range(len(low))] #可能出錯(1)(2)
# Scale all the data
newrows=[matchrow(scaleinput(row.data)+[row.match])for row in rows]
# Return the new data and the function
return newrows,scaleinput
可能出錯(1):如果使用作者前面計算位置距離的函數milesdistance():
def milesdistance(a1,a2):
return 0
分母則會為0出錯,我的做法如下:1.產生[0,1]隨機數;2.分母另外加上0.000000001;但使用Yahoo來獲取距離是可以的!
出錯的地方(2):d.data[i]出錯,應該更改為d[i]
還有附錄B中計算點積的公式有誤:
def veclength(a):
return sum([a[i] for i in range(len(a))])**.5
一個多維向量的模應該為a[i]**2而非a[i];
