• 検索結果がありません。

comment.dvi

N/A
N/A
Protected

Academic year: 2021

シェア "comment.dvi"

Copied!
13
0
0

読み込み中.... (全文を見る)

全文

(1)

プログラムの解説

情報科学研究科 情報通信技術論

工学部電子情報システム・応物系

(通信・情報コース)

パターン認識論

サンプルプログラム

(sample1.c)

の内容

サンプルプログラム (sample1.c) は 2 クラスの 2 次元データに対して、Nearest Neighbor 法を用 いて認識を行うプログラムである。入力データは、クラス 1 の学習データ (2D-class1.dat)、クラ ス 2 の学習データ (2D-class2.dat)、未知データ (2D-test.dat) の 3 つである。 Nearest Neighbor Nearest Neighbor 法とは、未知データの最近傍に存在するデータが所属するクラスを、未知デー タのクラスであると判別する方法である。 すなわち、未知データと全学習データの距離を計算し、距離が最小となる学習データが所属する クラスを認識結果とする (図 1)。

ᧂ⍮䊂䊷䉺

䉪䊤䉴䋱ቇ⠌䊂䊷䉺

䉪䊤䉴

2ቇ⠌䊂䊷䉺

ᧂ⍮䊂䊷䉺䈲䉪䊤䉴䋱䈪䈅䉎䈫್ᢿ

図 1: NN 法

(2)

サンプルプログラム

サンプルプログラム (sample1.c) を以下に示す。 /* --- */ /* パターン認識論 サンプルプログラム (2 次元データ 2 クラス ver.) */ /* --- */ /* Nearest Neighbor */ #include <stdio.h> #include <stdlib.h> #include <math.h> #define LDATA 20 // 学習データ数 #define TDATA 40 // テストデータ数 #define DIM 2 // データ次元数 double class1[LDATA][DIM]; // クラス 1 の学習データ double class2[LDATA][DIM]; // クラス 2 の学習データ double test[TDATA][DIM]; // テスト (未知) データ int tans[TDATA]; // テストデータの正解 int result[TDATA]; // 認識結果 double met1[TDATA]; // 最小値 (クラス 1) double met2[TDATA]; // 最小値 (クラス 2)

int main(int argc, char* argv[]){

/* --- 関数のプロトタイプ宣言 --- */ int input(); // データ入力

int nearest(); // Nearest Neighbor法 int output(); // 認識結果出力 /********** データ入力 **********/ input(); /********** Nearest Neighbor法 **********/ nearest(); /********** 認識結果出力 **********/ output(); return(0); }

(3)

/* --- */

/* データ入力 */

/* --- */ int input(){

FILE *fin1, *fin2, *fin3; // ファイルポインタ int i, j;

/* --- ファイル open --- */ fin1 = fopen("2D-class1.dat", "r");

if( fin1 == NULL){

fprintf(stderr, "file open error : 2D-class1.dat \n"); return -1; }

fin2 = fopen("2D-class2.dat", "r"); if( fin2 == NULL){

fprintf(stderr, "file open error : 2D-class2.dat \n"); return -1; }

fin3 = fopen("2D-test.dat" , "r"); if( fin3 == NULL){

fprintf(stderr, "file open error : 2D-test.dat \n"); return -1; } /* --- データの読み込み --- */ for(i=0;i<LDATA;i++){ for(j=0;j<DIM;j++){ fscanf(fin1, "%lf", &class1[i][j]); fscanf(fin2, "%lf", &class2[i][j]); } } for(i=0;i<TDATA;i++){

for(j=0;j<DIM;j++) fscanf(fin3, "%lf", &test[i][j]); fscanf(fin3, "%d", &tans[i]);

}

/* --- ファイル close --- */ fclose(fin1); fclose(fin2); fclose(fin3);

return 0; }

(4)

/* --- */ /* Nearest Neighbor */ /* --- */ int nearest(){

double min1, min2, dist, tmp; /* min1・min2 はクラス1・2に属 */ /* するデータの中で一番近い距離 */ int i, j, k; for(k=0;k<TDATA;k++){ min1 = min2 = 9999999; // 初期値を大きな値に設定 for(i=0;i<LDATA;i++){ /* --- クラス1のデータの中で一番近いデータの距離を測定 --- */ tmp = 0; for(j=0;j<DIM;j++)

tmp += (test[k][j] - class1[i][j]) * (test[k][j] - class1[i][j]); dist = sqrt(tmp);

if(min1 > dist) min1 = dist; /* min1に代入 */

/* --- クラス2のデータの中で一番近いデータの距離を測定 --- */ tmp = 0;

for(j=0;j<DIM;j++)

tmp += (test[k][j] - class2[i][j]) * (test[k][j] - class2[i][j]); dist = sqrt(tmp);

if(min2 > dist) min2 = dist; /* min2に代入 */ }

met1[k] = min1; met2[k] = min2;

/* 最近傍点のクラスを認識結果とする */ if(min1 <= min2) result[k] = 1; else result[k] = 2; } return 0; } /* --- */ /* 結果出力 */ /* --- */ int output(){

(5)

FILE *fout; int k;

/* --- ファイル open --- */ fout = fopen("2D-result.dat", "w"); if( fout == NULL){

fprintf(stderr, "file open error : result.dat \n"); return -1; }

/* --- データ出力 --- */

fprintf(fout, "NUM MIN1 MIN2 RES ANS o/x\n"); fprintf(fout, "---\n"); for(k=0;k<TDATA;k++){

fprintf(fout, "%3d %4.2lf %4.2lf %3d %3d " , k+1, met1[k], met2[k], result[k], tans[k]); if(result[k] == tans[k]) fprintf(fout, "o \n"); else fprintf(fout, "x \n"); } /* --- ファイル close --- */ fclose(fout); return 0; }

(6)

サンプルプログラムの解説

関数のプロトタイプ宣言

サンプルプログラム内で使用している関数は、

input() 学習データ、テストデータの読み込みを行う nearest() Nearest Neighbor 法

output() 認識結果の出力を行う の 3 つである。 これらの関数を用いるためには、リスト 1 のように関数のプロトタイプ宣言を行う必要がある。 リスト 1   /* --- 関数のプロトタイプ宣言 --- */ int input(); // データ入力

int nearest(); // Nearest Neighbor法 int output(); // 認識結果出力   データの読み込み 入力ファイルの形式は、 データ 1 の 1 次元目 (x の値) データ 1 の 2 次元目 (y の値) データ 2 の 1 次元目 (x の値) データ 2 の 2 次元目 (y の値) データ 3 の 1 次元目 (x の値) データ 3 の 2 次元目 (y の値) .. . ... のようになっている。各データを配列に格納するには、i をデータ番号、j を次元としたとき、以 下のように配列の添字を与えれば良い。 class[i][j] 2 次元配列の第 1 添字をデータ番号、第 2 添字を次元数に割り当てる。したがって、配列の宣言 は以下のように行う。 リスト 2   #define LDATA 20 // 学習データ数 #define TDATA 40 // テストデータ数 #define DIM 2 // データ次元数 double class1[LDATA][DIM]; // クラス 1 の学習データ double class2[LDATA][DIM]; // クラス 2 の学習データ double test[TDATA][DIM]; // テスト (未知) データ  

(7)

また、データの読み込み部は以下のようになる。 リスト 3   /* --- データの読み込み --- */ for(i=0;i<LDATA;i++){ for(j=0;j<DIM;j++){ fscanf(fin1, "%lf", &class1[i][j]); fscanf(fin2, "%lf", &class2[i][j]); } } for(i=0;i<TDATA;i++){

for(j=0;j<DIM;j++) fscanf(fin3, "%lf", &test[i][j]); fscanf(fin3, "%d", &tans[i]);

}

(8)

サンプルプログラム実行の手順

1. 以下の URL より、sample1.c、2D-class1.dat、2D-class2.dat、2D-test.dat をダウンロードす る。 http://www.it.ecei.tohoku.ac.jp/pattern/ 2. サンプルプログラムをコンパイルする。 % cc sample1.c -lm 3. サンプルプログラムを実行する % a.out 4. 実行結果を確認する % less result.dat

(9)

テストプログラム

(u-eigen.c

g-eigen.c)

の内容

テストプログラム (u-eigen.c、g-eigen.c) は、N 次元の正方行列の固有値問題・一般固有値問題 を解くプログラムである。固有値、固有ベクトルを出力する。このプログラムでは CLAPACK と いう数値計算ライブラリを使用している。 • u-eigen.c - 固有値問題 Ax = λx を解く • g-eigen.c - 一般固有値問題 Ax = λBx を解く

テストプログラム

固有値問題・一般固有値問題を解くテストプログラムを以下に示す。 • 固有値問題 (u-eigen.c) /* 固有値問題 Ax = λ x */

/* C interface example for dsyev hidehisa_2006/05/01 */

#include <stdio.h> #include <stdlib.h>

#include <PRT.h> /* #define L (64) */

int main( void ){

FILE *fp; int ds; int N; // 配列の次元数 double A[L][L],E[L],V[L][L]; int i,j; /* --- ファイル --- */ fp=fopen( "NA4.dat", "r"); // 入力ファイル if( fp==NULL ){

fprintf(stderr,"file open error\n"); return(-1); } else{ fscanf(fp, "%d", &N ); // 配列の次元数 for(i=0;i<N;i++) for(j=0;j<N;j++) fscanf(fp,"%lf", &A[i][j] ); // 配列の入力 fclose( fp );

(10)

/* --- 関数コール --- */ ds=dsyev(N,A,E,V);

if( ds < 0 ){ perror("dsyev"); exit(2); }

/* --- 固有値・固有ベクトル出力 --- */ fprintf(stderr,"*** Output ***\n\n");

for(i=0;i<N;i++) fprintf(stderr,"\t Eigenvalue"); fprintf(stderr,"\n");

for(i=0;i<N;i++) fprintf(stderr,"\t %9.6lf", E[i] ); fprintf(stderr,"\n\n");

for(i=0;i<N;i++) fprintf(stderr,"\t Eigenvector"); fprintf(stderr,"\n");

for(j=0;j<N;j++){

for(i=0;i<N;i++) fprintf(stderr,"\t %9.6lf", V[i][j] ); fprintf(stderr,"\n"); } fprintf(stderr,"\n"); return( 0 ); } • 一般固有値問題 (g-eigen.c) /* 一般固有値問題 Ax = λ Bx */

/* C interface example for dsygv hidehisa_2006/05/01 */

#include <stdio.h> #include <stdlib.h>

#include <PRT.h> /* #define L ( 64 ) */

int main( void ){

FILE *fp; int ds; int N; // 配列の次元 double A[L][L],B[L][L],E[L],V[L][L]; int i,j; /* --- ファイル --- */ fp=fopen( "NAB4.dat", "r"); if( fp==NULL ){

fprintf(stderr,"file open error\n"); return(-1); }

(11)

fscanf(fp, "%d", &N ); // 配列の次元数 if( N > L ){ perror("Input N"); exit(1); }

for(i=0;i<N;i++) for(j=0;j<N;j++) fscanf(fp,"%lf", &A[i][j] ); // 入力 A for(i=0;i<N;i++) for(j=0;j<N;j++) fscanf(fp,"%lf", &B[i][j] ); // 入力 B fclose( fp ); } /* --- 関数コール --- */ ds=dsygv(N,A,B,E,V);

if( ds < 0 ){ perror("dsygv"); exit(2); }

/* --- 固有値・固有ベクトル出力 --- */ fprintf(stderr,"*** Output ***\n\n");

for(i=0;i<N;i++) fprintf(stderr,"\t Eigenvalue"); fprintf(stderr,"\n");

for(i=0;i<N;i++) fprintf(stderr,"\t %9.6lf", E[i] ); fprintf(stderr,"\n\n");

for(i=0;i<N;i++) fprintf(stderr,"\t Eigenvector"); fprintf(stderr,"\n");

for(j=0;j<N;j++){

for(i=0;i<N;i++) fprintf(stderr,"\t %9.6lf", V[i][j] ); fprintf(stderr,"\n");

}

fprintf(stderr,"\n");

return( 0 ); }

(12)

テストプログラムの解説

データの読み込み テストプログラムの入力ファイルは以下のような形式になっている。一般固有値問題の場合を例 に示す (NAB4.dat)。1 行目に行列の次元数を指定する。 • 一般固有値問題 (g-eigen.c) の場合 例)4 次元行列 A = ⎛ ⎜ ⎜ ⎜ ⎜ ⎝ 2 1 1 2 1 1 1 1 1 1 2 2 2 1 2 4 ⎞ ⎟ ⎟ ⎟ ⎟ ⎠ B = ⎛ ⎜ ⎜ ⎜ ⎜ ⎝ 153 31 58 −58 31 153 −58 58 58 −58 153 31 −58 58 31 153 ⎞ ⎟ ⎟ ⎟ ⎟ ⎠ 4 // 行列の次元数 2 1 1 2 // 行列 A 1 1 1 1 1 1 2 2 2 1 2 4 153 31 58 -58 // 行列 B 31 153 -58 58 58 -58 153 31 -58 58 31 153 ※固有値問題 (u-eigen.c) の場合は行列 A のみを与える。

(13)

テストプログラム実行の手順

1. 以下の URL より、u-eigen.c、g-eigen.c、NA4.dat、NAB4.dat をダウンロードする。 http://www.it.ecei.tohoku.ac.jp/pattern/ 2. サンプルプログラムをコンパイルする。数値計算ライブラリ (LAPACK) を使用するため、末 尾に"$PRTFLAG"を付加する。 % cc u-eigen.c $PRTFLAG % cc g-eigen.c $PRTFLAG 3. サンプルプログラムを実行し、実行結果を確認する。 % a.out

参照

関連したドキュメント

Also, for the sake of comparison we give the probability density functions of the terminal wealth of portfolios managed by the pure bond strategy, whose fraction of wealth invested

The main purpose of this paper is to extend the characterizations of the second eigenvalue to the case treated in [29] by an abstract approach, based on techniques of metric

The damped eigen- functions are either whispering modes (see Figure 6(a)) or they are oriented towards the damping region as in Figure 6(c), whereas the undamped eigenfunctions

Given a compact Hausdorff topological group G, we denote by O(G) the dense Hopf ∗-subalgebra of the commutative C ∗ -algebra C(G) spanned by the matrix coefficients of

AUTO : 出力先機器の EDID に従います。. DVI :

p-Laplacian operator, Neumann condition, principal eigen- value, indefinite weight, topological degree, bifurcation point, variational method.... [4] studied the existence

DVI-D シングルリンク信号エクステンダー DVIDEX-UTPPSV は、安価な CAT5e 以上の UTP LAN ケ ーブルを使用して、DVI-D

An important new aspect of the results in [ 12 ] is that they enable one to obtain uniqueness of stationary distributions for stochastic delay differential equations when the