我是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