用c语言写一个基于svm对葡萄酒品质分类的程序
时间: 2023-06-26 17:07:12 浏览: 158
基于SVM神经网络的葡萄酒种类识别代码.rar
以下是一个简单的基于SVM的葡萄酒品质分类程序,使用了libsvm库:
```
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "svm.h"
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))
struct svm_node *x;
int max_nr_attr = 64;
struct svm_model* model;
int predict_probability=0;
void exit_input_error(int line_num)
{
fprintf(stderr,"Wrong input format at line %d\n", line_num);
exit(1);
}
void predict(FILE *input, FILE *output)
{
int correct = 0;
int total = 0;
double error = 0;
double sumv = 0, sumy = 0, sumvv = 0, sumyy = 0, sumvy = 0;
int svm_type=svm_get_svm_type(model);
int nr_class=svm_get_nr_class(model);
double *prob_estimates=NULL;
int j;
if (predict_probability)
{
if (svm_type==NU_SVR || svm_type==EPSILON_SVR)
fprintf(output,"labels 1 2 3 actual predicted prob_estimates\n");
else
fprintf(output,"labels 1 2 3 ... actual predicted prob_estimates\n");
}
else
fprintf(output,"labels 1 2 3 ... actual predicted\n");
while(1)
{
int i = 0;
double target_label, predict_label;
fscanf(input,"%lf",&target_label);
if(feof(input)) break;
while(1)
{
int index;
double value;
fscanf(input,"%d:%lf",&index,&value);
if(index == -1) break;
while(index > i)
{
x[i].index = i+1;
x[i].value = 0;
i++;
}
x[i].index = index;
x[i].value = value;
i++;
}
x[i].index = -1;
if (predict_probability && (svm_type==C_SVC || svm_type==NU_SVC))
{
predict_label = svm_predict_probability(model,x,prob_estimates);
fprintf(output,"%g ",target_label);
for(j=0;j<nr_class;j++)
fprintf(output,"%g ",prob_estimates[j]);
fprintf(output,"%g\n",predict_label);
}
else
{
predict_label = svm_predict(model,x);
fprintf(output,"%g ",target_label);
fprintf(output,"%g\n",predict_label);
}
if(predict_label == target_label)
++correct;
error += (predict_label-target_label)*(predict_label-target_label);
sumv += predict_label;
sumy += target_label;
sumvv += predict_label*predict_label;
sumyy += target_label*target_label;
sumvy += predict_label*target_label;
++total;
}
if (svm_type==NU_SVR || svm_type==EPSILON_SVR)
{
printf("Mean squared error = %g (regression)\n",error/total);
printf("Squared correlation coefficient = %g (regression)\n",
((total*sumvy-sumv*sumy)*(total*sumvy-sumv*sumy))/
((total*sumvv-sumv*sumv)*(total*sumyy-sumy*sumy))
);
}
else
printf("Accuracy = %g%% (%d/%d) (classification)\n",
(double)correct/total*100,correct,total);
if (predict_probability)
free(prob_estimates);
}
void exit_with_help()
{
printf(
"Usage: svm-predict [options] test_file model_file output_file\n"
"options:\n"
"-b probability_estimates: whether to predict probability estimates, 0 or 1 (default 0); one-class SVM not supported yet\n"
"-q : quiet mode (no outputs)\n"
);
exit(1);
}
int main(int argc, char **argv)
{
char input_file_name[1024];
char model_file_name[1024];
char output_file_name[1024];
FILE *input, *output;
x = Malloc(struct svm_node,max_nr_attr);
// parse options
int i;
for(i=1;i<argc;i++)
{
if(argv[i][0] != '-') break;
++i;
switch(argv[i-1][1])
{
case 'b':
predict_probability = atoi(argv[i]);
break;
case 'q':
svm_print_string = &print_null;
i--;
break;
default:
fprintf(stderr,"Unknown option: -%c\n", argv[i-1][1]);
exit_with_help();
}
}
if(i>=argc-2)
exit_with_help();
strcpy(input_file_name, argv[i]);
strcpy(model_file_name, argv[i+1]);
strcpy(output_file_name, argv[i+2]);
if((input=fopen(input_file_name,"r"))==NULL)
{
fprintf(stderr,"can't open input file %s\n",input_file_name);
exit(1);
}
if((output=fopen(output_file_name,"w"))==NULL)
{
fprintf(stderr,"can't open output file %s\n",output_file_name);
exit(1);
}
if((model=svm_load_model(model_file_name))==0)
{
fprintf(stderr,"can't open model file %s\n",model_file_name);
exit(1);
}
predict(input,output);
svm_free_and_destroy_model(&model);
free(x);
free(line);
fclose(input);
fclose(output);
return 0;
}
```
其中,训练数据应该保存为以下格式的文件:
```
label 1:value 2:value ... -1
label 1:value 2:value ... -1
...
```
其中,每行表示一个样本,以标签开头,后面跟着特征值。特征值的索引从1开始,以`index:value`的格式表示,最后一个特征值后面必须加上`-1`。
例如,下面是一个样本:
```
1 1:0.5 2:0.3 3:0.8 -1
```
表示标签为1,有三个特征,分别为0.5、0.3和0.8。
然后使用以下命令编译程序:
```
gcc svm-predict.c svm.o -o svm-predict
```
其中,`svm.o`是libsvm库编译生成的二进制文件,可以从libsvm官网下载到。
然后使用以下命令运行程序:
```
./svm-predict -b 0 test_file.model model_file output_file
```
其中,`test_file`是测试数据文件,`model_file`是训练好的模型文件,`output_file`是输出结果文件。 `-b`选项表示是否输出概率估计。
阅读全文