⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 svm_common.c

📁 一款不错的支持向量机程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/************************************************************************//*                                                                      *//*   svm_common.c                                                       *//*                                                                      *//*   Definitions and functions used in both svm_learn and svm_classify. *//*                                                                      *//*   Author: Thorsten Joachims                                          *//*   Date: 02.07.04                                                     *//*                                                                      *//*   Copyright (c) 2004  Thorsten Joachims - All rights reserved        *//*                                                                      *//*   This software is available for non-commercial use only. It must    *//*   not be modified and distributed without prior permission of the    *//*   author. The author is not responsible for implications from the    *//*   use of this software.                                              *//*                                                                      *//************************************************************************/# include "ctype.h"# include "svm_common.h"# include "kernel.h"           /* this contains a user supplied kernel */long   verbosity;              /* verbosity level (0-4) */long   kernel_cache_statistic;double classify_example(MODEL *model, DOC *ex)      /* classifies one example */{  register long i;  register double dist;  if((model->kernel_parm.kernel_type == LINEAR) && (model->lin_weights))    return(classify_example_linear(model,ex));	     dist=0;  for(i=1;i<model->sv_num;i++) {      dist+=kernel(&model->kernel_parm,model->supvec[i],ex)*model->alpha[i];  }  return(dist-model->b);}double classify_example_linear(MODEL *model, DOC *ex)      /* classifies example for linear kernel */          /* important: the model must have the linear weight vector computed */     /* use: add_weight_vector_to_linear_model(&model); */     /* important: the feature numbers in the example to classify must */     /*            not be larger than the weight vector!               */{  double sum=0;  SVECTOR *f;  for(f=ex->fvec;f;f=f->next)      sum+=f->factor*sprod_ns(model->lin_weights,f);  return(sum-model->b);}CFLOAT kernel(KERNEL_PARM *kernel_parm, DOC *a, DOC *b)      /* calculate the kernel function */{  double sum=0;  SVECTOR *fa,*fb;  /* in case the constraints are sums of feature vector as represented     as a list of SVECTOR's with their coefficient factor in the sum,     take the kernel between all pairs */   for(fa=a->fvec;fa;fa=fa->next) {     for(fb=b->fvec;fb;fb=fb->next) {      if(fa->kernel_id == fb->kernel_id)	sum+=fa->factor*fb->factor*single_kernel(kernel_parm,fa,fb);    }  }  return(sum);}CFLOAT single_kernel(KERNEL_PARM *kernel_parm, SVECTOR *a, SVECTOR *b)      /* calculate the kernel function between two vectors */{  kernel_cache_statistic++;  switch(kernel_parm->kernel_type) {    case 0: /* linear */             return((CFLOAT)sprod_ss(a,b));     case 1: /* polynomial */            return((CFLOAT)pow(kernel_parm->coef_lin*sprod_ss(a,b)+kernel_parm->coef_const,(double)kernel_parm->poly_degree));     case 2: /* radial basis function */            return((CFLOAT)exp(-kernel_parm->rbf_gamma*(a->twonorm_sq-2*sprod_ss(a,b)+b->twonorm_sq)));    case 3: /* sigmoid neural net */            return((CFLOAT)tanh(kernel_parm->coef_lin*sprod_ss(a,b)+kernel_parm->coef_const));     case 4: /* custom-kernel supplied in file kernel.h*/            return((CFLOAT)custom_kernel(kernel_parm,a,b));     default: printf("Error: Unknown kernel function\n"); exit(1);  }}SVECTOR *create_svector(WORD *words,char *userdefined,double factor){  SVECTOR *vec;  long    fnum,i;  fnum=0;  while(words[fnum].wnum) {    fnum++;  }  fnum++;  vec = (SVECTOR *)my_malloc(sizeof(SVECTOR));  vec->words = (WORD *)my_malloc(sizeof(WORD)*(fnum));  for(i=0;i<fnum;i++) {       vec->words[i]=words[i];  }  vec->twonorm_sq=sprod_ss(vec,vec);  fnum=0;  while(userdefined[fnum]) {    fnum++;  }  fnum++;  vec->userdefined = (char *)my_malloc(sizeof(char)*(fnum));  for(i=0;i<fnum;i++) {       vec->userdefined[i]=userdefined[i];  }  vec->kernel_id=0;  vec->next=NULL;  vec->factor=factor;  return(vec);}SVECTOR *copy_svector(SVECTOR *vec){  SVECTOR *newvec=NULL;  if(vec) {    newvec=create_svector(vec->words,vec->userdefined,vec->factor);    newvec->next=copy_svector(vec->next);  }  return(newvec);}    void free_svector(SVECTOR *vec){  if(vec) {    free(vec->words);    if(vec->userdefined)      free(vec->userdefined);    free_svector(vec->next);    free(vec);  }}double sprod_ss(SVECTOR *a, SVECTOR *b)      /* compute the inner product of two sparse vectors */{    register CFLOAT sum=0;    register WORD *ai,*bj;    ai=a->words;    bj=b->words;    while (ai->wnum && bj->wnum) {      if(ai->wnum > bj->wnum) {	bj++;      }      else if (ai->wnum < bj->wnum) {	ai++;      }      else {	sum+=(CFLOAT)(ai->weight) * (CFLOAT)(bj->weight);	ai++;	bj++;      }    }    return((double)sum);}SVECTOR* sub_ss(SVECTOR *a, SVECTOR *b)      /* compute the difference a-b of two sparse vectors */     /* Note: SVECTOR lists are not followed, but only the first	SVECTOR is used */{    SVECTOR *vec;    register WORD *sum,*sumi;    register WORD *ai,*bj;    long veclength;      ai=a->words;    bj=b->words;    veclength=0;    while (ai->wnum && bj->wnum) {      if(ai->wnum > bj->wnum) {	veclength++;	bj++;      }      else if (ai->wnum < bj->wnum) {	veclength++;	ai++;      }      else {	veclength++;	ai++;	bj++;      }    }    while (bj->wnum) {      veclength++;      bj++;    }    while (ai->wnum) {      veclength++;      ai++;    }    veclength++;    sum=(WORD *)my_malloc(sizeof(WORD)*veclength);    sumi=sum;    ai=a->words;    bj=b->words;    while (ai->wnum && bj->wnum) {      if(ai->wnum > bj->wnum) {	(*sumi)=(*bj);	sumi->weight*=(-1);	sumi++;	bj++;      }      else if (ai->wnum < bj->wnum) {	(*sumi)=(*ai);	sumi++;	ai++;      }      else {	(*sumi)=(*ai);	sumi->weight-=bj->weight;	if(sumi->weight != 0)	  sumi++;	ai++;	bj++;      }    }    while (bj->wnum) {      (*sumi)=(*bj);      sumi->weight*=(-1);      sumi++;      bj++;    }    while (ai->wnum) {      (*sumi)=(*ai);      sumi++;      ai++;    }    sumi->wnum=0;    vec=create_svector(sum,"",1.0);    free(sum);    return(vec);}SVECTOR* add_ss(SVECTOR *a, SVECTOR *b)      /* compute the sum a+b of two sparse vectors */     /* Note: SVECTOR lists are not followed, but only the first	SVECTOR is used */{    SVECTOR *vec;    register WORD *sum,*sumi;    register WORD *ai,*bj;    long veclength;      ai=a->words;    bj=b->words;    veclength=0;    while (ai->wnum && bj->wnum) {      if(ai->wnum > bj->wnum) {	veclength++;	bj++;      }      else if (ai->wnum < bj->wnum) {	veclength++;	ai++;      }      else {	veclength++;	ai++;	bj++;      }    }    while (bj->wnum) {      veclength++;      bj++;    }    while (ai->wnum) {      veclength++;      ai++;    }    veclength++;    /*** is veclength=lengSequence(a)+lengthSequence(b)? ***/    sum=(WORD *)my_malloc(sizeof(WORD)*veclength);    sumi=sum;    ai=a->words;    bj=b->words;    while (ai->wnum && bj->wnum) {      if(ai->wnum > bj->wnum) {	(*sumi)=(*bj);	sumi++;	bj++;      }      else if (ai->wnum < bj->wnum) {	(*sumi)=(*ai);	sumi++;	ai++;      }      else {	(*sumi)=(*ai);	sumi->weight+=bj->weight;	if(sumi->weight != 0)	  sumi++;	ai++;	bj++;      }    }    while (bj->wnum) {      (*sumi)=(*bj);      sumi++;      bj++;    }    while (ai->wnum) {      (*sumi)=(*ai);      sumi++;      ai++;    }    sumi->wnum=0;    vec=create_svector(sum,"",1.0);    free(sum);    return(vec);}SVECTOR* add_list_ss(SVECTOR *a)      /* computes the linear combination of the SVECTOR list weighted	by the factor of each SVECTOR */{  SVECTOR *scaled,*oldsum,*sum,*f;  WORD    empty[2];      if(a){    sum=smult_s(a,a->factor);    for(f=a->next;f;f=f->next) {      scaled=smult_s(f,f->factor);      oldsum=sum;      sum=add_ss(sum,scaled);      free_svector(oldsum);      free_svector(scaled);    }    sum->factor=1.0;  }  else {    empty[0].wnum=0;    sum=create_svector(empty,"",1.0);  }  return(sum);}void append_svector_list(SVECTOR *a, SVECTOR *b)      /* appends SVECTOR b to the end of SVECTOR a. */{    SVECTOR *f;        for(f=a;f->next;f=f->next);  /* find end of first vector list */    f->next=b;                   /* append the two vector lists */}SVECTOR* smult_s(SVECTOR *a, double factor)      /* scale sparse vector a by factor */{    SVECTOR *vec;    register WORD *sum,*sumi;    register WORD *ai;    long veclength;      ai=a->words;    veclength=0;    while (ai->wnum) {      veclength++;      ai++;    }    veclength++;    sum=(WORD *)my_malloc(sizeof(WORD)*veclength);    sumi=sum;    ai=a->words;    while (ai->wnum) {	(*sumi)=(*ai);	sumi->weight*=factor;	if(sumi->weight != 0)	  sumi++;	ai++;    }    sumi->wnum=0;    vec=create_svector(sum,a->userdefined,a->factor);    free(sum);    return(vec);}int featvec_eq(SVECTOR *a, SVECTOR *b)     /* tests two sparse vectors for equality */{    register WORD *ai,*bj;    ai=a->words;    bj=b->words;    while (ai->wnum && bj->wnum) {      if(ai->wnum > bj->wnum) {	if((CFLOAT)(bj->weight) != 0)	  return(0);	bj++;      }      else if (ai->wnum < bj->wnum) {	if((CFLOAT)(ai->weight) != 0)	  return(0);	ai++;      }      else {	if((CFLOAT)(ai->weight) != (CFLOAT)(bj->weight)) 	  return(0);	ai++;	bj++;      }    }    return(1);}double model_length_s(MODEL *model, KERNEL_PARM *kernel_parm)      /* compute length of weight vector */{  register long i,j;  register double sum=0,alphai;  register DOC *supveci;  for(i=1;i<model->sv_num;i++) {      alphai=model->alpha[i];    supveci=model->supvec[i];    for(j=1;j<model->sv_num;j++) {      sum+=alphai*model->alpha[j]	   *kernel(kernel_parm,supveci,model->supvec[j]);    }  }  return(sqrt(sum));}void clear_vector_n(double *vec, long int n){  register long i;  for(i=0;i<=n;i++) vec[i]=0;}void add_vector_ns(double *vec_n, SVECTOR *vec_s, double faktor){  register WORD *ai;  ai=vec_s->words;  while (ai->wnum) {    vec_n[ai->wnum]+=(faktor*ai->weight);    ai++;  }}double sprod_ns(double *vec_n, SVECTOR *vec_s){  register double sum=0;  register WORD *ai;  ai=vec_s->words;  while (ai->wnum) {    sum+=(vec_n[ai->wnum]*ai->weight);    ai++;  }  return(sum);}void add_weight_vector_to_linear_model(MODEL *model)     /* compute weight vector in linear case and add to model */{  long i;  SVECTOR *f;  model->lin_weights=(double *)my_malloc(sizeof(double)*(model->totwords+1));  clear_vector_n(model->lin_weights,model->totwords);  for(i=1;i<model->sv_num;i++) {    for(f=(model->supvec[i])->fvec;f;f=f->next)        add_vector_ns(model->lin_weights,f,f->factor*model->alpha[i]);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -