文章目录

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目录下


效果

参数简单调整后,分类效果如图: