Taiyo Mineo / SVM

Dependents:   WeatherPredictor

Files at this revision

API Documentation at this revision

Comitter:
yukari_hinata
Date:
Sun Feb 15 09:27:08 2015 +0000
Parent:
1:1a0d5152d50b
Child:
3:a8938dc2c422
Commit message:
modified

Changed in this revision

MCSVM.cpp Show annotated file Show diff for this revision Revisions of this file
MCSVM.hpp Show annotated file Show diff for this revision Revisions of this file
SVM.cpp Show annotated file Show diff for this revision Revisions of this file
SVM.hpp Show annotated file Show diff for this revision Revisions of this file
debug/debug.cpp Show diff for this revision Revisions of this file
debug/debug.hpp Show diff for this revision Revisions of this file
main.cpp Show diff for this revision Revisions of this file
mbed.bld Show diff for this revision Revisions of this file
util/util.hpp Show diff for this revision Revisions of this file
--- a/MCSVM.cpp	Wed Jan 28 15:22:10 2015 +0000
+++ b/MCSVM.cpp	Sun Feb 15 09:27:08 2015 +0000
@@ -89,6 +89,10 @@
   // 単位ステップ関数による決定的識別
   float net;
   int* result_label_count = new int[n_class];
+  
+  // 元のラベルを退避
+  int* tmp_label = new int[n_sample];
+  memcpy(tmp_label,label, sizeof(int) * n_sample);
 
   int tmp_ci, tmp_cj;
   memset(result_label_count, 0, sizeof(int) * n_class);
@@ -127,8 +131,10 @@
       argmax = i;
     }
   }
-
-  delete [] result_label_count;
+    // 元のラベルを復帰
+  memcpy(this->label, tmp_label, sizeof(int) * n_sample);
+  delete [] tmp_label; delete [] result_label_count;
+  
   return argmax;
 
 }
@@ -140,7 +146,13 @@
   float prob;
   float* result_label_prob = new float[n_class];
   int tmp_ci, tmp_cj;
+
   memset(result_label_prob, 0, sizeof(float) * n_class);
+  
+  // 元のラベルを退避
+  int* tmp_label = new int[n_sample];
+  memcpy(tmp_label,label, sizeof(int) * n_sample);
+  
   for (int ci = 0; ci < n_class; ci++) {
     for (int cj = ci + 1; cj < n_class; cj++) {
 
@@ -174,8 +186,11 @@
       max = result_label_prob[i];
     }
   }
-
-  delete [] result_label_prob;
+  
+  // 元のラベルを復帰
+  memcpy(this->label, tmp_label, sizeof(int) * n_sample);
+  delete [] tmp_label; delete [] result_label_prob;
+  
   // 平均確率を返す.
   return (max / (n_class-1));
 
@@ -196,6 +211,6 @@
         return;
     }
     int nC2 = n_class * (n_class - 1)/2;
-    memcpy(mc_alpha, mcalpha_data, sizeof(float) * n_sample * (n_class * (n_class - 1) / 2));
+    memcpy(mc_alpha, mcalpha_data, sizeof(float) * n_sample * nC2);
     status = SVM_SET_ALPHA;
 }
--- a/MCSVM.hpp	Wed Jan 28 15:22:10 2015 +0000
+++ b/MCSVM.hpp	Sun Feb 15 09:27:08 2015 +0000
@@ -26,30 +26,29 @@
     float* mc_alpha;     // 各識別用の双対係数
     int*   mc_label;     // 各識別用の2値(-1,1)ラベル, 識別に関係しないデータにはラベル0が付与される.
                          // マルチクラス識別の場合,SVM::labelには0,...,n_class-1までのラベルが付いている
-
   public:
     MCSVM(int,      // クラス個数
           int,      // データ次元
           int,      // サンプル個数
           float*,   // サンプルデータ
-          int*);    // マルチクラスラベル
+          int*);    // マルチクラスラベル:ラベルは0,...,n_class-1の整数
           
     ~MCSVM(void);
           
     // 未知データのラベルを推定する.返り値はマルチクラスラベル0,...,n_class-1
-    int predict_label(float*);
+    virtual int predict_label(float*);
     
     // 未知データの識別確率を推定する.
     // ラベル識別predict_label結果の整合性を考えない.
-    float predict_probability(float*);
+    virtual float predict_probability(float*);
 
     // 全てのSVMの学習する.
-    int learning(void);
+    virtual int learning(void);
     
     // 双対係数のゲッター
-    float* get_alpha(void);
+    virtual float* get_alpha(void);
     
-    // 双対係数のセッター
+    // 双対係数/ラベルのセッター
     void set_alpha(float*, int, int);
                         
 };
--- a/SVM.cpp	Wed Jan 28 15:22:10 2015 +0000
+++ b/SVM.cpp	Sun Feb 15 09:27:08 2015 +0000
@@ -71,7 +71,7 @@
   // ソフトマージンの係数. 両方ともFLT_MAXとすることでハードマージンと一致.
   // また, 設定するときはどちらか一方のみにすること.
   C1 = FLT_MAX;
-  C2 = 10;
+  C2 = 5;
 
   srand((unsigned int)time(NULL));
 
--- a/SVM.hpp	Wed Jan 28 15:22:10 2015 +0000
+++ b/SVM.hpp	Sun Feb 15 09:27:08 2015 +0000
@@ -1,3 +1,5 @@
+/* Support Vector Machine by hinata_yukari */
+
 #ifndef SVM_H_INCLUDED
 #define SVM_H_INCLUDED
 
@@ -48,7 +50,7 @@
         inprod += powf(x[i] - y[i],2);
         //printf("x[%d] : %f y[%d] : %f \n", i, x[i], i, y[i]);
       }
-      return expf(-inprod);
+      return expf(-inprod/0.1);
     }
 
   public:
@@ -80,7 +82,7 @@
     virtual float* get_alpha(void);
     
     // 双対係数のセッター
-    virtual void set_alpha(float*, int);
+    void set_alpha(float*, int);
 
 };
 
--- a/debug/debug.cpp	Wed Jan 28 15:22:10 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-#include "debug.hpp"
-
-void print_mat_func(float* mat, int row, int col) {
-    for (int i = 0; i < row; i++) {
-      for (int j = 0; j < col; j++) {
-        if (j == 0) { printf("|"); }
-        float val = MATRIX_AT(mat,col,i,j);
-        if (val > 0) { printf(" "); }
-        printf("%3.3f ",val);
-        if (j == col-1) { printf("| \r\n"); };
-      }
-    }
-}
-
-void print_vec_func(float* vec, int dim) {
-    for (int i = 0; i < dim; i++) {
-        printf("%f ", vec[i]);
-    }
-    printf("\r\n");
-}
-
-void no_memory(void) {
-    fprintf( stderr, "panic: can't allocate to memory! \r\n");
-    exit(1);
-}
--- a/debug/debug.hpp	Wed Jan 28 15:22:10 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-#ifndef DEBUG_H_INCLUDED
-#define DEBUG_H_INCLUDED
-
-#include "mbed.h"
-#include <new> 
-
-#include "../util/util.hpp"
-
-// Debug Macros
-#define DBG(...) printf("" __VA_ARGS__)
-#define PRINT_INT(x) (printf(#x " : %d \r\n", x))
-#define PRINT_FLT(x) (printf(#x " : %f \r\n", x))
-
-#define PRINT_VEC(vec,dim) (printf("FILE[%s] LINE %d, %s: \r\n", __FILE__, __LINE__, (#vec)) \
-                           (print_vec_func((vec),(dim)))
-#define PRINT_MAT(mat,row,col) (printf("FILE[%s] LINE %d, %s: \r\n", __FILE__, __LINE__, (#mat)) \
-                               (print_vec_func((vec),(row),(col)))
-
-// Debug Modules
-
-void print_vec_func(float* vec, int dim);
-
-void print_mat_func(float* mat, int row, int col);
-
-void write_log(char* name, ...);
-
-void no_memory(void);               // error handler for memory allocate failing
-
-#endif /* DEBUG_H_INCLUDED */
-
--- a/main.cpp	Wed Jan 28 15:22:10 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,101 +0,0 @@
-#include "mbed.h"
-
-#include "MCSVM.hpp"
-#include "./debug/debug.hpp"
-
-LocalFileSystem local("local");
-
-// SVMのテストルーチン
-int main(void) {
-  /*
-  FILE* fp;
-  const char* fname = "/local/iris.csv";
-  char s[100];
-  int ret;
-  float f1, f2, f3, f4;
-
-  set_new_handler(no_memory);
-
-  float* sample = new float[150 * 4];
-  int* sample_label = new int[150];
-
-  fp = fopen( fname, "r" );
-  if( fp == NULL ){
-    fprintf( stderr, "[%s] File cannot opne \r \n", fname );
-    return 1;
-  }
-
-  int cnt = 0;
-  while( ( ret = fscanf( fp, "%f,%f,%f,%f,%s", &f1, &f2, &f3, &f4, s) ) != EOF ){
-    //printf( "%f %f %f \n", f1, f2, f3 );
-    sample[cnt * 4]     = f1;
-    sample[cnt * 4 + 1] = f2;
-    sample[cnt * 4 + 2] = f3;
-    sample[cnt * 4 + 3] = f4;
-    
-    //printf("string : %s \n",s);
-    //printf("strcmp : %d \n",strcmp(s,"Iris-setosa"));
-    if ( !strcmp(s,"Iris-setosa") ) {
-      sample_label[cnt] = 0;
-    } else if ( !strcmp(s,"Iris-versicolor")) {
-      sample_label[cnt] = 1;
-    } else if ( !strcmp(s,"Iris-virginica")) {
-      sample_label[cnt] = 2;
-    }
-    //printf("sample : %f %f %f %f %d\n", MATRIX_AT(sample,4,cnt,0), MATRIX_AT(sample,4,cnt,1), MATRIX_AT(sample,4,cnt,2), MATRIX_AT(sample,4,cnt,3), sample_label[cnt]);
-
-    cnt++;
-  }
-
-  MCSVM mcsvm(3, 4, 150, sample, sample_label);
-  mcsvm.learning();
-
-  float *test = new float[4];
-  for (int i = 0; i < 150; i++ ) {
-    test[0] = sample[i * 4 + 0];
-    test[1] = sample[i * 4 + 1];
-    test[2] = sample[i * 4 + 2];
-    test[3] = sample[i * 4 + 3];
-    printf("<TEST No:%d> label : %d, answer : %d \r\n", i, mcsvm.predict_label(test), sample_label[i]);
-  }
-  fclose( fp );
-  free( fp ); // required for mbed.
-  */
-
-  /* 簡単な例 : 2次元空間の象限 */
-  // /*
-  float* easy_sample = new float[2 * 12];
-  int* easy_sample_label = new int[12];
-  easy_sample[0] = 1;     easy_sample[1] = 1;     easy_sample_label[0] = 0; // 第一象限 : ラベル0
-  easy_sample[2] = 0.5;   easy_sample[3] = 1;     easy_sample_label[1] = 0;
-  easy_sample[4] = 1;     easy_sample[5] = 0.5;   easy_sample_label[2] = 0;
-  easy_sample[6] = -1;    easy_sample[7] = 1;     easy_sample_label[3] = 1; // 第二象限 : ラベル1
-  easy_sample[8] = -0.5;  easy_sample[9] = 1;     easy_sample_label[4] = 1;
-  easy_sample[10] = -1;   easy_sample[11] = 0.5;  easy_sample_label[5] = 1;
-  easy_sample[12] = 1;    easy_sample[13] = -1;   easy_sample_label[6] = 2; // 第四象限 : ラベル2
-  easy_sample[14] = 0.5;  easy_sample[15] = -1;   easy_sample_label[7] = 2;
-  easy_sample[16] = 1;    easy_sample[17] = -0.5; easy_sample_label[8] = 2;
-  easy_sample[18] = -0.5; easy_sample[19] = -1;   easy_sample_label[9] = 3; // 第三象限 : ラベル3
-  easy_sample[20] = -1;   easy_sample[21] = -0.5; easy_sample_label[10] = 3;
-  easy_sample[22] = -1;   easy_sample[23] = -1;   easy_sample_label[11] = 3;
-
-  MCSVM mcsvm(4, 2, 12, easy_sample, easy_sample_label);
-  mcsvm.learning();
-
-  float *test = new float[2];
-  int ans;
-  for (float i = -1; i <= 1; i += 0.2) {
-    for (float j = -1; j <= 1; j += 0.2) {
-      test[0] = i; test[1] = j; ans = 0;
-      if ( i < 0 ) { ans += 1; }
-      if ( j < 0 ) { ans += 2; }
-      printf("<TEST> [%f,%f] label : %d prob : %f answer : %d \r\n", test[0], test[1], mcsvm.predict_label(test), mcsvm.predict_probability(test), ans);
-    }
-  }
-  // */
-  
-  delete [] test;
-
-  return 0;
-}
-
--- a/mbed.bld	Wed Jan 28 15:22:10 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1 +0,0 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/4fc01daae5a5
\ No newline at end of file
--- a/util/util.hpp	Wed Jan 28 15:22:10 2015 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,92 +0,0 @@
-#ifndef UTIL_H_INCLUDED
-#define UTIL_H_INCLUDED
-
-#include "mbed.h"
-
-/* float.h がないので, FLT_MAXをここで */
-#define FLT_MAX  (0x1.fffffeP127F)      // float max
-
-// 特に行列演算用のマクロ集
-
-// 行列アクセス用マクロ. n_lenは行列の幅(length, col,列の数)
-#define MATRIX_AT(ary,n_len,i,j) (ary[(((i) * (n_len)) + (j))])
-
-// 2乗(ユーグリッド)ノルムを返す
-inline float two_norm(float *vec, int dim) {
-  register float ret = 0;
-  for (int i=0; i < dim; i++) {
-    ret += powf(vec[i],2);
-  }
-  return sqrtf(ret);
-}
-
-// 2ベクトル間の距離をユーグリッドノルムで測る.
-inline float vec_dist(float *x, float *y, int dim) {
-  register float ret = 0;
-  for (int i=0; i < dim; i++) {
-    ret += powf(x[i] - y[i],2);
-  }
-  return sqrtf(ret);
-}
-
-// 一様乱数の生成 : [-w,w]で生成.
-inline float uniform_rand(float w) {
-  return (float(rand() - RAND_MAX/2) / float(RAND_MAX)) * 2 * w;
-}
-
-// float配列の最大値を返す
-inline float maxf(float* ary, int dim) {
-  register float max = 0;
-  for (int i=0; i < dim; i++) {
-    if (ary[i] >= max) {
-      max = ary[i];
-    }
-  }
-  return max;
-}
-
-// float配列の最小値を返す
-inline float minf(float* ary, int dim) {
-  register float min = FLT_MAX;
-  for (int i=0; i < dim; i++) {
-    if (ary[i] <= min) {
-      min = ary[i];
-    }
-  }
-  return min;
-}
-
-// サイズm*nの行列とサイズn*1のベクトルの掛け算を計算し,結果をresultにセットする.
-
-inline void multiply_mat_vec(float*  mat, // m * n 行列
-                             float*  vec, // n * 1 ベクトル
-                             float*  result, // m * 1 計算結果ベクトル
-                             int     m,   // m
-                             int     n)   // n
-{
-  register float sum;
-  for (int i=0;i<m;i++) {
-    sum = 0;
-    for (int j=0;j<n;j++) {
-      sum += MATRIX_AT(mat,n,i,j) * vec[j];
-    }
-    result[i] = sum;
-  }
-}
-
-// シグモイド(ロジスティック)関数.
-inline float sigmoid_func(float x){
-  return (1 / (1 + expf(-x)));
-}
-
-// 信号の正規化([0,1]の範囲に収めること:超重要)
-inline float normalize_signal(float in, float max, float min){
-  return float((in - min) / (max - min));
-} 
-
-// 信号の元の領域への拡大([0,1]から元の信号値にスケール)
-inline float expand_signal(float in, float max, float min){
-  return float(min + (max - min) * in);
-} 
-
-#endif /* UTIL_H_INCLUDED */