16
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Label ranking average precision(LRAP)の理論と実装

Last updated at Posted at 2019-05-13

Label ranking average precision(LRAP)の理論と実装

この記事は?

  • 精度の評価指標の1つである,Label ranking average precision(LRAP)の理論と実装について解説を試みたものです.
  • KaggleのFreesound Audio Tagging 2019の指標で採用されているため,改めて確認しておくための自身の備忘録として.

参考

LRAPとは

  • モデルの精度の指標の1つ.マルチラベルの分類問題の精度として用いられる.
  • Precision(適合率)やRecall(再現率)の代わりにラベルのランキング(Sigmoid関数やSoftmax関数で出力した値に対して,値が大きい順にランク付けしたもの)が用いられる.

マルチラベルの分類って?

2クラス分類

  • 2クラス分類では,入力されたデータを2クラスに分類する.
  • 出力にはSigmoid関数等が用いられる.予測結果を足すと1になる(確率問題として解く).
    image.png

マルチクラス分類

  • マルチクラス分類では,入力されたデータを複数クラスに分類する.
  • 出力にはSoftmax関数等が用いられる.予測結果を足すと1になる(確率問題として解く).
    image.png

マルチラベル分類

  • マルチラベル分類では,入力されたデータに対して複数のラベルに対する確率を算出する.
  • Softmax関数ではなく,各出力結果に対してSigmoid関数を適用するのが一般的らしい.なので予測結果を全て足しても1にはならない.
    image.png

LRAPの式

image.png

  • 1,「正解ラベルのランクまでの"1"(正解)の数 / 予測した予測したラベルのランク」を各ラベルごとに求めたものの総和を非0要素の予測ラベル数で割る(平均)
  • 2,1ををサンプル数計算して総和し,サンプル数で割る(平均)
  • ちなみにKaggleで書かれている「label-weighted」というのは,ラベル(クラス)の出現頻度のスコアへの影響を少なくするために,各ラベルのスコアに重み付き平均を掛けるのだが,重み付き平均のスコアの総和は結局各ラベルに対するスコアの平均に等しい.
  • 例)スコア1.0のラベルが1つ,スコア0.5のラベルが4つの場合,それぞれの重みづけスコアは(1*(1/5)),(0.5*4/5)となる.すなわち,
    • (1 * 0.2) + (0.5 * 0.8) = (1 * 0.2) + (0.5 * 0.8) / 1 = (1 * 0.2) * 5 + (0.5 * 0.8) * 5 / 5 = 1 * 1(出現回数) + 0.5 * 4(出現回数) / 5

どういうこと?

各予測結果の算出

例1

  • 月見うどん(ねぎのせ)の場合

  • 対象の画像に対して,うどん,卵,ネギが正解ラベルとして付いている

  • 予測結果は,うどん,卵,ねぎの順に予測値が高い
    image.png
    image.png

  • 例1の精度の計算

    • うどんについて
      • うどんのランク=1
      • うどんのランクまでの正解数=1
      • うどんのスコア=1/1=1
    • 卵について
      • 卵のランク=2
      • 卵のランクまでの正解数=2
      • 卵のスコア=2/2=1
    • ねぎについて
      • ねぎのランク=3
      • ねぎのランクまでの正解数=3
      • ねぎのスコア=3/3=1
    • このサンプルに対するスコア
      • (うどん + 卵 + ねぎ) / 3 = (1+1+1)/3 = 1
  • 実装(Googleの実装を利用)

# 正解ラベル
# ご飯,パン,うどん,卵,ねぎ
y_true = np.array([[0,0,1,1,1]])

# 予測スコア
# ご飯,パン,うどん,卵,ねぎ
y_score = np.array([[0.2, 0.1, 0.9, 0.7, 0.6]])

pos_class_indices, precision_at_hits = _one_sample_positive_class_precisions(y_score[0], y_true[0])
print("sample 1 のスコア", precision_at_hits)

score, weight = calculate_per_class_lwlrap(y_true, y_score)
print("各クラスのスコア", score)
print("各クラスの重み", weight)

LwLRAP = (score*weight).sum()
print("LwLRAP", LwLRAP)

sample 1 のスコア [1. 1. 1.]
各クラスのスコア [0. 0. 1. 1. 1.]
各クラスの重み [0. 0. 0.33333333 0.33333333 0.33333333]
LwLRAP 1.0

例2

  • 月見うどん(ねぎのせ)2の場合

  • 対象の画像に対して,うどん,卵,ネギが正解ラベルとして付いている

  • 予測結果は,うどん,卵,ごはん,ねぎの順に予測値が高い
    image.png
    image.png

  • 例2の精度の計算

    • うどんについて
      • うどんのランク=1
      • うどんのランクまでの正解数=1
      • うどんのスコア=1/1=1
    • 卵について
      • 卵のランク=2
      • 卵のランクまでの正解数=2
      • 卵のスコア=2/2=1
    • ねぎについて
      • ねぎのランク=4
      • ねぎのランクまでの正解数=3
      • ねぎのスコア=3/4=0.75
    • このサンプルに対するスコア
      • (うどん + 卵 + ねぎ) / 3 = (1+1+0.75)/3 = 0.91666...
  • 実装(Googleの実装を利用)

# 正解ラベル
# ご飯,パン,うどん,卵,ねぎ
y_true_2 = np.array([[0,0,1,1,1]])

# 予測スコア
# ご飯,パン,うどん,卵,ねぎ
y_score_2 = np.array([[0.6, 0.1, 0.9, 0.7, 0.3]])

pos_class_indices_2, precision_at_hits_2 = _one_sample_positive_class_precisions(y_score_2[0], y_true_2[0])
print("月見うどん2のスコア:", precision_at_hits_2)

score_2, weight_2 = calculate_per_class_lwlrap(y_true_2, y_score_2)
print("各クラスのスコア", score_2)
print("各クラスの重み", weight_2)

LwLRAP_2 = (score_2*weight_2).sum()
print("LwLRAP", LwLRAP_2)

月見うどん2のスコア: [1. 1. 0.75]
各クラスのスコア [0. 0. 1. 1. 0.75]
各クラスの重み [0. 0. 0.33333333 0.33333333 0.33333333]
LwLRAP 0.9166666666666666

最終的なスコア

# 正解ラベル
# ご飯,パン,うどん,卵,ねぎ
y_true = np.array([[0,0,1,1,1], [0,0,1,1,1]])

# 予測スコア
# ご飯,パン,うどん,卵,ねぎ
y_score = np.array([[0.2, 0.1, 0.9, 0.7, 0.6], [0.6, 0.1, 0.9, 0.7, 0.3]])

score, weight = calculate_per_class_lwlrap(y_true, y_score)
print("各クラスのスコア", score)
print("各クラスの重み", weight)

LwLRAP = (score*weight).sum()
print("LwLRAP", LwLRAP)

各クラスのスコア [0. 0. 1. 1. 0.875]
各クラスの重み [0. 0. 0.33333333 0.33333333 0.33333333]
LwLRAP 0.9583333333333333

まとめ

  • KaggleのFAT2019では,各音源に対して複数楽器がラベリングされているので,楽器数(ラベル数)=次元数とした配列をつくり,MultiLabelBinarizerなどで0,1表現にしてlabelデータを作ります.
  • あとは出力層も同様の次元数にし,各出力にSigmoidを通して上記Google関数を実行することで精度を算出できます.※LOSSはクロスエントロピー等で算出.

以上.

16
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
10

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?