サポートベクターマシンのライブラリ「libsvm」をVisual C++ 2010上での使い方

(1)ライブラリのダウンロード

(2) 「libsvm-3.17.zip」の内容説明

  • VC++2010にライブラリとして利用するものは,「svm.h」「svm.c」のみとなります.すなわち,新規プロジェクトを作成し,そのプロジェクトに「svm.h」「svm.c」を追加するのみで,libsvmのプログラムを構築することが可能です.
  • 「svm-scale.c」「svm-train.c」「svm-predict.c」は3種別々のサンプルコードとなります.すなわち
「svm.h」「svm.c」「svm-scale.c」の組合せサポートベクターマシンに入力するためにデータを正規化するプログラム「svm-scale.exe」
「svm.h」「svm.c」「svm-train.c」の組合せサポートベクターマシンにラベルとデータのセットを入力し,ラベルとデータの対応づける学習パラメータを決定するプログラム「svm-train.exe」
「svm.h」「svm.c」「svm-predict.c」の組合せサポートベクターマシンに学習パラメータとデータを入力し,ラベルを推測するプログラム「svm-predict.exe」

(3) Visual C++ 2010の新規プロジェクトの作り方

  • 重要な点は,新規プロジェクトに「svm.h」「svm.c」を追加すること.「マウス・右クリック>追加>既存の項目」にて「svm.h」「svm.c」を追加してください.また,もし- 「svm.c」に「#include "stdafx.h"」を追加して下さい.
  • 新規プロジェクトで作成したCPPファイルに「#include "svm.h"」を追記することを忘れないで下さい.
  • svm-train.exe」を作成したい場合は,「svm-train.c」から必要な部分を新規プロジェクトで作成したCPPファイルにコピー&ペーストしてください.(違いは,「main」の表現だけです.)
  • あと,「プロジェクト>プロパティ>全般>文字セット」で「マルチバイト文字セットを使用する」を選択してください.

(4) 「libsvm-3.17」にある実行形式ファイルの使い方

  • 上記の実行形式ファイル「svm-scale.exe」「svm-tran.exe」「svm-predict.exe」は,「windows」フォルダに存在しています.

4.0 前準備:データファイル形式

SVM用実行ファイルに入力されるデータは,テキストファイルが推奨され,「ラベル」と「データ」のセットが番号順に記述されるものとする.すなわち

[ラベル値][スペース]1:[1個目のデータ値][スペース]2:[2個目のデータ値][スペース]3:[3個目のデータ値]
[ラベル値][スペース]1:[1個目のデータ値][スペース]2:[2個目のデータ値][スペース]3:[3個目のデータ値]
[ラベル値][スペース]1:[1個目のデータ値][スペース]2:[2個目のデータ値][スペース]3:[3個目のデータ値]

というように,1行が1データセットとなり,まずはラベル値,それ以降はデータを番号を付けて順々に記載するという形式である.各データには番号が付けられており「:」より前がデータ番号,「:」より後ろがデータ値となる.また,それぞれのデータはスペースで区切られている.下記に入力データ例「test.txt」を示す.

+0 1:2.4 2:45.2 3:44.2 4:55.1 5:1.12
+0 1:3.3 2:40.1 3:41.2 4:50.2 5:2.32
+1 1:4.1 2:42.2 3:47.7 4:48.2 5:0.11
+1 1:2.3 2:38.2 3:40.1 4:54.3 5:2.25

4.1 「svm-scale.exe」の使い方

  • 「svm-scale.exe」は,「svm-train.exe」に入力するデータを正規化するプログラムである.ただし,必ずしも,使用する必要はない.正規化をするメリットは,「svm-train.exe」利用時の処理の高速化らしい.
  • 「svm-scale.exe」を使い,「test.txt」を正規化するには,「svm-scale.exe」と「test.txt」を同じフォルダに配置し,コマンドプロンプトを起動し,そのフォルダに移動し「svm-scale.exe test.txt > test2.txt」を入力する.
    svm-scale.exe test.txt > test2.txt
  • 「>」前の「test.txt」は,「test.txt」からデータを読み取りを実行し,「>」の後の「test2.txt」は「>」前のコマンドが実行された結果を「test2.txt」に記述するという意味となる.もし,「> test2.txt」を記述しない場合は,コマンドプロンプト上にコマンド結果が表示されるのみとなる.
  • 調整可能なパラメータ「-u +1 -l -1」などがあり,その意味は,各データ番号ごとにデータの最大値・最小値を抽出し,その値を基準にすべてのデータを「-1」から「+1」までの小数値に変換=正規化するという内容である.
     svm-scale.exe -u +1 -l -1 test.txt > test2.txt
  • なおデータセット例は「libsvm」のサイトで公開されていますので,利用してみたいらいかがでしょうか?<http://www.csie.ntu.edu.tw/~cjlin/libsvmtools/datasets/>
  • 【注意!】テキストファイルを作る上で気を付けなければいけないのは,「メモ帳」で作ると改行が正しく記述されず,「svm-scale.exe」「svm-train.exe」に読み取ってはもらえない.そのため,その他の「ワードパッド」などを推薦する.(例えば,メモ帳で何かしらのファイルを開くと,正しく改行されていない場合がある.そのように改行がいまいち正しく反映されないのが,この場合の「メモ帳」利用の問題点である.)

4.2 「svm-train.exe」の使い方

  • 「svm-train.exe」と「test.txt」を同じフォルダに配置し,コマンドプロンプトを起動し,「svm-train.exe test.txt」を入力する.(正規化したファイルでもOK.)
    svm-train.exe test.txt
  • 学習結果「test.txt.model」ファイルがフォルダ作成される.
  • なお「svm-train.exe」を使用する場合,下記のSVMパラメータが調整可能となる.ただ,一般に使うのであれば,パラメータ調整しなくとも問題ない.
    * SVMの種類の指定(デフォルトは「0」)
     -s svm_type
       0 -- C-SVC
       1 -- nu-SVC
       2 -- one-class SVM
       3 -- epsilon-SVR
       4 -- nu-SVR
    【コメント】複数の分類は「C-SVC」「nu-SVC」となる.「C-SVC」で問題ないらしい.
    
    * カーネル関数の種類の指定(デフォルトは「2」)
     -t kernel_type
       0 -- 線形(linear): u'*v
       1 -- 多項式(polynomial): (gamma*u'*v + coef0)^degree
       2 -- RBF(radial basis function): exp(-gamma*|u-v|^2)
       3 -- シグモイド(sigmoid): tanh(gamma*u'*v + coef0)
    【コメント】通常は,RBFの利用で問題ないらしい. 
    
    * カーネル関数のパラメータ調整
     -d degree : (デフォルトは「3」)
     -g gamma : (デフォルトは「1/k」, kは入力ベクトルの次元)
     -r coef0 : (デフォルトは「0」)
     -c cost : SVM種類が「C-SVC」「epsilon-SVR」「nu-SVR」の場合のコストパラメータ (デフォルトは「1」)
     -n nu : SVM種類が「nu-SVC」「one-class SVM」「nu-SVR」の場合のnuパラメータ (デフォルトは 0.5)
     -m cachesize : 使用キャッシュメモリサイズ(単位MB, デフォルトは「100」)
     -e epsilon : 終了の閾値 (デフォルトは「0.001」)
     -v n: n-foldのクロスバリデーション実行
    【コメント】通常は,デフォルト設定で問題ないらしい. 
  • パラメータ調整のコマンド例を以下に示す.
    > svm-train.exe -s 1 -t 1 -d 4 text2.txt.model

4.3 「svm-predict.exe」の使い方

  • 前準備として,判定に利用するデータファイル(input.txt)を作成する必要がある.そのため,入力用データとして作成した4.0節のデータフォーマットと同様の形式で作成する.ただし,先頭のラベルは形式として付け加えれているので,いずれのラベルでも問題ない.
    +0 1:2.3 2:42.2 3:24.2 4:05.1 5:1.32
    +1 1:3.1 2:41.1 3:01.2 4:10.2 5:1.32
  • 「svm-predict.exe」「test.txt.model」「input.txt」を同じフォルダに配置し,コマンドプロンプトを起動し,「svm-predict.exe test.txt,model input.txt output.txt」を入力する.
    svm-predict.exe test.txt,model input.txt output.txt
  • 識別結果は,「output.txt」ファイルに記載される.すなわち,各行の識別結果=ラベルの種類が行ごとに記されている.
  • なお,「svm-predict.exe」には,probility estimatesを算出する設定パラメータ「-b」というものがあるのだが,3種類以上の分類では利用できないかもしれない.念のため,パラメータ設定有のコマンドも下記する.
    svm-predict.exe -b 1 test.txt,model input.txt output.txt
    

(5) Visual C++ 2010用サンプルコード

#include "stdafx.h"
#include <Windows.h>
#include "svm.h"

struct svm_parameter param;		// SVM設定用パラメータ
struct svm_problem prob;		// データセット(ラベル&データ)・パラメータ
struct svm_node *x_space;		// データ・パラメータ(svm_problemの下部変数)
struct svm_model *model;		// 学習データ・パラメータ

#define NUM_OF_DATA_SET	10	// データセット数 
#define MAX_INDEX	7	// 1データセットに収納されているデータ数(データ次元)

// 入力するラベルとデータのセット(一列目:ラベル,それ以降の列:データ)
double data[NUM_OF_DATA_SET][MAX_INDEX+1]={
	1,	0.92,0.97,0.11,0.01,0.12,0.11,0.09,
	1,	0.91,0.99,0.21,0.02,0.09,0.12,0.09,
	1,	0.90,0.90,0.22,0.01,0.10,0.13,0.10,
	2,	0.12,0.21,0.32,0.12,0.99,0.11,0.91,
	2,	0.13,0.11,0.22,0.13,0.98,0.12,0.90,
	2,	0.12,0.24,0.11,0.14,0.89,0.13,0.91,
	3,	0.13,0.31,0.82,0.12,0.89,0.11,0.10,
	3,	0.12,0.23,0.89,0.10,0.92,0.12,0.11,
	3,	0.11,0.11,0.87,0.01,0.93,0.13,0.12,
	3,	0.10,0.12,0.81,0.12,0.97,0.11,0.12};

int _tmain(int argc, _TCHAR* argv[]){
	int i=0,j=0;

	// SVM設定値(デフォルト値)
	param.svm_type = C_SVC;
	param.kernel_type = RBF;
	param.degree = 3;
	param.gamma = 1./MAX_INDEX;
	param.coef0 = 0;
	param.nu = 0.5;
	param.cache_size = 100;
	param.C = 1;
	param.eps = 1e-3;
	param.p = 0.1;
	param.shrinking = 1;
	param.probability = 0;
	param.nr_weight = 0;
	param.weight_label = NULL;
	param.weight = NULL;

	// データセットのパラメータ設定
	prob.l=NUM_OF_DATA_SET;	// データセット数

	// 各パラメータのメモリ領域確保
	prob.y= new double[prob.l];		// ラベル
	prob.x= new svm_node *[prob.l];		// データセットの分だけデータ収納空間を作成
	x_space = new svm_node[(MAX_INDEX+1)*prob.l];

	// データセット・パラメータへの数値入力
	for(i=0;i<prob.l;i++){
		prob.y[i]=(int)data[i][0];	// ラベル入力
		for(j=0;j<MAX_INDEX;j++){
			x_space[(MAX_INDEX+1)*i+j].index = j+1;			// データ番号の入力
			x_space[(MAX_INDEX+1)*i+j].value = data[i][j+1];	// データ値の入力 
 		}
		x_space[(MAX_INDEX+1)*i+MAX_INDEX].index = -1;
		prob.x[i] = &x_space[(MAX_INDEX+1)*i];	// prob.xとx_spaceとの関係付
	}						

	model = svm_train(&prob,&param);	// SVM学習
	svm_save_model("model.txt",model);	// 学習結果のファイル出力
	
	printf("学習終了→「model.txt」をファイル出力\n");
	Sleep(100000);

	svm_free_and_destroy_model(&model);
	svm_destroy_param(&param);

	// メモリ領域の開放
	delete[] prob.y;
	delete[] prob.x;
	delete[] x_space;

	return 0;
}

以降,鋭意製作中.


トップ   編集 凍結解除 差分 バックアップ 添付 複製 名前変更 リロード   一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2013-08-29 (木) 21:34:44 (1543d)