Я новичок в 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-битных целых чисел. Единственный обходной путь, который я вижу, - это поддерживать отдельный файл «ключа», который сопоставляет каждую строку с целым числом («среднее» = 0, «stddev» = 1). Но очевидно, что это будет больно, так как мне придется поддерживать и сохранять второй файл вместе с сериализованным классификатором. Кто-нибудь видит более простой способ?