めも

これはメモ。

XGBoostで自分で設計した目的関数(objectiveを自分で定義)で回帰を行う

やること

xgboostの目的関数を定義済みのものから自分で定義したものに変える。 回帰は常に 正解ラベル=予測の平均値 だったらいいのだけれど、予測を外したらまずいケースも現実問題では存在する。 なので、予測を外したらダメなケースだけは特にペナルティを大きくした目的関数を自分で定義したかった。 今回は練習でQuantile Regressionをxgboostを使って行う。

Quantile Regression

Koenker, Roger. Quantile regression. No. 38. Cambridge university press, 2005.

イメージ

f:id:misos:20170122001713p:plain

赤実線以下のサンプル(正解ラベルよりも予測値の方が大きいケース)をなくしたい。 なので非対称(asymmetric)な損失を自分で定義してモデルを作りたい。 Quantile regressionはすぐ実装できそう。

scikit-learnのGradientBoostingでの実装

scikit-learnのGradient Boostingのオプションとして選択可能。アルファの値で罰則項の値のバランスを指定する。 scikit-learnでここ以外でQuantile Regressionを目にする機会ない気がする。

class QuantileLossFunction(RegressionLossFunction):
    """Loss function for quantile regression.
    Quantile regression allows to estimate the percentiles
    of the conditional distribution of the target.
    """

    def __init__(self, n_classes, alpha=0.9):
        super(QuantileLossFunction, self).__init__(n_classes)
        assert 0 < alpha < 1.0
        self.alpha = alpha
        self.percentile = alpha * 100.0

    def init_estimator(self):
        return QuantileEstimator(self.alpha)

    def __call__(self, y, pred, sample_weight=None):
        pred = pred.ravel()
        diff = y - pred
        alpha = self.alpha

        mask = y > pred
        if sample_weight is None:
            loss = (alpha * diff[mask].sum() -
                    (1.0 - alpha) * diff[~mask].sum()) / y.shape[0]
        else:
            loss = ((alpha * np.sum(sample_weight[mask] * diff[mask]) -
                    (1.0 - alpha) * np.sum(sample_weight[~mask] * diff[~mask])) /
                    sample_weight.sum())
        return loss

scikit-learn/gradient_boosting.py at master · scikit-learn/scikit-learn · GitHub

sample_weightの重み分だけ正解ラベルのとの差が0以下と以上のサンプルで alpha(1.0 - alpha)だけ罰則が科される。

XGBoostの目的関数を変更する

実装のサンプルでは

def objective_function(preds, dtrain):
    ....
    return grad, hess

dtrainxgboost.DMatrix のデータ。gradとhessが以下の論文のGとHの部分に対応している、はず。

Chen, Tianqi, and Carlos Guestrin. "Xgboost: A scalable tree boosting system." Proceedings of the 22Nd ACM SIGKDD International Conference on Knowledge Discovery and Data Mining. ACM, 2016.

目的関数

def quantile(preds, labels):
    alpha = .8
    N = preds.shape[0]
    O = np.zeros(N)+1
    
    mask = labels > preds
    grad = ((alpha * mask) - ((1.0 - alpha) * (1-mask))) * labels 
    hess = O
    
    return grad, hess

hessは固定で予測値が正解を下回った時にalphaをかけるように変更。 このあともうちょっと目的関数をクロスバリデーションしながら調節。

結果

入力データは 0 ~ 40の乱数xとxに対して多項式で従う特徴を50個くらい適当につけたもの。

f:id:misos:20170122002539p:plain

赤実線以下のサンプルがほとんどなくなったことがわかる。残りの誤差が大きいデータは適当なアンサンブルを作ってカットすればいい、かな?

他の目的関数

問題によって適宜変更する必要あり。

paper.hatenadiary.jp

OPENVIS, ウェブ上のインフォマティクスに関する学会

ウェブ上でのデータ可視化に関する学会。 可視化の人たちだけあって、スライドも綺麗。 スライドは全てダウンロード or 閲覧できて発表動画も公開されているので、 暇なときに面白そうなのが見れたらなあ、と思う。

ついでに可視化に関する他の学会のリンク。

この分野の人ではないから学会の知名度とかの感覚がわからない。

OPENVIS

2017

2016

2015

IEE VIZ 2017

IEEE VIS 2017

IVAPP 2017

損失関数・評価指標のめも

書いてる途中でドキュメントのいいページを見つけたので書くのやめました。 ただドキュメントには非対称な損失関数に関しては定義されてないらしい。 そのような設定(足りないのはokだけど超えるとものすごいロスになるような状態)での回帰や一部の分類問題は モデルを自分で定義して解かないといけない。

非対称な損失での回帰:Efron, Bradley. "Regression percentiles using asymmetric squared error loss." Statistica Sinica (1991): 93-125.など

scikit-learnのモデル評価に関するドキュメント

基本ここを見ればなんとかなる。

http://scikit-learn.org/stable/modules/model_evaluation.html

回帰(Regression)問題

Hinge loss

ヒンジ関数 - 機械学習の「朱鷺の杜Wiki」

平均絶対誤差(Mean absolute error)

Mean Squared Error

PRMLバイアス・バリアンスの分解でおなじみ。

ニクラス分類(Binary Classification)問題

F1 score

精度と再現率の調和平均を求めたもの。

F値 - 機械学習の「朱鷺の杜Wiki」

MAP(Mean average precision)

マルチラベル分類(Multi-Label Classification)問題

Hamming Loss

{
\frac{1}{|D|} \sum_{i=1}^{|D|} \frac{xor(x_i, y_i)}{|L|},
}

Logarithmic Loss

[tex:{ -\frac{1}{N}\sum{i=1}^N\sum{j=1}^My{ij}\log(p{ij}) }]

カッパ係数(Cohen’s kappa)

18.7 - Cohen's Kappa Statistic for Measuring Agreement | STAT 509

その他

Brier Score

確率の予測精度の評価指標。

http://scikit-learn.org/stable/modules/generated/sklearn.metrics.brier_score_loss.html#sklearn.metrics.brier_score_loss

nDCG (normalized Discounted Cumulated Gain)

非対称な損失関数

本当はこれを調べたかった。

Structured Optimization for Big Data and Machine Learning | Applied Mathematics, University of Washington

確率的モデルのライブラリ Edward

こちら:http://edwardlib.org/

Dustin Tran, Alp Kucukelbir, Adji B. Dieng, Maja Rudolph, Dawen Liang, and David M. Blei. 2016. Edward: A library for probabilistic modeling, inference, and criticism. arXiv preprint arXiv:1610.09787.

チュートリアルベイジアン線形回帰とかが載ってる。 tensor flowとKerasとも組み合わせて使える?春休みに試してみようと思います。

エラー解決:LaTeX Error: Cannot determine size of image (no BoundingBox)のエラー

エラー内容

LaTeX Error: Cannot determine size of image (no BoundingBox)

解決法

Step1

\usepackage[dvipdfmx]{graphicx}

大概これで解決。

Step2

dvipdfmxが無いと言われている場合は、こちらからダウンロードして texファイルと同じディレクトリ内にdvipdfmx.def を置いて実行してみる。

Step3

エラーメッセージに従って --shell-escape オプションを指定して

platex --shell-escape ~~~.tex

とする。

Step4

よく見ると

runpopen command not allowed: extractbb

とエラーメッセージに含まれていた場合はextractbbが実行できない!と言われてる。

$ sudo vim  /usr/local/texlive/texmf-local/web2c/texmf.cnf

を編集して

shell_escape_commands = \
bibtex,bibtex8,bibtexu,upbibtex,biber,\
kpsewhich,\
makeindex,mendex,texindy,\
mpost,upmpost,\
repstopdf,epspdf,extractbb

を保存する。そのあと

$ sudo mktexlsr

を実行。そうすればextractbbのエラーが出なくなる、はず。