0

私の問題の要約:検出があります (二項分類、不均衡問題)。シグモイドを使用してサンプルを分類します。報告された f スコア、適合率、および再現率は両方のクラスを考慮しているようです。たとえば、真陽性は正しく分類されたサンプルの総数であり、正しく分類されたクラス '1' に属するサンプルの総数ではないようです。

より長い説明:私の実験では、人に関する人口統計データがあり、彼らが製品を購入したかどうかを予測する必要があります。PCA を使用して初期機能を 4 つの機能だけに減らし、データを csv ファイルに保存しました (最初の列にはクラス ラベル '0' と '1' があります)。ほとんどの人は購入しなかったため、2 つのクラスは非常にバランスが取れていないことに注意してください。CSVDatasetクラスを使用して読み取ります。

dataset: &train !obj:pylearn2.datasets.csv_dataset.CSVDataset {
        path: 'input.csv',
        task: 'classification'
}

簡単な分類モデルから始めたいと思います。パフォーマンスの尺度として f スコアを使用します。したがって、私の最初のアイデアは、単一のシグモイド層を持つ MLP モデルを使用することでした (デフォルトのモニター「検出」は再現率、精度、f スコアを提供します)。

model: !obj:pylearn2.models.mlp.MLP {
        layers: [
                 !obj:pylearn2.models.mlp.Sigmoid {
                     layer_name: 'y',
                     dim: 2,
                     irange: .005
                 }
                ],
        nvis: 4,
    }

私の最初のアイデアは、dim を 1 に設定することでした (決定規則は、出力 > 0.5 の場合はクラス '1' を選択し、< 0.5 の場合はクラス '0' を選択します)。しかし、 ValueError: Can't convert to VectorSpace of dim 1というエラーが発生しました。 be: out1 > out0 の場合は「1」を選択、out1 の場合

私のtrain.yamlでは、ドキュメントで提供されているソフトマックス サンプル ノートブックに多かれ少なかれ従っています。たとえば、BGD アルゴリズムを使用し、batch_size をトレーニング セット内のサンプルの総数 (74164 サンプル、小さなデータセット!) として設定して、パフォーマンスを手動でチェックするときの混乱を避けます。

モデルは提供されているtrain.pyスクリプトを使用してトレーニングされ、結果を見るまではすべて問題ないように見えました。前述のように、検出するクラス ('1') が非常にまれにしか発生しない検出の問題です。したがって、報告された train_y_f1 の高い値を見て非常に驚きました (1 エポック後の最良の結果は約 94% です)。

これを確認するために、提供されたスクリプト predict_csv.py を使用して手動で f スコアを計算し、予測をロードしました。実際にはミスしかないことがわかりました (すべての「1」は「0」に分類されました)。そのため、適合率、再現率、および f スコアはすべてゼロになるはずです。検出モニターがより高い値を報告するのはなぜですか?

いくつかの調査の後、MLP には各クラスの出力があることがわかり、get_detection_channels_from_state() で定義された真陽性と偽陽性が実際に両方のクラス '1' と「0」、たとえば真陽性は、「1」として分類された「1」に属するベクトルの数を、「0」として分類された「0」に属するベクトルの数に合計したものです。したがって、MLP はすべてを「0」として分類しており、ほぼすべてのベクトルが「0」に属しているため、パフォーマンスは良好です。これは、正しい分類率が適切な尺度ではない不均衡な検出問題の既知の問題であり、f スコアや AUC などの尺度がある理由です。でも、

これは Sigmoid クラスの設計者に知られていると想像できるので、何か間違ったことをしているとしか思えません。うまくいけば、誰かが私にヒントを与えることができます:)

注:この質問を pylearn2 ユーザー メーリング リストに送信しました。返事が来たらここにコピペします…

4

1 に答える 1

0

pylearn モニターは、エポック全体ではなく、バッチごとに f1 スコア、ミスクラスの割合などを計算します。レポートを生成するとき、f1 スコアはエポック内のすべてのバッチの f1 の平均です。すべてのバッチの平均を報告することは、ミスクラスのような数量を見ると問題なく機能します。

misclass[n] は n 番目のバッチのスコアです。
misclass_epoch = mean(misclass[0] + misclass[1] +.. misclass[n])

ただし、f1 スコアに対して同じステートメントを作成することはできません:
f1_epoch != mean(f1[0] + f1[1] +.. f1[n])
where f1[n] = 2*precision[n]*リコール[n]/(精度[n] + リコール[n])

デモンストレーションのために、バッチ サイズをデータ セットのサイズに設定してみてください (mnist の例ではこれを回避できます)。その場合、f1 スコアは正しくなります。

したがって、最良のアドバイスは、ミスクラスのようなモニターで量に注意することです。ここでは、バッチの平均がエポックの値と同じです。nn をトレーニングしたら、検証セット全体の予測を行い、その時点で f1 スコアを計算できます。

于 2015-04-24T04:59:08.633 に答える