我是SVM新手,我試圖使用Python接口來libsvm來對包含mean和stddev的樣本進行分類。但是,我收到了無意義的結果。使用LibSVM計算平均值/ Stddev對的最近匹配
此任務不適合SVM使用,還是在使用libsvm時出現錯誤?以下是我用來測試的簡單Python腳本:
#!/usr/bin/env python
# Simple classifier test.
# Adapted from the svm_test.py file included in the standard libsvm distribution.
from collections import defaultdict
from svm import *
# Define our sparse data formatted training and testing sets.
labels = [1,2,3,4]
train = [ # key: 0=mean, 1=stddev
{0:2.5,1:3.5},
{0:5,1:1.2},
{0:7,1:3.3},
{0:10.3,1:0.3},
]
problem = svm_problem(labels, train)
test = [
({0:3, 1:3.11},1),
({0:7.3,1:3.1},3),
({0:7,1:3.3},3),
({0:9.8,1:0.5},4),
]
# Test classifiers.
kernels = [LINEAR, POLY, RBF]
kname = ['linear','polynomial','rbf']
correct = defaultdict(int)
for kn,kt in zip(kname,kernels):
print kt
param = svm_parameter(kernel_type = kt, C=10, probability = 1)
model = svm_model(problem, param)
for test_sample,correct_label in test:
pred_label, pred_probability = model.predict_probability(test_sample)
correct[kn] += pred_label == correct_label
# Show results.
print '-'*80
print 'Accuracy:'
for kn,correct_count in correct.iteritems():
print '\t',kn, '%.6f (%i of %i)' % (correct_count/float(len(test)), correct_count, len(test))
該域看起來相當簡單。我認爲,如果知道2.5的平均值意味着標籤1的訓練,那麼當它看到平均值2.4時,它應該返回標籤1作爲最可能的分類。但是,每個內核的準確度都爲0%。爲什麼是這樣?
有幾個附註,是否有一種方法可以隱藏libsvm在終端中轉儲的所有詳細訓練輸出?我搜索了libsvm的文檔和代碼,但是我找不到任何方法來關閉它。另外,我希望在我的稀疏數據集中使用簡單的字符串作爲鍵(例如{'mean':2.5,'stddev':3.5})。不幸的是,libsvm只支持整數。我嘗試使用字符串的長整型表示(例如'mean'== 1109110110971110),但libsvm似乎將這些截斷爲正常的32位整數。我看到的唯一解決方法是維護一個單獨的「密鑰」文件,將每個字符串映射到一個整數('mean'= 0,'stddev'= 1)。但顯然這將是一個痛苦,因爲我將不得不維護和持續第二個文件以及序列化的分類器。有沒有人看到更簡單的方法?
如果您刪除概率估計值(即刪除「概率= 1」,將prediction_probability更改爲僅預測並刪除pred_probability),則您的代碼似乎可行。 – dmcer 2010-04-02 19:51:29
@dmcer,輝煌。相反,只要每個標籤至少有兩個樣本,就可以保留概率估計值。奇怪它不適用於每個標籤的單個樣本。如果您發表評論作爲答案,那麼我會將其標記爲接受的答案。 – Cerin 2010-04-03 00:41:34