Cross-Entropy MethodによるSVMのパラメータ最適化

パターン認識の講義の課題で以下のコンペに参加したのでその記録に. http://universityofbigdata.net/competition/5723788444434432

Hog特徴量

今回のテーマが与えられた名刺画像の記載項目の予測だったので,画像を横長に調整してからhog特徴量に変換をするようにした.

www26.atwiki.jp

DIR_IMAGES = 'sansan-001/images'
IMG_SIZE = 100

def load_hog(df):
    X = []
    for i, row in df.iterrows():
        img = Image.open(os.path.join(DIR_IMAGES, row.filename))
        img = img.crop((row.left, row.top, row.right, row.bottom))
        if img.size[0] < img.size[1]:
            img = img.transpose(Image.ROTATE_90)
        img = img.convert('L')
        img = np.array(img.resize((216, 72)))/255.0
        img = hog(img, orientations=6, pixels_per_cell=(12,12), cells_per_block=(1,1))
        x = np.asarray(img, dtype=np.float32)
        x = x.flatten()
        X.append(x)

    X = np.array(X)
    return X

Pipelineの生成とGridSearch

GridSearchにかけるパイプラインを生成.
今回は色々試したのとトレーニングデータの数が少なかったのでPCAかけてSVMを用いて精度を上げていくことにした.
9項目あったのでそれぞれに対してOne vs Restの判別器を作ってGridSearchで良さそうなパラメータの学習.
マシンスペックがよくないのでパターン数があまり増えないようにした.

    columns = ['company_name', 'full_name', 'position_name',
               'address', 'phone_number', 'fax',
               'mobile', 'email', 'url']

    '''''''''''''''
    Data Loading
    '''''''''''''''
    df_train = pd.read_csv('sansan-001/train.csv')
    X_train = load_hog(df_train)
    Y_train = df_train[columns].values

    '''''''''''''''
    GridSearch
    '''''''''''''''
    pipe_lr = Pipeline([('sc', StandardScaler()), ('pca', PCA()), ('svc', SVC(probability=True))])
    parameter =  {
        'pca__n_components': [100, 150, 200],
        'svc__C': [1, 10, 100, 1000],
        'svc__kernel': ['rbf'],
        'svc__gamma':[0.0001, 0.001, 0.01],
        'svc__probability':[True]
        }

    clf = GridSearchCV(pipe_lr, parameter, cv=5, n_jobs = -1)
    score_average = 0
    for n in range(Y_dev.shape[1]):
        clf.fit(X_train, Y_train[:, n])
        save_model(clf.best_estimator_, filename='best_svm-' + str(n) + '.pkl')
   

Cross-Entropy Methodによるパラメータ最適化

上記のGridSearchで得られたモデルを使ってテストデータに対して適応して提出してみたらこの時点では過学習もみられずAUCスコアが0.98ちょっとだったので, 更にパラメータを最適化して精度を上げるためにCross-Entropy Methodを実装してみた.

Cross-Entropy Method

Cross-Entropy Methodは分布推定アルゴリズムに類似したパラメータ学習法.
まずパラメータを持ったサンプルを p*N 個作る.
そのサンプルの分布を  U とし,Cross-Entropy  D_{CE}が最小となる分布gを選択する.
 D_{CE}(g||U) = \int g(x)\log \frac{U(x)}{g(x)}dx
この分布gを元に,サンプルをN個生成する.このサンプルを持ったSVMでテストデータに対して交差検証を行い,精度の良いサンプル p*Nをエリートサンプルとして取り出し,それを元に新たな分布Uとする.
これを繰り返してパラメータの学習を行う.

実装

パラメータの分布に関しては正規分布を前提として上位20%のパラメータの平均値を新しい分布の平均値とした.
分散に関しては初期値が最適解に近いと想定して分散一定にし,平均値だけを変動させてスコアの変動を確認した.

結果

色々あって実装するのが遅くなってコンペの開催期間中に結果出なかった辛い.
具体的な数字は出してないけれど,どの項目においてもテストデータの分類精度の向上はみられた.

終わりに

今回はじめて機械学習のコンペに参加して楽しかったので次はKaggleのコンペに参加してみている. https://www.kaggle.com/c/planet-understanding-the-amazon-from-space

機械学習詳しい人からのフィードバック欲しい…
まさかりでもいいので投げて欲しい…
機械学習できるマンになりたい…