我刚接触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)。但显然,这会很麻烦,因为我必须维护和持久化除序列化分类器之外的第二个文件。有人看到更简单的方法吗?