libsvm
具有特定的数据格式,每一行都是一个训练/测试向量,其形式为
标签索引 0:值 0 索引 1:值 1 ... 索引:值
因此,在最“天真的”方法中,您只需通过连接连续的行将矩阵表示形式转换为行表示形式,因此图像就像
010
011
000
会成为
010011000
以及 libsvm 格式(假设我们用“5”标记它):
5 0:0 1:1 2:0 3:0 4:1 5:1 6:0 7:0 8:0 9:0
由于 libsvm 支持“稀疏”表示,因此您可以省略带有“0”的值
5 1:1 4:1 5:1
这是手动方式,示例数据位于此处:http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/binary/a1a
最简单的“自动”方法是将数据表示为 .csv 格式(再次将数据转换为行格式,然后转换为 .csv),这是非常标准的方法:
标签,PIXEL_0,PIXEL_1,...,PIXEL_N
...
然后用这个程序进行转换
/* convert cvs data to libsvm/svm-light format */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char buf[10000000];
float feature[100000];
int main(int argc, char **argv)
{
FILE *fp;
if(argc!=2) { fprintf(stderr,"Usage %s filename\n",argv[0]); }
if((fp=fopen(argv[1],"r"))==NULL)
{
fprintf(stderr,"Can't open input file %s\n",argv[1]);
}
while(fscanf(fp,"%[^\n]\n",buf)==1)
{
int i=0,j;
char *p=strtok(buf,",");
feature[i++]=atof(p);
while((p=strtok(NULL,",")))
feature[i++]=atof(p);
// --i;
/*
if ((int) feature[i]==1)
printf("-1 ");
else
printf("+1 ");
*/
// printf("%f ", feature[1]);
printf("%d ", (int) feature[0]);
for(j=1;j<i;j++)
printf(" %d:%f",j,feature[j]);
printf("\n");
}
return 0;
}
训练和测试文件的结构完全相同,只需将数据按一定比例(3:1 或 9:1)随机分割到文件中training
and testing
,但请记住在每个文件中包含每个类的平衡数量的训练向量。
特别是 - 你的数据看起来有点像MNIST数据集,如果是这种情况,这个已经为libsvm准备好了:
http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass.html
MNIST 培训:http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/mnist.scale.bz2
MNIST 测试:http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/multiclass/mnist.scale.t.bz2
如果您的数据可以的话,将图像转换为 [0,1] 区间内的实值图像将比二进制数据(丢失大量信息)更有价值。
EDIT
举个例子,如果你的图像是 8 位灰度图像,那么每个像素实际上是一个数字v
0 到 255 之间。您现在正在做的是一些阈值处理,将 1 设置为v > T
0 表示v <= T
,而将这些值映射到实际值将为模型提供更多信息。可以通过简单的挤压来完成v / 255
。结果,所有值都在[0,1]
间隔,但也有“之间”的值,例如0.25
etc.