libSVM的C#接口与使用

  台湾林智仁教授的libSVM工具大家都已经非常熟悉了,的确非常的好用。以前大多是在matlab下面用libSVM做训练以及分类,这个比较好做而且网上很多例程可以借鉴,但在C#里面怎么用这个工具的介绍就很少了。前段时间正好在项目里面要用到这个,索性研究了下发现还是比较简单的,这个是libSVM的主页:http://www.csie.ntu.edu.tw/~cjlin/libsvm/,最新版本是3.1。

  其实在主页中给出了几个C#版本的接口,libSVMWrapperSVM.NET.NET wrapper等,都试用了下发现第一个是比较好用的,我也是把第一个用到了项目中。用过libSVM的童鞋都知道分类器参数的选择对分类结果的影响是非常大的,另外一个因素是如果原特征需要做scale的话,scale也是非常重要的。libSVM提供了2个py的执行文件来进行参数的选择:grid.py和easy.py,其中前者是单独用来进行参数寻优的,后者则是全自动的进行处理,包括训练样本的scale,参数寻优,训练,以及对测试样本的分类。他们的用法网上很多,这里就不详述了。有了这些基本知识,就可以来讲讲怎么在C#里面来用libSVM了。libSVMWrapper本身提供了trainAuto的方法,可以自动对参数进行寻优,但速度实在是不敢恭维,更重要的是他没有提供scale的方法,这个就有点不爽了,既然作者提供了如此方便的参数选择工具就一定不能错过,而且在实际工作中,对于分类器的训练本身就可以单独来进行处理,所以我采用如下的处理方式:

(1)训练样本的特征的计算在C#中完成,然后以文本形式保存到本地;

(2)利用grid.py或者easy.py来进行参数寻优,输出的svm的参数与SV会以.model格式保存,如果是选用easy.py的话还会有一个.range文件;

(3)以后对于每一个测试样本都可以直接在C#中读取.model和.range(如果有的话),对测试样本进行分类。

libSVMWrapper中提供了对于特征与文本之间的相互转换,也提供了对于.model格式的读取方法,这些方法都是和libSVM自己的格式兼容。但缺少对于.range格式的读取,以及在predict的时候用range来scale测试样本。缺少的这部分需要额外的编写代码来实现;

 1     class libSvmScale
2 {
3 /// <summary>
4      /// Read LibSVM range date file.
5      /// The file is generated using svm-scale.exe tool of LibSVM
6      /// Note: y scaling is not supported.
7      /// </summary>
8      /// <param name="range_file_path">The file path generated using svm-scale.exe</param>
9      /// <param name="targe_min">The targe min</param>
10      /// <param name="targe_max">The targe max</param>
11      /// <param name="features_min">The minimums of all features</param>
12      /// <param name="features_max">The maximums of all features</param>
13 public static void ReadRange(string range_file_path, out double targe_min, out double targe_max, out double[] features_min, out double[] features_max)
14 {
15 string line; string[] words; int id, id_max = -1; double min, max;
16 List<int> ids = new List<int>(); List<double> mins = new List<double>(), maxs = new List<double>();
17 using (System.IO.StreamReader sr = new System.IO.StreamReader(range_file_path))
18 {
19 line = sr.ReadLine(); //Read x
20 line = sr.ReadLine(); //Target
21 words = line.Split(); targe_min = double.Parse(words[0]); targe_max = double.Parse(words[1]);
22
23 while ((line = sr.ReadLine()) != null) //Read min, max for each feature
24 {
25 words = line.Split();
26 id = int.Parse(words[0]); min = double.Parse(words[1]); max = double.Parse(words[2]);
27
28 ids.Add(id); mins.Add(min); maxs.Add(max);
29 if (id > id_max) id_max = id;
30 }
31 }
32
33 features_min = new double[id_max]; features_max = new double[id_max];
34 for (int i = 0; i < ids.Count; i++)
35 {
36 features_min[ids[i] - 1] = mins[i];
37 features_max[ids[i] - 1] = maxs[i];
38 }
39 }
40
41 /// <summary>
42      /// make scaling to the test data unit
43      /// </summary>
44      /// <param name="orig_data">test data unit</param>
45      /// <param name="targe_min">The targe min</param>
46      /// <param name="targe_max">The targe max</param>
47      /// <param name="features_min">The minimums of all features</param>
48      /// <param name="features_max">The maximums of all features</param>
49      /// <returns>scaled data</returns>
50 public static List<SortedDictionary<int, double>> ScaleData(SortedDictionary<int, double>[] orig_data,
51 double targe_min, double targe_max, double[] features_min, double[] features_max)
52 {
53 int feature_n = features_min.Length;
54 double[] k = new double[feature_n];
55 for (int i = 0; i < feature_n; i++)
56 k[i] = (targe_max - targe_min) / (features_max[i] - features_min[i]);
57
58 int sample_n = orig_data.Length;
59 List<SortedDictionary<int, double>> data = new List<SortedDictionary<int, double>>();
60 for (int m = 0; m < sample_n; m++)
61 {
62 SortedDictionary<int, double> scaled_data = new SortedDictionary<int,double>();
63 for (int i = 0; i < feature_n; i++)
64 {
65 if (double.IsNaN(orig_data[m][i + 1])) continue;
66 scaled_data.Add(i + 1, k[i] * (orig_data[m][i + 1] - features_min[i]) + targe_min);
67 }
68 //scaled_data.Add(-1, 0);
69 data.Add(scaled_data);
70 }
71 return data;
72 }
73
74 /// <summary>
75      /// make scaling to each test data
76      /// </summary>
77     /// <param name="orig_data">test data</param>
78      /// <param name="targe_min">The targe min</param>
79      /// <param name="targe_max">The targe max</param>
80      /// <param name="features_min">The minimums of all features</param>
81      /// <param name="features_max">The maximums of all features</param>
82      /// <returns>scaled data</returns>
83 public static SortedDictionary<int, double> ScaleData(SortedDictionary<int, double> orig_data,
84 double targe_min, double targe_max, double[] features_min, double[] features_max)
85 {
86 int feature_n = features_min.Length;
87 double[] k = new double[feature_n];
88 for (int i = 0; i < feature_n; i++)
89 k[i] = (targe_max - targe_min) / (features_max[i] - features_min[i]);
90
91 SortedDictionary<int, double> scaled_data = new SortedDictionary<int, double>();
92 for (int i = 0; i < feature_n; i++)
93 {
94 scaled_data.Add(i + 1, k[i] * (orig_data[i + 1] - features_min[i]) + targe_min);
95 }
96 return scaled_data;
97 }
98 }

 

具体的预测部分就不说了,参考libSVMWrapper中的说明即可。

 

转载于:https://www.cnblogs.com/Alex-Zhu/archive/2011/12/08/2280465.html

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值