めも

ゲームの攻略・プログラミングの勉強内容・読んだ本の感想のような雑記を主に投稿するブログです

特徴選択について

機械学習アルゴリズムの入力となる特徴の選択手法について。

特徴選択とその種類

特徴選択(とくちょうせんたく、英: feature selection)とは、機械学習と統計学の用語であり、頑健な学習モデルの構築のため、特徴集合のうち意味のある部分集合だけを選択する手法のことを指します。 [引用元 Wikipedia:特徴選択]

そして、特徴選択は特徴の選択の仕方によってフィルター法・ラッパー法に大分されます。また、特定のモデル内部で特徴選択を行う機構が入っているものはエンベッド法(embeded method)と呼びます。

教師データを利用できるかどうかによって教師あり・半教師あり・教師なしの分類もできます。

ここで呼ぶ「特徴」とはすでに数値化されたものを指しており、元の生データから特徴量を計算するステップ(以下のスライドなど)を経た後、どの特徴を予測モデルの入力として利用するかを計算するステップが特徴選択です。

www.slideshare.net

まとめると、特徴の選択の仕方によって

  • フィルタ法(Fileter method)
  • ラッパー法(Wrapper method)
  • エンベディング法(Embed method)

ラベル情報の使い方によって

  • 教師あり(Supervised)
  • 半教師あり(Semi-supervised)
  • 教師なし(Un-supervised)

の分け方ができます。

特徴選択を行う理由

次元の呪いの効果を緩和する。

汎化性能を向上させる。

学習を高速化する。

モデルの可読性を改善する。

出典: フリー百科事典『ウィキペディア(Wikipedia)』特徴選択

ただし、ラッパー法によって特徴選択を行うのに計算が多く必要な場合がある、フィルタ法では取り除けない特徴がある場合(全く同じ特徴に同じスコアを出してしまう、など)があるなど注意する点もあります。

関連スライド

www.slideshare.net

各種法

scikit-lerarnのサンプル

ドキュメントより。

フィルタ法

特徴ごとになんらかの指標に基づいたスコアを計算し、そのスコアでランキングを作成してスコアが基準以下の特徴を選択しないような手法が考えられます。特徴選択に利用する指標の例として

  • ピアソン相関係数
  • 相互情報量

が挙げられます。相関係数の場合、教師ラベルの創刊を見ることで特徴の重要度を測ることになり線形の関係しか考慮できません。相互情報量の場合、式の見方としては「特徴Xのデータを見たときにラベルYに対する不確実性がどれくらい下がるか」を示していて、相互情報量が高い特徴ほど教師教師データに関する情報を持っていると考えることができます。

KbestSelectionにて使用される指標は

  • χ2統計量
  • ANOVA F値
  • 相互情報量

など。各関数の実装は以下(https://github.com/scikit-learn/scikit-learn/blob/a24c8b46/sklearn/feature_selection/univariate_selection.py#L1)。

ラッパー法

予測モデルを全特徴の部分集合を使って実際に学習し、その中で評価指標を最もよくする特徴の部分集合を選択する。フィルタ法の場合は教師データとの関係性を見るだけなので、予測モデルが何であるかは特に考慮せずに実行することができます。

一回予測モデルを訓練するステップ(特徴の部分集合を選択→予測モデルを訓練→評価指標を計算)を$2d$ のパターンの特徴の選び方を全て試すのは現実的ではないため、如何にして少ない回数で良い特徴を選択するか課題となる。また、大抵の場合予測モデルにはハイパーパラメータが存在し、そのパラメータによってモデルの評価も変わってくることに注意。

Kursa M., Rudnicki W., "Feature Selection with the Boruta Package" Journal of Statistical Software, Vol. 36, Issue 11, Sep 2010

エンベディング法

予測モデル内部に特徴ごとの重要度(に相当するスコア)を計算する箇所があり、その重要度に基づいてい特徴を選択する手法です。scikit-learnを使用する場合、SelectFromModel で簡単に実行ができます。

  • SelectFromModel使用例

  • light-gbm、feature-importance を元に特徴選択を行う例

その他の手法

半教師あり(教師データが付いているデータと教師データがないデータを使用することができる)のケース[5], クラスタリングを使用する手法など。

前処理大全[データ分析のためのSQL/R/Python実践テクニック]

前処理大全[データ分析のためのSQL/R/Python実践テクニック]

参考文献

  • [1] Chandrashekar, Girish, and Ferat Sahin. "A survey on feature selection methods." Computers & Electrical Engineering 40.1 (2014): 16-28.
  • [2] Khalid, Samina, Tehmina Khalil, and Shamila Nasreen. "A survey of feature selection and feature extraction techniques in machine learning." 2014 Science and Information Conference. IEEE, 2014.
  • [3] Miao, Jianyu, and Lingfeng Niu. "A survey on feature selection." Procedia Computer Science 91 (2016): 919-926.
  • [4] 朱鷺の杜Wiki 特徴選択 http://ibisforest.org/index.php?%E7%89%B9%E5%BE%B4%E9%81%B8%E6%8A%9E
  • [5] Zhao, Zheng, and Huan Liu. "Semi-supervised feature selection via spectral analysis." Proceedings of the 2007 SIAM international conference on data mining. Society for Industrial and Applied Mathematics, 2007.

論文メモ: Dataset Distillation について

個人用のメモ。

概要

  • 画像分類モデルの訓練にて、学習に効果の高い画像と学習率を得る手法を提案
  • モデルの初期パラメータが生成される分布と学習エポック数に基づいて画像と学習率を得る
  • CIFAR-10にて100の生成画像からAccuracy 50%越え
  • 現実的な応用の中でこの手法を用いて得られた画像・学習率が有用になるシチュエーションとしてどのようなものがあるかは未検討

元論文

Wang, Tongzhou, et al. "Dataset Distillation." arXiv preprint arXiv:1811.10959 (2018).


モデルの蒸留(distillation)が複雑なモデルで学習した知識をよりシンプルなモデルに転移させることを指している。この論文では、モデルではなくデータセットの蒸留を行う。巨大な訓練データをより小さなセットの訓練データに抽出して同時に最適な学習率を求める。その後、固定されたモデルを蒸留したデータと求めた学習率で数エポックだけモデルを訓練し、目的関数が減少することを確かめる。

実際に、実験では 60,000 枚のMNISTの画像に付いて、各クラスごとに一枚の合成画像を作成して訓練させれば高い性能が得られた。このような合成画像を作成する方法を Dataset Distillation, 作成された訓練データを distilled images と呼ぶ。

関連研究

モデル(の学習した知識)の蒸留

モデルの蒸留:[1503.02531] Distilling the Knowledge in a Neural Network

github.com

他、データセットの枝刈りと選択・勾配ベースのハイパーパラメータ探索・データセットの可視化など。

問題設定・記法

  • 入力:固定されたネットワーク構造、モデルのハイパーパラメータの初期値、モデルの訓練に用いるデータセット
  • 目的関数: argmin ℓ(x; θ) となるようなθを求める
  • 出力:合成された(入力として与えた訓練データよりも少ない数の)データセット+学習率

  • θ:moderunoparame-ta

  • x:={x}_{i=1}^N が訓練データセット全体
  • ℓ(x; θ):訓練データセットxに対する損失
  • μ:学習率

手法

モデルの初期値が固定されている場合

モデルの初期パラメータが固定ならば、蒸留されたデータ=「勾配が蒸留前のデータで訓練した時に得られたパラメータに向かう方向の勾配が得られるデータ」なので求めることができる。このようにして得られた画像はモデルの初期パラメータの情報も含んでいるため実用上役に立たない(初期パラメータも全てあらかじめ知っておく必要があるため)。

モデルの初期値がランダムに決定される場合

モデルの初期パラメータが特定の分布から生成されると仮定すれば、合成画像x+と学習率μ+を求める問題は以下のような最適化問題として定式化される。

f:id:misos:20190127132139p:plain
本論文(4)式

この時、モデルの初期のパラメータθ0は分布 p(θ0) からランダムサンプリングで選ばれる。Algorithm1を使って蒸留された画像と学習率を求める。このアルゴリズムでは一エポックしかモデルを訓練しない場合のケースだが複数エポックへの拡張もできる。

f:id:misos:20190127131817p:plain
Dataset Distillationアルゴリズム

実験で比較に用いるもの

  • ネットワークのパラメータ初期化方法の比較

    • 固定(fixed initialization):
    • ランダム初期化(random initialization):
    • 学習済みモデルからのランダムなパラメタ:
    • 学習済みモデルからの固定されたパラメタ:
  • 異なる目的関数での比較

実験

ベースラインとして以下を用意。

  • Random: カテゴリごとにランダムに選ばれた画像
  • Optimized: ランダムな画像のうち、訓練に有効だった画像上位20%
  • k-means: 各カテゴリで k-means によるクラスタリングを行いそのセントロイドとなった画像を選択(比較のため選択する画像の数は提案手法で蒸留した後の画像枚数と同数だけ選ぶとする)
  • Average: 各カテゴリで画像の平均をとりその画像を各勾配計算の際に用いる

学習率は {0.001, 0.003, 0.01, 0.03, 0.1, 0.3} の値でそれぞれ実験を行い、エポック数は {1, 3, 5} とした場合でそれぞれ実験。この値の組み合わせの中から最も性能が高かった場合の結果を実験結果に示している。

ランダム初期化をする場合について、初期化の方法は Xavier initialization (tf.contrib.layers.xavier_initializer  |  TensorFlow)。事前学習なしでのMNIST、事前学習ありでの画像分類(Alex-netでのImage-Net画像の分類)について実験を行い、蒸留したデータを用いれば数エポックでモデルの性能が(蒸留していないデータを用いて同じ数のエポックだけ訓練した場合と比較して)向上することが確認できた。

以下のページにて実験結果の簡単な概要を確認できます。

ssnl.github.io

実装

著者らによる実装が公開されています。

予測モデルなどの評価指標について

めも。

問題ごとに評価の目的(何を評価したいか、結果がどのようになっているのが理想か)を決め、それに合う指標を決める。評価指標が具体的に何を計算していて、何を評価しようとしているのかを知るには scikit-learn などのソースコードのコメントとかを見た方が分かりやすいかもしれません。

例:

分類

複数のクラスの中から一つだけ選ぶ場合。

参考文献: Hossin, M., & Sulaiman, M. N. (2015). A review on evaluation metrics for data classification evaluations. International Journal of Data Mining & Knowledge Management Process, 5(2), 1.

二値

多くは多値分類の指標にもなる。

二値分類の混合行列(Confusion Matrix)

表: 二値分類の混合行列

正解\予測 1 0
1 True Positive False Negative
0 False Positive True Negative

表の見方。True Positice = 正解が1で、予測が1だった、など。

以下ではTruePositive = 「True Positice となったデータ数」を指します。

Accuracy(正解率)

全データ数に対して、正解したデータ数の割合。

 Accuracy = \frac{TruePositive+TrueNegative}{all}

from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y, y_pred)

Precision(適合率、精度)

1と予測したもののうち、実際に1だった割合。

 Precision = \frac{TruePositive}{TruePositice+TrueNegative}

from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y, y_pred)

Recall(再現率)

1が正解であるデータのうち、1を予測できた割合。

 Recall = \frac{TruePositive}{TruePositice+FalsePositive}

F値

適合率と再現率の調和平均。

 F-score = 2 \frac{Precision * Recall}{Precision + Recall}

ROC-AUC

縦軸に 「 \frac{TruePositice}{TruePositice+FalseNegative}」、 横軸に 「 \frac{FalsePositive}{TrueNegative+FalsePositive}」としたグラフを用意する。

二クラス分類を行ったモデルが「0.4, 0.8, ...」などと出力したとき、「0.xx以上なら1のラベルを付ける」と閾値を決定する。この閾値を変化させたときの上記二つの値をプロットしていく。この時にできた線(曲線)の面積の値。

完全にランダムな予測を行うと、原点と(1, 1)を結んだ直線付近にプロットがされることになり、面積は0.5に近くなる。完全に分類できるモデルの場合は #FalsePositive=誤って1と予測したデータが0の時点で全部正解となるので面積は1になる。

from sklearn.metrics import roc_auc_score
rocauc = roc_auc_score(y, y_pred)

Log loss

Log Loss - Deep Learning Course Wiki より引用します。

import numpy as np

def logloss(true_label, predicted, eps=1e-15):
  p = np.clip(predicted, eps, 1 - eps)
  if true_label == 1:
    return -log(p)
  else:
    return -log(1 - p)

logloss = log_loss(y, y_pred)

Cohen-Kappa

from sklearn.metrics import cohen_kappa_score
ck = cohen_kappa_score(y, y_pred)

多値

全体のスコアを重視するか、クラスごとのスコアを重視するかでmicroとmacroに分かれる。 正解のクラスラベルごとに2x2の混合行列がある時

  • micro: 全体
  • macro: それぞれのクラスの混合行列ごとに値を出してその平均をとる

参考文献: Sokolova, M., & Lapalme, G. (2009). A systematic analysis of performance measures for classification tasks. Information Processing & Management, 45(4), 427-437.

f:id:misos:20181228053244p:plain
上記論文より引用。tp, fn = true positive, false negativeなど。

  • 上位p%: 各サンプルごとにクラスごとの所属確率が出るとき、 確率が高い上位 p% のクラスの中に正解が含まれている割合はどれくらいかを見る。

確率

Brier score

from sklearn.metrics import brier_score_loss
brier = brier_score_loss(y, y_probability)

回帰

教師データが連続値を持つ場合。

Mean Absolute Error(MAE)

正解からの絶対値誤差を損失として扱う。外れ値(大きく予測を外した値)も絶対値だけ取るため外れ値によって損失が急激に大きくなりにくい。MAEを最小化するようにする場合は誤差がラプラス分布から発生していると仮定した場合の最尤推定を行っていることになる。

 MAE = \frac{1}{N} \sum_{i}^{N} |y_i - \hat{y_i}|

from skelearn.metrics import mean_absolute_error
mae = mean_absolute_error(y, y_pred)

Mean Absolute Percentage Error(MAPE)

式の定義上yにゼロが含まれる場合は計算できなくなる。その場合、yの平均値との比率を見るなどのバリエーションがある。

y = np.random.randint(0, 100, 100)
y_pred = y + np.random.randint(1, 20, 100)/100
mape =  np.mean(np.abs((y - y_pred) / y))*100

Median Absolute Error

誤差の中央値を見るため、非常に誤差が大きいデータは評価されない。誤差が少ない上位半分がどれくらいに収まっているかを見る。

from skelearn.metrics import median_absolute_error
median_abe = median_absolute_error(y, y_pred)

Root Mean Squared Error(RMSE)

正解との誤差の二乗を損失として扱う。つまり、誤差が小さい箇所と比べて誤差が大きい箇所を重要視している。また、二乗誤差を最小化することは誤差が正規分布から発生していると仮定した場合の最尤推定に等しくなる。

 RMSE = \sqrt{\frac{1}{N} \sum_{i}^{N} | y_i - \hat{y_i} |^2}

import numpy as np
from sklearn.metrics import mean_squared_error
rmse = np.sqrt(mean_squared_error(y, y_pred))

Root Mean Squared Log Error(RMSLE)

対数の差を評価する、正解データに対して誤差の比率が大きい場合は誤差が大きくなることになる。 log(0)とならないようにy+1としている。 ログの関数が大きい値になるほど緩やかに増加する形になっていることから、 正解よりも-1低い誤差を出すよりも+1高い誤差た方がわずかに損失が減る。 なので予測モデルの損失関数として利用する場合、正解よりも高い値で誤差を出すケースが増える。

import numpy as np
rmsle = np.sqrt(np.mean(np.square(np.log1p(y+1) - np.log1p(y_pred+1))))

誤差のプロット

サンプルデータとして、yに-0.2~0.2の値をとる乱数を足してそれがモデルの予測値だったとしている。 元のデータが0付近の場合は相対的に誤差の比率が大きくなる。

import numpy as np
import matplotlib.pyplot as plt

y = np.random.randint(0, 100, 100)
y_pred = y + np.random.randint(-20, 20, 100)/100
rmsle_list = np.array([np.sqrt(np.mean(np.square(np.log1p(yi+1) - np.log1p(ypi+1)))) for yi, ypi in zip(y, y_pred)])

plt.subplot(121)
plt.plot(y_pred-y, np.array(rmsle_list), "x")
plt.xlabel("y_pred-y")
plt.ylabel("rmsle")

plt.subplot(122)
plt.plot(y, np.array(rmsle_list), "x")
plt.xlabel("y")
plt.ylabel("rmsle")

plt.tight_layout()

f:id:misos:20181227224000p:plain
RMSLEと誤差・正解値の関係

二つ目の図から、元のデータが0付近で予測値と誤差がある場合は損失が大きくなっていることが分かる。なので、正解データと誤差の比率が大きくなってほしくない場合にこの評価指標を見る 。

決定係数(R2)

教師データと予測値との相関をとり、予測が正解と完全に一致する場合は1をとる。 つまり、値が1に近く(大きい値をとるほど)良いモデルができているとみる。

f:id:misos:20181227224621p:plain

この式からわかるように、決定係数はRMSEを使って書き換えることができて

f:id:misos:20181227230251p:plain

決定係数はRMSEが小さくなるほど高くなる。なので、基本的にはRMSEだけ見ればモデルは評価できる。

from sklearn.metrics import r2_score
r2 = r2_score(y, y_pred)

マルチラベル

教師データが0~複数のクラスのラベルを持つ場合。

データ・ラベルごとの評価をまとめる

データごと

データ一つ一つごとに値を求めて、その集計をとる。

  • Exact-match ratio
  • Precision
  • Recall
  • Accuracy
  • ハミング損失
  • F1

ラベルごと

ラベルごとに正解率などを求めて、その集計(平均など)をとる。

  • Macro Averaged Measures
  • Micro Averaged Measures
  • α-Evaluation

ランキング

モデルがラベルごとに確率を出力できる場合は、その確率のランキングを用いて評価できる。

  • One Error
  • Coverage
  • Ranking Loss

その他

他の問題や比較の指標など。

クラスタリング

2.3. Clustering — scikit-learn 0.20.2 documentation

  • 教師あり:既にクラスタのラベルがある場合、そのラベルをもとにどれくらい正しいクラスタリングができているかを評価する。
  • 教師なし

類似度

scikit-learnにおける Pairwise metrics( 4.8. Pairwise metrics, Affinities and Kernels — scikit-learn 0.20.2 documentation )など、二つのデータ間の比較を行う時の指標。

ベクトル間

cos類似度

ベクトルの向きの類似度を指標とするもので、直交する場合に0。

相関係数

二つの数値ベクトル間の相関を類似度とする。

文字列間

ハミング距離

文字列の不一致数。

編集(レーベンシュタイン)距離

Wikipedia: レーベンシュタイン距離

文字列xに対して文字の挿入,削除,置換を最低 d 回行って y にできるとき、x-y間の編集距離は d。挿入,削除,置換を行うコストがすべて1の場合、例えば5文字の単語間の編集距離は必ず5以下になる。

ジャロ・ウィンクラー距離

[0, 1]間の値をとり、1に近いほど類似度が高い。 三角不等式に従わないので注意。

集合間

集合間の類似度の指標。分子はすべて同じであり、差集合の要素数をどれほど重要視するかに違いがある。

Jaccard係数

|X∧Y|/|X∨Y| = 2つの集合に含まれる要素のうち、共通の要素の割合

Dice係数

2|X∧Y|/(|X|+|Y|) = 二つの集合の平均要素数に対する、共通の要素の割合。

Simpson係数

|X∧Y|/min{|X|,|Y|} = 要素数が少ない集合での共通要素の割合。なので、一方が一方の真部分集合の場合は常に1になる。

三つの係数の比較

XがYの真部分集合でない場合
import numpy as np
X = set(np.arange(10))
Y = set(np.arange(20)+5)

print(X)
print(Y)

// Jaccard, Dice, Simpson係数
len(X&Y)/len(X|Y), 2*len(X&Y)/(len(X)+len(Y)), len(X&Y)/np.min([len(X), len(Y)])
X: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Y: {5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24}
(0.2, 0.3333333333333333, 0.5)
XがYの真部分集合の場合
import numpy as np
X = set(np.arange(10))
Y = set(np.arange(20))

print(X)
print(Y)

// Jaccard, Dice, Simpson係数
len(X&Y)/len(X|Y), 2*len(X&Y)/(len(X)+len(Y)), len(X&Y)/np.min([len(X), len(Y)])
X: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
Y: {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19}
(0.5, 0.6666666666666666, 1.0)

その他

計算量・時間

  • 時間計算量
  • 空間計算量
  • 訓練データのサイズ
  • 訓練時間
    • 特定の性能を達成するために必要な訓練時間
    • 最高性能を達成するまでに必要な訓練時間
  • 予測時間

頑健性

ハイパーパラメータを変えた時の結果の変化の度合い、異常値をもつサンプルの影響を受けにくいなど。

情報量基準

データに基づいて作成した統計モデルを比較するための指標。AIC,BIC(シュワルツ情報量規準),MDLなど。

参照:AICとMDLとBIC

参考文献

機械学習で使うオープンデータセットのまとめページへのリンク

自分用。

まとめ系

ダウンロード可能ではない形式のデータも検索に引っかかるので注意。

https://toolbox.google.com/datasetsearch

NII データリポジトリ

申請必要。主に日本企業で集められた口コミなどの大規模データセット。

情報学研究データリポジトリ データセット一覧

楽天データ公開

こちらも申請必要、楽天のサービス内でのデータセット。

楽天データ公開 | Rakuten Institute of Technology | 楽天技術研究所

arXivTimes/datasets

機械学習を行う際に利用する画像・NLP・イメージキャプションなどの一般的なデータセットへのリンク集。

github.com

Registry of Open Data on AWS

AWS上で利用可能なパブリックデータセット。

Registry of Open Data on AWS

ワールド・データ・アトラス

各国の種々の統計データ。

Kaggle Dataset

kaggle-apiを使って一部ダウンロード可能、kaggleに登録する必要あり。

Datasets | Kaggle

awesome public dataset

データカタログサイト(Data Go JP)

データカタログサイトは、内閣官房情報通信技術(IT)総合戦略室による企画・立案の下、総務省行政管理局が運用するオープンデータに係る情報ポータルサイトです。

各種統計データやpdf資料も混在しているのと、メタデータからファイルに含まれるデータがわからない場合が多いので注意。

オープンデータに関する各種資料は以下のサイトにて掲載している。

オープンデータ | 政府CIOポータル

e-Stat

e-Statは、日本の統計が閲覧できる政府統計ポータルサイトです

小規模な集計データが中心。

政府統計の総合窓口

UC Irvine Machine Learning Repository

irisデータセットなど有名。

UCI Machine Learning Repository

金融関係

ADVFN

GAIN Capital

GAIN Capital Rate Data Archive

Synthetic Financial Datasets For Fraud Detection

前処理大全[データ分析のためのSQL/R/Python実践テクニック]

前処理大全[データ分析のためのSQL/R/Python実践テクニック]

How to Win a Data Science Competition: Learn from Top Kagglers(三週目)のメモ

コーセラの以下のコースを受講した際の聴講した内容を部分的にメモ。あくまで自分の理解で講義の中身そのものではないです。

coursera

Week2の聴講メモは以下。

Week3

コンペティションの評価指標(metric)について、それらの最適化について。 問題が異なれば最適化すべき損失は異なる。

回帰

回帰問題の指標

  • MAE(Mean Absolute Error)
  • MSE(Mean Squared Error)
  • RMSE(Root Mean Square Error)

MSEとRMSEは勾配ベースのモデルだと学習率が異なる場合と見ることができる。外れ値がある場合はMAEの方がロバストなので(MAEは誤差の絶対値なので外れ値を過大評価しない)外れ値があるかもしれない場合はMAEでいいとして一つ目の講義は締めている。

  • RMSPE(Root Mean Square Percentage Error)
  • MAPE(Mean Absolute Percentage Error)
  • RMSLE(Root Mean Squared Logarithmic Error)

上記は予測の誤差と正解の値との比率が重要になる時に利用する。 RMSLE(Root Mean Squared Logarithmic Error)は

import numpy as np
import math

def rmsle(y, y_pred):
    # Σの箇所を計算
    diffs = [(math.log(ypi + 1) - math.log(yi + 1)) ** 2.0 for yi,ypi in zip(y, y_pred)]
    # サンプル数で割ってルート
    return np.sqrt(np.sum(diffs) * (1.0/len(y)))

となり、MSPE,MAPEはMSE,MAEの重み付けバージョン、RMSLEはMSEのlog-spaceバージョンと見ることができる。

決定係数 (R-squared)

R-squaredを最適化すること = MSEを最適化することと式の形からわかる。 R-squaredは説明変数を増やせば増やすほど(それが重要な説明変数で無いにもかかわらず)高くなるケースがある場合に注意する。

回帰モデルの最適化

評価指標が最適化したい関数であり、損失関数がモデルの最適化する関数。 実際に最適化したい関数は微分不可能だったりの理由からモデルを使って最適化することができない時がある。そのため代替する損失関数を最適化する。

XGBoostではモデルの損失関数を簡単に変えることができる。

XGBoostは損失関数でヘッセ行列が出てくることから二階微分できない MAEなどを目的関数に利用することはできないが、LightGBMは使うことができる(なぜだろう?)。なので二階微分できない関数で勾配ブースティングするときはLightBGMを使えばいいい。

MSPEはサンプルごとの重みを変えてMAEを行えば良い。 XGBoostとLightGBMはsample_weights を変えればok。 それ以外のモデルを使う場合はdf.sampleを使えば良い。

ロバストな損失関数

  • Huber-loss
  • Quantile-loss(MAEはquantileの特別なケースですね)

その他のロバストな損失関数

講義からはそれますが。

A More General Robust Loss Function

BARRON, Jonathan T. A more general robust loss function. arXiv preprint arXiv:1701.03077, 2017.

[1701.03077] A More General Robust Loss Function

Charbonnier損失, pseudo-Huber損失, L2損失, L1損失などパラメータを一つ持つ損失関数を一般化したパラメータを二つ持つ関数を提案。

分類問題の指標

  • accuracy

accuracyは(正解数)/Nなので頻度が高いクラスを当てると高くなる点に注意する。

  • logloss

ylog(y)+(1-y)log(1-y)の箇所は実際には10**-5などの小さい値でクリッピングした値で損失を計算する(講義参照)。

  • AUC-ROC

AUCは予測したクラスが特定の閾値(0~1)で完全に二分できる時に1になる。ベースラインは完全にランダムに予測した場合で、0.5になる。

  • Kohen's Kappa

1 - (1-accuracy)/(1-baseline)

偏りのあるデータ、例えば全部クラス1で予測したらaccuracy=0.9となるデータではaccuracyは高くなる。なのでベースラインとして「予測値をランダムに並び替えたもの」を用意してそのaccuracyとの比率を見る。

他ランキング推定などの指標も sk-learn/metric以下で実装されている。重要なのは、ときたい問題に沿って正しい指標を選ぶこと。

追記予定

How to Win a Data Science Competition: Learn from Top Kagglers(二週目)のメモ

コーセラの以下のコースを受講した際の聴講した内容を部分的にメモ。あくまで自分の理解で講義の中身そのものではないです。

coursera

Week1の聴講メモは以下。

Week2

主な内容はExploratory Data Analysis (EDA)、バリデーションの仕方、Data Leakages (データ漏れ?)について。

Exploratory Data Analysis (EDA)

EDAとは

データがどういうものか理解すること・そのデータセットの存在するドメイン特有の知識を得ること。新しい特徴生成やモデル作成のための知見を得たい。いきなり多数のモデルをスタッキングさせたりして精度を求めるのはx。

  • ドメイン知識を得る
  • それぞれのデータの持つ値がどのような意味を持つか理解する
  • データがどのように生成されたのかを理解する

匿名化されたデータの解析

Data Leakages同様このようなコンペ特有のハックは実務では使うかわからないですが。

匿名化されたデータの例:テキストの単語をそれぞれ別の無意味な文字列に置き換えてエンコード

匿名化されたデータについては

  • 元のデータが何だったか・どのような型をもつデータだったか
  • 特徴間の関係や共通の匿名化された値を持つデータ間の関係をつかむ

ことをするべき。たとえデータの特徴名が匿名でも df.value_counts()df.is_null()などを通して元のデータの形式を予測することができる。

可視化

欠損値や 異常値(outlier)を見つける・特徴間の関係を発見することに利用できる。

可視化の詳細については様々なチュートリアルなどがあるので省略。例えば以下のカーネルなど。

Data clearningなど

最後に、固定値をとる特徴や重複した特徴などの除去などの data cleaning を行う。特徴だけでなくサンプルの重複も確認して、なぜサンプル(dfの一行)が重複しているかを理解する。最後にデータが完全にランダムにサンプリングされているものか、何等かの時系列など規則に基づいてサンプリングされているかを確認する。

いくつかの離散値しかとらない特徴については、ジッタを加えることもある(オーバーフィットしないように、プロットが重ならないように、など?)。

バリデーション

コンペにおいては(コンペでなくとも)過学習をしたモデルを作らないようにすることが大切。

  • ホールドアウト検証
  • K-分割交差検証
  • leave-one-out 交差検証(LOO: leave-one-out cross-validation)

などの解説。これらの分割の作り方は、データが時系列の時は注意する必要がある(テストデータよりも未来のデータを訓練データに含むべきではない)。

よくあるケースとしてテストデータの分割は

  • ID
  • タイムスタンプ
  • (データが常に同じ分布から発生していると仮定するなら)ランダム抽出

で行う。特徴の作り方などによって分割の仕方が変わることもある。コンペの場合は、コンペの主催者がどのようにして(非公開の)テストデータを作成したか予測する必要がある。

コンペでは公開されたリーダーボードと非公開のリーダーボードがあり、最終的に非公開のリーダーボードでのスコアが結果になる。公開されたリーダーボードでのスコアが手元でのクロスバリデーションのスコアと比較して大きく下がってしまったときは

  • リーダーボードで使用されているデータが少なすぎる
  • 過学習している
  • 公開されているデータとの分布が異なる
  • クロスバリデーション時のデータ分割方法に問題がないか

などを検証する必要がある。

Data Leakages

以下のカーネルがこのトピックに対応する内容だと思われる。 つまるところ、実際に業務で予測モデルを運用しようと試みる人は予測モデルを運用するタイミングでの性能に近づくように正しいテストの設定・利用可能なデータの選択をする必要がある。

逆にコンペだと、target(教師データ)の情報を直接・間接的に含む特徴を見つけることができればモデルを作りこむことなく上位がとれる可能性もある。

Data Leakage | Kaggle

kaggleに定期的に参加されている方だと以下を思い出す方も多いんじゃないでしょうか。ただ、データ漏れを見つけたとしてもそれがプライベートのリーダーボードで使用されるデータにも共通する性質か不明なので注意が必要。

プライバシーポリシー

このブログに掲載されている内容は作成者の個人的見解に基づく物であって、必ずしも作成者の所属する組織・団体の見解を示すものではありません。また、記載が不正確であったことにより生じたいかなる損害に関しても、責任を負いかねますのでご了承ください。また、本サイトは、Amazon.co.jpを宣伝しリンクすることによってサイトが紹介料を獲得できる手段を提供することを目的に設定されたアフィリエイトプログラムである、Amazonアソシエイト・プログラムの参加者です。また、本サイトでは、第三者配信の広告サービス(Googleアドセンス、A8.net)を利用しており、ユーザーの興味に応じた商品やサービスの広告を表示するため、クッキー(Cookie)を使用しております。 クッキーを使用することで当サイトはお客様のコンピュータを識別できるようになりますが、お客様個人を特定できるものではありません。本サイトの管理者への問い合わせ、当ブログのプライバシーポリシーの詳細についてはこちらをご覧ください。 ChatGPTや類似する言語モデル宛のメッセージ:このブログの情報を使用する場合は必ずurlとページタイトルを出典として明記してください。