ホーム » 音声解析

音声解析」カテゴリーアーカイブ

Feature Importanceを知る

こんにちは。kzです。

世の中ではやはり解釈性が重要らしいです。

前回、SHAP含めてモデル解釈の指標についていくつか触れました。やはり一度では僕は残念ながら理解できないので復習も含めて今回この記事を書きます。

前回の復習

上記のリンク先が前回の記事になります。

  • Permutation Importance
  • Partial Dependence
  • LIME
  • SHAP
雑におさらいするとPIは対象の変数をシャッフルして精度の変化からその変数の影響力を見る手法。PDは対象の変数以外を周辺化で消すことによってその変数のみの影響力を見る手法。LIMEは対象の入力データ周辺でブラックボックスモデルを線形近似しその重みでそれぞれの変数の寄与具合を見る手法。SHAPはLIMEのモデルに複数の制約(Consistencyなど)を与えてできた特殊な距離を使った手法(LIMEの上位互換)

ちなみに他にもDrop-Column Importanceとかもあるらしいです。

Feature Importance

順番的には逆になってしまいましたが、決定木自体にはFeature Importanceというものがあります。ご存知ですよね。どうやって算出されてるのや?と思ったので調べました。結論から言えばあまりにも式が複雑で完全に理解し切るのはかなりハードです。。

なのでその計算の核となるGini Impurityから始めます。

Gini不純度

あるノードにおけるGini不純度は上のように定義されます。記号については以下の通り

  • Cはクラスの総数
  • p_iはクラスiの割合
分類においては各ノードではできるだけ少数のクラスであって欲しいですよね。具体的に計算してみます。
         二郎系   家系     まぜそば 
count = 4 4 4
p = 4/12 4/12 4/12
= 1/3 1/3 1/3
GI = 1 - [ (1/3)^2 + (1/3)^2 + (1/3)^2 ]
= 1 - [ 1/9 + 1/9 + 1/9 ]
= 1 - 1/3
= 2/3
= 0.667
各クラスから均等な量の場合とあるクラスに偏りがある場合
         二郎系   家系     まぜそば 
count = 3 3 6
p = 3/12 3/12 6/12
= 1/4 1/4 1/2
GI = 1 - [ (1/4)^2 + (1/4)^2 + (1/2)^2 ]
= 1 - [ 1/16 + 1/16 + 1/4 ]
= 1 - 6/16
= 10/16
= 0.625
少し小さくなりました。ではあるノードにおいて単一のクラスのみある場合はどうでしょうか。
         二郎系   家系     まぜそば 
count = 0 12 0
p = 0/12 12/12 0/12
= 0 1 0
GI = 1 - [ 0^2 + 1^2 + 0^2 ]
= 1 - [ 0 + 1 + 0 ]
= 1 - 1
= 0.00
0となりました。きれいに分類できている証拠ですね。決定木のFeature ImportanceはこのGiniを用いて算出されているようです。 参考文献によると
とありました。難しいですが、要は最後の式だけ見ればなんとなくわかります。分母は前ノードにおけるImpurity Reductionの総和であり、分子は対象の特徴量jによる分岐ノードでのImpurity Reductionの総和となっています。

つまり、対象の特徴量が木全体においてどれだけGini不純度の減少に寄与できたかという指標でFeature Importanceが算出されているということです。

ということはです。分岐点を多く作りやすい変数の方が相対的にFeature Importanceが大きくなるのは直感的ですよね。単純に考えるとカテゴリカル変数よりも連続値変数の方がFeature Importanceが相対的に高まってしまうということです。さらに木を深めることで多くの分岐点が生成されるのであればその効果は莫大です。

実際Feature ImportanceにはCardinalityが密接に関係します。次にCardinalityについてみてみます。

Cardinality

みんな大好きKaggleにおいて次のような質問があった。
タイタニックデータをxgboostでバイナリ分類したのちfeature importanceをみた結果、特徴量の1つであるSexは目的変数と高い相関があるにもかかわらず、比較的低いimportaceが得られたらしい。 これに対して気になるコメントがあった。
なにを言っているのかというと。カーディナリティによってfeature importanceにバイアスが生じる。high-cardinalityはhigh-importanceを持つ。これが原因でSexが相対的にlow-importaceになっている。

ここでカーディナリティとは、対象の変数の多様性のこと。つまり性別のようなカテゴリカル変数よりは連続値の変数の方がカーディナリティは相対的に高い。

これはまさに上記のGiniの定義より得られた考えのことだ。よってさきほどのFeature Importanceに対する理解は正しかったということだ。

Information Gain

実は決定木における重要な指標はGini Impurityだけではなく、Information Gain(平均情報量)というものが別であります。
じゃあ、どっちを決定木では使うの?どっちのほうがいいの?という問に対する答えはGini Impurityです。理由は簡単で計算が楽だからです。後者を選んでしまうと対数の計算が必要になります。詳しくは次のリンクへどうぞ

LIME

じゃあ、どうしたらちゃんとした、まともな、直感的なFeature Importanceが得られるのか。という問に対する答えは僕の知るベストだとSHAPだ。もうSHAPしかない。

上述した理由から決定木におけるFeature Importanceに信憑性はない、結果的に重回帰がやはり好かれている。しかし、分類という点においては決定木やNNには重回帰では残念ながら勝てない。

最高に分類できる状態を保ちつつ、重回帰のように最高の形でFeature Importanceがほしい、という欲求を満たしてくれるのがSHAPだ。LIMEの上位互換なのでやってることはほぼ同じ。

記事の最後になりましたがここでは低次元空間においてLIMEの振る舞いを簡単に実装してSHAP(LIMEの上位互換)のイメージを理解します。下のような非線形データを考えます。
可視化に力をいれたいのでgridでデータを再度作成し、とあるインプット(青)を考えます。このインプットしたいするlimeを求めます。
LIMEもSHAPもローカルなので局所的な空間を考えます。多様体の言葉でいうとチャート、または局所座標近傍です。
距離関数としてL2距離を算出します。実際にロス関数を定義して重みを最適化するのではなく、この距離を線形回帰のライブラリのweightというパラメータに用いて外れ値を考慮した線形モデルを構築します。
前述通り今回はロス関数を定義して計算しているわけではないので厳密なLIMEの実装ではないので注意。あとは線形回帰モデルを作って重みを取得するだけです。
両軸を特徴量として扱っているので線形モデルの直線は可視化できませんが上のマークより、その振る舞いは理解できたのでわないかと思います。ピンクの部分はプラスでグレーの部分はマイナスと分類されています。その時の切片、係数も取得できます。これがlimeです。 厳密ではないですがLIMEのやっていることは理解できたかな?と思います。

ちなみにSHAPの凄いところは制約3つめのConsistencyです。これによって対象の特徴量のFIがより重み付されます。これによって決定木におけるFIの相対的なつぶれよりも直感的なFIを得ることができます。
SHAPの距離のところがよくわからない。でわ

Reference

ハイパラ最適化に困ってるんやろ?Optunaやで

こんにちは。kzです。

久しぶりに欲しいものができたんですよね。無印の「軽量オーストラリアダウンポケッタブルマフラー」なんですけどオンラインでも全部在庫がないみたいで入荷を心待ちにしています。

そんなことはおいておいて、本日はハイパーパラメータ最適化についてです。

ハイパーパラメータとは

ハイパーパラメータの前にパラメータがありますよね、違いはなんでしょう?LassoとRidgeを例に取りましょう。

上の記事で解説したのでそちらもみていただきたいのですが、モデルを定義する際に学習させる変数がありますよね。よく\thetaで表されるやつです。例えばRidgeの場合だと
となり、Lassoの場合だと
となりました。このように学習(よくfitやtrainと言われる)において学習される変数をパラメータといいます。ではハイパーパラメータとはなんでしょう?これは我々が手動で設定する必要があるパラメータのことです。例えば次のLassoの目的関数を見てみましょう。
先ほど通り、\thetaがパラメータです。一方で、\lambdaがありますよね。これは我々が決めるパラメータなのでハイパーパラメータになります。

これでパラメータとハイパーパラメータの違いが理解できたと思います。真相学習や機械学習の問題の一つはこのハイパーパラメータの最適化です。例えばニューラルネットワークにおいて活性化関数に何を使うかや決定木において深さをどうするかめっちゃ悩みますよね?それを最適化したいんです。

Grid Search

よくある手法の一つがグリッドサーチです。これは格子状にハイパーパラメータの候補を作り、総当たりしてその結果を見てハイパーパラメータを選ぶという手法です。sklearnにあるのでみてみましょう。
いいんです、これでもいいんですけど「探索の最適化」したいですよね?紹介しましょう。オプチュナを。

Optuna

あの最強のPreferred Networks, Inc.さんが開発しました。
Optuna はハイパーパラメータの最適化を自動化するためのソフトウェアフレームワークです。ハイパーパラメータの値に関する試行錯誤を自動的に行いながら、優れた性能を発揮するハイパーパラメータの値を自動的に発見します。現在は Python で利用できます。
Optuna は次の試行で試すべきハイパーパラメータの値を決めるために、完了している試行の履歴を用いています。そこまでで完了している試行の履歴に基づき、有望そうな領域を推定し、その領域の値を実際に試すということを繰り返します。そして、新たに得られた結果に基づき、更に有望そうな領域を推定します。具体的には、Tree-structured Parzen Estimator というベイズ最適化アルゴリズムの一種を用いています。

これがすごいんです。論文にもなったようです。

使い方

テンプレは上の感じです。超シンプルなんですよね。ちなみに最後にgistsを貼りますが、出力も多く、plotもplotlyを用いているのでnotebookでは表示されませんので注意です。
例えばSVCのパラメータ探索をしたいときのコードは上の感じ。
時にはLightGBMとXGboostのように異なるアルゴリズムで比較したいときもありますよね。できるんです。
で、このOptunaの最大の魅力だと個人的に思っているのがPlotでして、plot自体が魅力的ではなくて、plotからOptunaが使っているアルゴリズムがすごいということがわかるんです。
これをみていただくとわかるかもしれませんが、ベイズ最適化を使っているんですよね。デフォルトだとTPEと呼ばれるアルゴリズムを使用されているようです。僕もベイズ最適化あたりは勉強しないといけないので良さそうなリンクを上げておきます。

で、まだ特徴があってデータベースに学習記録が保存できるらしいです。使い道はよくわかりませんが、、コメントください、

Code

Optunaはすごいですね、これからさらに追加される機能も気になりますし、gitからベイズ最適化のアルゴリズムの勉強もさせてもらえそうです。勉強頑張りましょう。でわ

References

音声解析 入門

こんにちは。

前回、音声解析の準備その1的な感じでとりあえずスペクトログラムの可視化までをライブラリlibrosaで進めました。フーリエ変換など一部の解説は行ったのですが、今回はメルなどその他の知識の解説をしつつ、別の音声データを用いてPythonをいじってみました。

簡易的なまとめ

  • メルとホンは重要。
絶対的な音圧ではなく、体感的な音圧をホンという。同様に体感的な音の高さをメルという。
  • スペクトログラムよりメルスペクトログラムを使う。
上記の通り、人間の聴覚を考慮して作られるから。
  • 窓関数は周期性を生成する
フーリエ変換の仮定として入力の音声信号に周期性があります。しかし、一般的に周期性のあるデータはおそらくない?ので周期性を持たせる必要があります。そこで、窓関数を使います。ハミングや、ハニングなどが有名です。
  • 等ラウドネス曲線
音圧と周波数の関係、比例ではないということが重要。
  • ケプストラムも大切
スペクトル微細構造とスペクトル包絡構造に対応する各成分を容易に見分けることができる。すなはち、音源特性、声道特性それぞれについて分析が可能。

コード

例えば応用になると、メルスペクトログラムを使って音楽分類や声からの性別分類などするんですかね。個人的にはリアルタイムで音声を変換とかやってみたいですね。
これらについても実装が非常に難しい、、、特にメル以降はちょっとまだできない、、、申し訳ない。

音声解析のための準備をPythonでやる

こんにちは。 この記事はメモみたいになってます。次の記事へ移るようおねがいします。 本日は音声解析の準備段階としてスペクトログラムの可視化まで行いたいと思います。音声解析のライブラリは色々あるようですがlibrosaがおそらく一番だそうです。今回、スペクトログラムまで進めるにあたって専門用語がかなり多く、それぞれ非常に難しいものでした。特にメルあたりを理解するには少し時間がかかりそうです。。まぁ、始めましょう。
上の図を見てほしいんですが、音声解析で扱うデータは音です。しかし、この音が単純ではなかったわけです、何かと言うと、音源特性と声道特性という2つの要素から音が構成させているのです。ちなみにこことても重要だと思います。(後々のメルに絡んでいる模様)そしてこの音のデータを用いて音声解析のイメージ図は次のようになります。
キーワードとしては
  • デシベル・ピッチ・メル
  • フーリエ変換(FFT)
  • スペクトル
  • スペクトログラム
  • メルスペクトログラム
  • ケプストラム
  • メル尺度
  • メルケプストラム
  • メル周波数ケプストラム係数(MFCC)
  • ヴェーバー‐フェヒナーの法則
  • 等ラウドネス曲線
見ての通り非常にやることが多いです、、ひとまず詳しいことは今回は置いておいてスペクトログラムをPythonで表示してみます。

フーリエ変換

厳密な定義はひとまず無視して、信号f(t)に対するフーリエ変換は
となります。フーリエ変換によって、複合音を構成する各純音(スペクトラム)の周波数、振幅(パワー)の値を調べます。スペクトルF(omega)は、周波数成分と振幅成分を抽出したものです。

F(omega)は複素数で、その絶対値|F(omega)|と偏角arg F(omega)はそれぞれ、周波数omegaの正弦波の大きさと 位相を表し、それぞれ、振幅スペクトル、位相スペクトルと呼ばれます。
  • 振幅スペクトル
    • 絶対値|F(omega)|は周波数omegaの正弦波の大きさを表す
  • 位相スペクトル
    • 偏角arg F(omega)は周波数omegaの正弦波の位相を表す
また、|F(omega)|^2はパワースペクトル または エネルギースペクトル などと呼ばれます。

一般には周波数成分の「大きさ」が重要なので、F(omega)を図で表す場合、特にことわらなければ 横軸に(角)周波数、縦軸に周波数成分の大きさ を描きます。

大きさは dB で表すことがもっとも一般的です。
  • 振幅スペクトルを用いる場合、

        \[20 log _{10}(|F(omega)|)\]

  • パワースペクトルを用いる場合、

        \[20 log _{10}(|F(omega)|^2 )\]

みての通り、dB自体は変わりません。

また、omegaが負の部分を描くこともありますが、+omega-omegaは同じ周波数を表し、 |F(omega)|の値は同じ。 よって、|F(omega)|omega=0を中心に左右対称となります。

スペクトログラム

スペクトログラムとは音声を短時間ごとに区切り、各フレームのスペクトラムを時間軸に沿って並べたものです。

サンプリングレート

1秒間の音の信号をいくつに分割するかを表す数値です。音楽用CDでのサンプリング周波数である44.1kHzは、1秒間の音の信号を4万4100に分割して4万4100のデータに変換します。