【LIBSVM】C++とLIBSVMを用いた機械学習+サンプル分類

6037 ワード

一、SVMを理解する:
サポートベクトルマシンは、英語名がsupport vector machineであるため、一般的にSVMと略称され、一般的には2種類の分類モデルであり、その基本モデルは特徴空間上の間隔が最大の線形分類器として定義され、その学習戦略は間隔が最大化され、最終的に凸二次計画問題の解に転化することができる.
SVMに関する具体的な理論解釈は博文を参考にすることができる:ベクトルマシン通俗導論を支持する(SVMの三層境界を理解する)
(ddlは緊張しているので、SVMの原理をよく見て、SVMを実現する方法を検討しました.少なくとも罰則パラメータCがどうなっているのかを理解することをお勧めします)
二、LIBSVMを理解する——便利で速いSVMツールパッケージ:
LIBSVMは台湾大学林智仁(Lin Chih-Jen)教授など2001年に開発設計された簡単で、使いやすく、迅速で効果的なSVMモード識別と回帰のソフトウェアパッケージであり、Windowsシリーズシステムでコンパイルできる実行ファイルを提供しただけでなく、ソースコードを提供し、改善しやすく、修正し、他のオペレーティングシステムで応用した.このソフトウェアはSVMに関連するパラメータの調整が比較的に少なく、多くのデフォルトパラメータを提供し、これらのデフォルトパラメータを利用して多くの問題を解決することができる.インタラクティブチェック(Cross Validation)の機能を提供する.パッケージはhttp://www.csie.ntu.edu.tw/~cjlin/無料入手.このソフトウェアはC-SVMを解決することができ、ν-SVM, ε-SVRとν-SVR等の問題は、一対一のアルゴリズムに基づく多種類のパターン認識問題を含む.
LIBSVMはWindowsで直接DOSで使えるexeファイルを提供していますが、大作業の環境では完全にC++で実現する必要があるため、LIBSVMのソースコードを取り出し、それに基づいてプログラミングする必要があります.
三、呼び出し方法とパラメータの紹介
(パラメータの調整方法がわからなくて関係なく、一時的にデフォルト値を使えばOK)
svm_モデルはモデルクラスであり、訓練されたモデルファイルを訓練またはロードすることによってsvm_を得る.parameterはパラメータクラスで、主にベクトルマシンをサポートするためにパラメータを設定し、具体的なパラメータは以下の通りである.
svm_parameter.svm_typesvmタイプ:SVM設定タイプ(デフォルトsvm_parameter.C_SVC)svm_parameter.C_SVC -- C-SVCsvm_parameter.NU_SVC -- ν-SVCsvm_parameter.ONE_CLASS–SVMSvmのクラスparameter.EPSILON_SVR -- ε -SVRsvm_parameter.NU_SVR -- ν-SVRsvm_parameter.kernel_typeコア関数タイプ:コア関数設定タイプ(svm_parameter.LINEAR)svm_parameter.LINEAR–線形:u'×vsvm_parameter.POLY–多項式:(γ×u'×v + coef0)^degreesvm_parameter.RBF–RBF関数:exp(-γ×|u-v|^2)svm_parameter.SIGMOID – sigmoid:tanh(γ×u'×v + coef0)
svm_parameter.degreeコア関数のdegree設定(デフォルト3)svm_parameter.coef 0コア関数のcoef 0設定(デフォルト0)svm_parameter.shrinkingがイニシアチブを使用するかどうか、0または1(デフォルト1)svm_parameter.nu設定ν-SVC、SVMとν- SVRのパラメータ(デフォルト0.5)svm_parameter.C C C-SVCを設定し、ε -SVRとν-SVRのパラメータ(デフォルト1)svm_parameter.cache_size cacheメモリサイズをMB単位で設定(デフォルト40)svm_Problemは訓練集合に相当し,訓練が必要なデータがこのクラスに加わって訓練器に伝達されるといえる.
四、説明
私の大宿題の工事はまだ完成していないので、まずYHBcctvさんの実験で説明しましょう(YHBcctvさんの実験報告とコードに感謝します)
完全なエンジニアリングコード+実験報告ダウンロード(ポイントフリー):http://download.csdn.net/detail/jsgaobiao/9332813
SVMの実装は主に訓練サンプルと予測サンプルの2つの部分から構成され,それらはそれぞれ関数svm_trainとsvm_predict実装.
(1) struct svm_model*svm_train(const struct svm_problem *prob, const struct svm_parameter *param);
ここでprobは訓練に参加するサンプルセットを格納し,paramは訓練に参加する各種パラメータを格納する.次のように定義されています.
struct svm_problem //             (   ),      。
{
int l; //      
double *y; //           
struct svm_node **x; //              
};

struct svm_parameter//     
{
int svm_type; //SVM  , 
int kernel_type; //     
int degree; /* for poly */
double gamma; /* for poly/rbf/sigmoid */
double coef0; /* for poly/sigmoid */
/* these are for training only */
double cache_size; /* in MB           */
double eps; /* stopping criteria */
double C; /* for C_SVC, EPSILON_SVR and NU_SVR ,    */
int nr_weight; /* for C_SVC      */
int *weight_label; /* for C_SVC   ,     nr_weight   */
double* weight; /* for C_SVC */
double nu; /* for NU_SVC, ONE_CLASS, and NU_SVR */
double p; /* for EPSILON_SVR */
int shrinking; /* use the shrinking heuristics              */
int probability; /* do probability estimates           */
}

ここで、SVMタイプとコア関数タイプは、enum{C_SVC,NU_SVC,ONE_CLASS,EPSILON_SVR,NU_SVR};/*svm_type */enum { LINEAR, POLY, RBF, SIGMOID, PRECOMPUTED };/* kernel_type */(2) doublesvm_predict(const struct svm_model *model, const struct svm_node *x);
パラメータモデルは、SVMモデルのポインタであり、関数struct svm_を使用することができます.model*svm_load_Model(const char*model_file_name)は、トレーニング時に保存したSVMモデルをインポートします.この関数は、変数modelに直接値を割り当てるSVMモデルのポインタを返します.パラメータx、const struct svm_Node構造体のポインタは,予測が必要な単一のサンプルを指す.
コアコードの一部は次のとおりです.
トレーニングサンプル
void train(char *filePath)
{
	FILE *fp;
	int k;
	int line=0;
	int temp;
 
	if((fp=fopen(filePath,"rt"))==NULL) return;
		
	while(1)
	{
		 svm_node* features = new svm_node[85+1];
		 

		//        (         86   ,               )
		 for(k=0;k<85;k++)		
		 {
		 	fscanf(fp,"%d",&temp);
        		features[k].index = k + 1;
			features[k].value = temp/(MAX*1.0) ;
			//             ,   :						
			//A、                      ;					
			//B、                              。
		}
			
		features[85].index = -1;
		fscanf(fp,"%d",&temp);
		xList.push_back(features);
		yList.push_back(temp);
    
		line++;
		trainNum=line;
		if(feof(fp)) 
			break; 
	}
        setParam();
	prob.l=line;
	prob.x=new svm_node *[prob.l];  //       
	prob.y = new double[prob.l];    //    
	int index=0;	
	while(!xList.empty())
	{
		prob.x[index]=xList.front();
		prob.y[index]=yList.front();
		xList.pop_front();
		yList.pop_front();
		index++;
	}
	svmModel=svm_train(&prob, ?m); //  svm_train   model

	//  model
	svm_save_model("model.txt",svmModel);

	//    
	delete  prob.y;
	delete [] prob.x;
	svm_free_and_destroy_model(&svmModel);
}

予測サンプル
void predict(char *filePath)
{
   svm_model *svmModel = svm_load_model("model.txt");  //        model

   	FILE *fp;
	int line=0;
	int temp;

	if((fp=fopen(filePath,"rt"))==NULL) return;
		
	while(1)
	{
		 svm_node* input = new svm_node[85+1]; //               (    86   )
		 for(int k=0;k<85;k++)
		 {
		 	fscanf(fp,"%d",&temp);
			input[k].index = k + 1;
			input[k].value = temp/(MAX*1.0); 	//   
		}
		input[85].index = -1;		//         -1
    	int predictValue=svm_predict(svmModel, input); //  svm_predict    
		predictvalue.push_back(predictValue);

		cout<

完全なエンジニアリングコード+実験報告ダウンロード(ポイントフリー):http://download.csdn.net/detail/jsgaobiao/9332813
五、SVMで多分類を実現する
SVMは2つの分類器であり、複数のカテゴリに遭遇した場合、一般的に次の2つのポリシーが採用される. 
a.一対多法(one-versus-rest、略称1-v-r SVms).訓練時にあるカテゴリのサンプルを順次1つに分類し,他の残りのサンプルを別のカテゴリに分類することで,kつのカテゴリのサンプルがkつのSVMを構築する.分類時に未知のサンプルを最大分類関数値を持つクラスに分類します.
b.一対一法(one-versus-one、略称1-v-1 SVms).いずれかの2種類のサンプルの間で1つのSVMを設計する方法であるため、k個のカテゴリのサンプルはk(k-1)/2個のSVMを設計する必要がある.未知のサンプルを分類すると、最後に最も得票されたカテゴリが未知のサンプルのカテゴリとなります.Libsvmにおける多種類の分類はこの方法によって実現される.