私はSVMを初めて使用し、Pythonインターフェイスを使用してlibsvmを使用して、平均値と標準偏差を含むサンプルを分類しようとしています。しかし、私は無意味な結果を得ています。
このタスクは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)。しかし、シリアル化された分類子と一緒に2番目のファイルを維持および永続化する必要があるため、明らかにそれは面倒です。誰かがもっと簡単な方法を見ていますか?