import java.awt.Color; // // 平均値に基づく閾値の計算クラス // class ThresholdByAverage implements ThresholdDeterminer { // 閾値と符号(グループ0の方が特徴量が閾値よりも小さければ真) protected float threshold; protected boolean is_first_smaller; // 特徴量データ(グラフ描画用) protected float features0[]; protected float features1[]; // 各グループの特徴量の平均値(グラフ描画用) protected float average0; protected float average1; // 度数分布(ヒストグラム) protected float histogram_min_f, histogram_max_f, histogram_delta_f; protected int[] histogram0; protected int[] histogram1; // 度数分布のデフォルトの区間幅 float default_histogram_delta = 0.02f; int default_histogram_size = 20; // 閾値の決定方法の名前を返す public String getThresholdName() { return "平均値による閾値の決定"; } // 両グループの特徴量から閾値を決定する public void determine( float[] features0, float[] features1 ) { // 各グループの平均値を計算 average0 = 0.0f; // 要実装 average1 = 0.0f; // 要実装 // 2つの平均値の中央値を計算 threshold = 0.0f; // 要実装 // 符号を計算 is_first_smaller = false; // 要実装 // 特徴量データを記録(グラフ描画用) this.features0 = features0; this.features1 = features1; } // 閾値をもとに特徴量から文字を判定する public int recognize( float feature ) { // グループ0の特徴量 < 閾値 < グループ1の特徴量 if ( is_first_smaller ) { if ( feature < threshold ) return 0; else return 1; } // グループ1の特徴量 < 閾値 < グループ0の特徴量 else { if ( feature < threshold ) return 1; else return 0; } } // 閾値を返す public float getThreshold() { return threshold; } // 特徴空間のデータをグラフに描画(グラフオブジェクトに図形データを設定) public void drawGraph( GraphViewer gv ) { // 2つの特徴量の度数分布(ヒストグラム)を計算 makeHistogramsBySize( default_histogram_size ); // データ分布を散布図で描画 drawScatteredGraph( gv, 0.0f, -1.0f ); // 度数分布を棒グラフで描画 drawHistogram( gv ); // 平均値を縦線で描画 drawAverage( gv ); // 閾値を描画 drawThreshold( gv ); } // // 閾値計算のための内部メソッド // // 指定された範囲・区間で特徴量の度数分布(ヒストグラム)を計算 //(min_f, maxf はヒストグラムを作成する特徴量の範囲、delta_f は各区間ごとの特徴量の幅) protected int[] makeHistogram( float[] features, float min_f, float max_f, float delta_f ) { // ヒストグラムの区間数を計算して配列を初期化 int histogram_size = (int) java.lang.Math.ceil( ( max_f - min_f ) / delta_f ); int[] histogram = new int[ histogram_size ]; // ヒストグラムの各区間におけるデータの出現回数をカウント for ( int i=0; i= histogram_size - 1 ) seg_no = histogram_size - 2; histogram[ seg_no ] ++; } return histogram; } // 特徴量の度数分布(ヒストグラム)を計算 //(全体をいくつの区間に分けるかという区間数を指定、区間幅は自動決定) protected void makeHistogramsBySize( int segment_size ) { // 度数を調べる範囲を設定 float delta_f; float min_f, max_f; min_f = features0[ 0 ]; max_f = features0[ 0 ]; int i; for ( i=1; i max_f ) max_f = features0[ i ]; } for ( i=0; i max_f ) max_f = features1[ i ]; } // 範囲・区間数に応じて区間幅を設定 delta_f = ( max_f - min_f ) / segment_size; // ヒストグラムの設定を記録 histogram_min_f = min_f; histogram_max_f = max_f; histogram_delta_f = delta_f; // 両端の区間の分布が0になるように、左右に区間を1つ追加する histogram_min_f -= delta_f; histogram_max_f += delta_f; // ヒストグラムを作成 histogram0 = makeHistogram( features0, histogram_min_f, histogram_max_f, delta_f ); histogram1 = makeHistogram( features1, histogram_min_f, histogram_max_f, delta_f ); } // 特徴量の度数分布(ヒストグラム)を計算 //(各区間の区間幅を指定、区間数は自動決定) protected void makeHistogramsByWidth( float delta_f ) { // 度数を調べる範囲を設定 float min_f, max_f; min_f = features0[ 0 ]; max_f = features0[ 0 ]; int i; for ( i=1; i max_f ) max_f = features0[ i ]; } for ( i=0; i max_f ) max_f = features1[ i ]; } // 区間幅に応じて範囲を調整(区間の両端値が区間幅の整数倍になるよう調整) min_f = (int)( min_f / delta_f ) * delta_f; max_f = (int)( max_f / delta_f + 1 ) * delta_f; // ヒストグラムの設定を記録 histogram_min_f = min_f; histogram_max_f = max_f; histogram_delta_f = delta_f; // 両端の区間の分布が0になるように、左右に区間を1つ追加する histogram_min_f -= delta_f; histogram_max_f += delta_f; // ヒストグラムを作成 histogram0 = makeHistogram( features0, histogram_min_f, histogram_max_f, delta_f ); histogram1 = makeHistogram( features1, histogram_min_f, histogram_max_f, delta_f ); } // // 特徴空間描画のための内部メソッド // // 閾値を描画 protected void drawThreshold( GraphViewer gv ) { // 閾値を描画 GraphPoint data[]; data = new GraphPoint[ 1 ]; data[ 0 ] = new GraphPoint(); data[ 0 ].x = getThreshold(); data[ 0 ].y = 0.0f; gv.addFigure( GraphViewer.FIG_Y_LINE, Color.MAGENTA, data ); } // データ分布を散布図で描画 protected void drawScatteredGraph( GraphViewer gv ) { drawScatteredGraph( gv, 0.0f, 0.0f ); } // データ分布を散布図で描画 protected void drawScatteredGraph( GraphViewer gv, float y0, float y1 ) { // 各データを散布図で描画 GraphPoint data[]; data = new GraphPoint[ features0.length ]; for ( int i=0; i