使用 LibSVM 计算与均值/标准差对最接近的匹配项

我是 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 defaultdictfrom 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 '-'*80print '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)。但显然这将很麻烦,因为我必须维护和持久化第二个文件以及序列化的分类器。有人看到更简单的方法吗?


回答:

问题似乎来自将多类预测与概率估计相结合。

如果您将代码配置为不进行概率估计,它实际上可以工作,例如:

<snip># 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) # Here -> rm probability = 1  model = svm_model(problem, param)  for test_sample,correct_label in test:      # Here -> change predict_probability to just predict      pred_label = model.predict(test_sample)      correct[kn] += pred_label == correct_label</snip>

通过此更改,我得到:

--------------------------------------------------------------------------------Accuracy:        polynomial 1.000000 (4 of 4)        rbf 1.000000 (4 of 4)        linear 1.000000 (4 of 4)

如果将训练集中的数据加倍(即,包含每个数据点两次),则使用概率估计进行预测确实有效。但是,我找不到任何方法来参数化模型,以便多类预测与概率一起仅适用于原始的四个训练点。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注