emm
前几天使用一个如下图的libsvm的c#封装库进行多分类任务的demo,记录一下步骤;
Step
0、整理数据至合理范围(进行归一化处理,这里的数据在matlab中已经处理好了);
1、处理数据为libsvm能够识别的格式,可以使用libsvm提供的FormatDataLibsvm.xls进行快速处理,这里使用matlab进行文件写操作处理:
load('NIAB_shannonE_new.mat'); %加载文件
A=NIAB_shannonE_new;
fp = fopen('mydataset.txt','w'); %打开或创建新文件,没有则创建
for i=1:11052
v1=A(1,i); %特征值
v2=A(2,i);
v3=A(3,i);
v4=A(4,i);
v5=A(5,i);
v6=A(6,i); %标签
%格式化数据
formatSpec = '%d 1:%f 2:%f 3:%f 4:%f 5:%f \r\n';
fprintf(fp,formatSpec,v6,v1,v2,v3,v4,v5); %输出文件
end
fclose(fp); %关闭文件
转换格式后数据:
2、使用subset.py划分训练集和测试集:0.8:0.2(11052个样本数据–> 8842:2210)
cd SVMTest
//划分数据集
python subset.py -s 0 mydataset.txt 8842 dataset_train.txt dataset_test.txt
3、使用训练样本进行训练,并使用测试样本进行测试来调整参数;
code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
//添加LibSVM命名空间
//参考:https://github.com/ccerhan/LibSVMsharp/blob/master/LibSVMsharp.Examples.Classification/Program.cs
using LibSVMsharp.Helpers;
using LibSVMsharp.Extensions;
using LibSVMsharp;
namespace svmTest_CSharp
{
class Program
{
static void PrintFunction(string output)
{
Console.Write(output);
}
static void Main(string[] args)
{
计算模型
//设置用于访问输出日志的 print 函数
SVM.SetPrintStringFunction(PrintFunction);
//加载数据集
SVMProblem trainSet = SVMProblemHelper.Load("dataset_train.txt");
SVMProblem testSet = SVMProblemHelper.Load("dataset_test.txt");
//选择SVM参数
SVMParameter parameter = new SVMParameter();
parameter.Type = SVMType.C_SVC;
parameter.Kernel = SVMKernelType.RBF;
parameter.CacheSize = 2000;
//调整参数至合适值
parameter.C = 16;
parameter.Gamma = 1.0;
//进行5折交叉验证判断参数设置是否正确
double[] crossValidationResults;
int nFold = 5;
trainSet.CrossValidation(parameter, nFold, out crossValidationResults);
//评估交叉验证结果,如果结果不好,重新设置参数C与Gamma
double crossValidationAccuracy = trainSet.EvaluateClassificationProblem(crossValidationResults);
//训练模型
SVMModel model = trainSet.Train(parameter);
//保存模型
SVM.SaveModel(model, "mymodel.txt");
//测试
double[] testResults = testSet.Predict(model);
//评估
int[,] confusionMatrix;
double testAccuracy = testSet.EvaluateClassificationProblem(testResults, model.Labels, out confusionMatrix);
//输出评估结果
Console.WriteLine("\n\ncrossValidationAccuracy: {0}", crossValidationAccuracy);
Console.WriteLine("\nTest Accuracy:{0}", testAccuracy);
///预测输出
Console.WriteLine("请输入数据值(demo: a-b-c-d-e,换行结束):");
string str = Console.ReadLine(); //读入一行字符串
string[] strValues = str.Split('-'); //字符串分割
double[] values = new double[strValues.Length];
Console.Write("输入的数据为:");
for(int i = 0; i < strValues.Length; i++)
{
values[i] = double.Parse(strValues[i]);
Console.Write(" {0} ", values[i]);
}
Console.Write("\n");
SVMNode[] x = new SVMNode[5];
for(int i =0; i < 5; i++)
{
x[i] = new SVMNode(); //申请内存空间
x[i].Value = values[i];
x[i].Index = i + 1; //索引从1开始
}
//预测
double prelabel = SVM.Predict(model, x);
Console.WriteLine("这组数据的预测标签为:{0}", (int)prelabel);
Console.ReadKey();
}
}
}
出现的小问题:
1、编译平台选择anycpu;
2、error: libsvm.dll找不到,复制该dll到bin目录下
效果
参数简单调整后,分类效果如图: