[Python]音声解析でトランペットの録音データを可視化してみる

はじめに

私はデータ分析以外の趣味としては、トランペットの演奏があります。個人でプイプイ吹いているだけのしょうもない趣味ですけどね。
先日、楽器屋に新しいマウスピース(楽器を口に当てる金属部分、振動させる部分)を買いに行ったのですが、吹いているうちによくわからなくなったので、録音した音声波形などを可視化することで、いいなと思う音がどんな波形をしているのかを明らかにしたいと思います。

進め方

  • 録音データを用意(iPhoneのムービー)
  • FFmpegで動画から音声のみを切り出し、サンプルレートを変え、モノラルにする
  • Pythonで基本周波数(F0)などを可視化

データの準備

今回はチューニングB♭(ベー)の音3種類(Yamaha 11C4、Bach 5C、Bach 3C)と、練習曲(ルパン三世のフレーズ)の音2種類(Yamaha 11C4、Bach 5C)の計5つの音源を扱います。

マウスピースのイメージ

  • Yamaha 11C4:オールマイティー(これまで使っていたやつ)
  • Bach 5C:少し深くて、少し内径が小さい
  • Bach 3C:少し深くて、少し内径が小さい(5Cと3Cの違いは当て心地?)

指標の説明

  • 音声波形:波動の振動の大きさを表す非負のスカラー量を縦軸に、横軸を時間とした場合のグラフを音声波形と呼ぶ。
  • ピッチマーク:単位波形を抽出する基準点でエポックマーカーと呼ばれる。音が鳴った際に1をとり音がない際は0を取る。
  • 基本周波数:信号を正弦波の合成で表したときの最も低い周波数成分の周波数で、音程に該当する。
  • 相関係数:ピッチマークの検出に使う指標でNCCF(Normalized Cross-Correlation Function)というものを使って計算している。自己相関のようなもので-1から1の間を取る。

音声ファイルのあるディレクトリで以下のコマンドを実行します。(私の環境はMacです。)

音声波形などの可視化〜チューニングB♭(ベー)〜

ここでは単純にチューニングベーの音を比較します。まず音源ですが、以下で実際に聴けるようになっています。(耳を痛めないように、最も小さい音で聴いてから調整してください。)
しかし、慣れないマウスピースで音程が不安定になっているのが悲しいですね。

・Yamaha 11C4のチューニングベー

・Bach 5Cのチューニングベー

・Bach 3Cのチューニングベー

以前書いたブログと同様に、pyreaperというREAPERのラッパーとなっているライブラリを用います。REAPERはGoogleが開発していて、C++で書かれています。

音声波形の比較


やはり慣れている分、11c4が安定してそうな波形に見えますね。3Cは結構ブレてそうです。実際の音源でもわかりますね。

ピッチの比較


発音のあったところで1となる指標です。今回は伸ばしているだけなので、何の面白味もないです。

基本周波数(F0)の比較


音程をつかさどるF0に関しては3Cが安定してそうです。聴いたらブレブレなのに。

相関係数の比較


いつも使っている11c4がブレにくいようで、5Cが比較的に上下動が多いように見えます。

音声波形などの可視化〜練習曲〜

結局、マウスピースは5Cを購入して、その後スタジオで練習曲の音を比較しました。先ほどと同様に音源が以下で実際に聴けるようになっています。(耳を痛めないように、最も小さい音で聴いてから調整してください。)私は、実際に録音して、マウスピースでこんなに変わるんだと驚きを隠せないです。チューニングベーを比較するだけではわかりにくいんですかね。私としては、5Cの音の方が好きです。

・Yamaha 11C4での練習曲

・Bach 5Cでの練習曲

音声波形の比較


5Cのほうが上下の大きさが対称に近いような印象を受けます。いい音を捉える参考になるんですかね?

ピッチの比較


おそらく、11c4の音源の息継ぎのタイミングがやや長くなった結果、ピッチに差が出たのではないかと思います。

基本周波数(F0)の比較


比較が難しいですが、最後の伸ばしは5Cのほうが安定しているようです。

相関係数の比較


5Cのほうが上下動をしているように見えます。いいなと思う音の方が上下動しやすいのでしょうか。気になるところ。

追記:スペクトログラムの比較

どうやら音色を考えるうえで、縦軸に周波数、横軸に時間をとったスペクトログラムというものを可視化するのも良いらしいです。参考文献に従って行ってみます。

5Cよりも11C4が赤い線が1つ多いように見えます。幅広く音が鳴っていてモサっとしてしまっているのでしょうか。私としては5Cの方が音が鋭くて好きです。

おわりに

音声波形で音色の比較がうまくできるかどうか試してみたのですが、良いと思われる音とそうでない音で相関係数や音声波形などのデータの可視化において違いが生じやすいのかなという印象でした。そして音色をつかさどるとされるスペクトログラムにおいても、違いがありそうでした。
もっと音源を集めていっていい音の研究をしていこうと思います。あと、音楽の理論の方も細々と学んでいきます。

参考文献

IPythonデータサイエンスクックブック ―対話型コンピューティングと可視化のためのレシピ集
pyreaperで音声データのピッチを掴むためのメモ書き(F0の抽出)
Pythonで音声解析 – 音声データの周波数特性を調べる方法
基本周波数についてのまとめ
イラストで学ぶ 音声認識 (KS情報科学専門書)

BLSTMを用いた文書分類でデザイナーズマンション予測に再挑戦

はじめに

仕事で深層学習を使うことはないのですが、扱える技術の幅を広げていきたいなと思い、BLSTMを用いた文書分類についてkerasでの簡単なサンプルコードをやってみようと思います。データは以前集めた、某不動産紹介サイトの賃貸マンションの設備に関する文書とそれがデザイナーズマンションかどうかのラベルを使います。そして文書内の単語からその文書がデザイナーズマンションかどうかを予測します。前回はAUCで83%だったので、それを超えれると良いですね。

目次

単純なRNNとは

  • モチベーション
    • フィードフォワード型のニューラルネットワークではうまく扱うことができない時系列データをうまく扱えるようにすること。
  •  特徴
    • 入力が互いに関係している(多層パーセプトロンの際は置かれていない仮定)
      • 直訳すると循環するニューラルネットワークとなる。
    • 最初の文の単語が2つ目、3つ目の単語に影響を与える可能性を考慮。
    具体的な関数の形としては、 $$ h_t = \tanh (W h_{t-1} + U x_t) \\\ y_t = softmax(V h_t) $$ で与えられる。
    \( h_t \)は隠れ層の状態を、\( x_t \)は入力変数を、\( y_t \)は出力ベクトルを表している。(他のアルファベットは重み行列)

LSTMとは

  • モチベーション
    • 単純なRNNの勾配消失問題を解決するために提案された手法。
  • 特徴
    • 単純なRNNに置き換えることで性能が大幅に向上することも珍しくない。
      • 時系列データ、長い文章、録音データからなる長期的なパターンを取り出すことを得意としている手法。
    • 勾配消失問題に強い
    • Long Short-Term Memory:長短期記憶
      • 長期依存性を学習できるRNNの亜種。
      • 入力ゲート、忘却ゲート、出力ゲート、内部隠れ層という4つの層が相互に関わり合う。重要な入力を認識し、それを長期状態に格納すること、必要な限りで記憶を保持すること、必要なときに記憶を取り出すことを学習する。
        • 入力ゲート:内部隠れ層のどの部分を長期状態に加えるかを決める。
        • 忘却ゲート:長期状態のどの部分を消去するか決める。
        • 出力ゲート:各タイムステップで、長期状態のどの部分を読み出し、出力するかを決める。
$$
i = \sigma (W_i h_{t-1} + U_i x_t) \\
f = \sigma (W_f h_{t-1} + U_f x_t) \\
o = \sigma (W_o h_{t-1} + U_ox_t ) \\
g = \tanh (W_g h_{t-1} + U_g x_t) \\
c_t = (c_{t-1} \otimes f ) \otimes ( g \otimes i) \\
h_t = \tanh (c_t) \otimes o
$$ i:入力ゲート(input)
f:忘却ゲート(forget)
o:出力ゲート(output)
\( \sigma \):シグモイド関数
g:内部隠れ層状態
\(c_t \):時刻tにおけるセル状態
\(h_t \):時刻tにおける隠れ状態

Bidirectional LSTMとは

  • モチベーション
    •  従来のRNNの制約を緩和するために導入。
  • 特徴
    • ある特定の時点で過去と将来の利用可能な入力情報を用いて訓練するネットワーク
      • 従来のRNNのニューロンをフォワード(未来)なものとバックワード(過去)なものとの2つに分ける。
        • 2つのLSTMを訓練している。
      • 全体のコンテキストを利用して推定することができるのが良いらしい。
        • 文章で言うと、文章の前(過去)と後(未来)を考慮して分類などを行うイメージ。
      • 人間もコンテキストを先読みしながら解釈することもある。
    • BLSTMは全てのシークエンスの予測問題において有効ではないが、適切に扱えるドメインで良い結果を残す。
    • 1997年とかなり歴史があるものらしい
出典:Deep Dive into Bidirectional LSTM

Bidirectional LSTMで文書分類

今回は、BLSTMを使って、マンションの設備に関するテキスト情報から、そのマンションがデザイナーズマンションかどうかを予測します。全体のソースコードはGoogle Colabを御覧ください。

データ

データを確認してみると、
 
今回のデータがテキストとラベルからなっていることがわかる。なお、データ数は1864件あり、そのうち16%がデザイナーズマンションです。

前処理

Google Colab上で形態素解析を行うために、MeCabをインストールする。
 
これでMaCab NeologdをGoogle ColabのPythonで実行できます。
テキストデータの前処理を行うために名詞だけを抽出してリスト形式で返す関数を定義します。
 
ここで、語彙に関するデータを作成します。
 
続いて、単語とそのインデックスからなるdict形式のデータを作成します。
 
最後に、これまでに作成した語彙とそのインデックスのデータを用いて、実際に学習に使う入力データと出力データを作成します。
 

実行

先程作成したデータを訓練データとテストデータに分けます。
ここで、AUCを計算するための関数を定義します。(まるまる拝借しました)
続いて、kerasを用いて、ネットワークを構築し、コンパイルを行います。
  テストデータでの予測精度を確認します。
実際のラベルとテキストデータを見比べてみます。
LSTMの場合は、BLSTMに関する記述(1行)をネットワークから除外すれば良いので簡単に試すことができます。 せっかくなので比較してみたところ、AUCは0.841でした。BLSTMは0.844だったので、若干上回る程度のようです。 以前扱った記事ではデザイナーズマンション分類はAUCが0.83程度だったので、LSTMを使ったほうが精度が少しだけ高いようです。

追記

TensorBoardの検証のloglossを見てみます。 エポックに対してloglossが非常に荒れています。学習曲線としてはセオリー的にアウトなようです。一方で、検証のAUCはエポックに従って高まるようです。 AUCは良くなっているけどloglossが増え続けている。loglossが下がらないと過学習している可能性が高いので、これは過学習しているだけなのだろう。

参考文献

 

2019年に読んだデータ分析系の本の振り返り(21+1冊)

はじめに

2020年、あけましておめでとうございます。年末に自分自身を振り返ろうと思ったのですが、結局データ分析と勉強しかしていないわけで、書籍を振り返ろうと思うに至りました。私の知り合いのデータサイエンティストはだいたい全冊持っているであろうと思われますが、良い本だと思うので思い出していただければ幸いです。

1.『ベイズモデリングの世界』(岩波書店)

基本的に階層ベイズモデルを使って、個体ごとの異質性を考慮した分析手法が提案されています。前半はオムニバス形式で様々な先生がモデルの適用について執筆されており、後半では伊庭先生による階層ベイズモデルの講義になっています。途中でスタイン統計量による縮小推定の話があげられ、柔軟なモデリングのためには「階層化した方が少なくとも望ましい推定量が得られる」という数学的証明を捨てることもやむを得ないと書かれています。

2.『トピックモデルによる統計的潜在意味解析 (自然言語処理シリーズ) 』(コロナ社)

この本はトピックモデルの教科書というよりも、ベイズ推定の教科書という側面が強い印象があります。途中で出てくる数式は流し読みするのは難しく、最低2冊以上のノートが別途必要になると思います。一度でもLDAのパラメータを導出してみたいという方には良い教科書だと思います。疑似コードが提供されているので、それをもとにRやPythonでコーディングしていけば、一番シンプルなLDAが非常に短い行で実行できてしまうことに驚かれるかもしれません。人間が手を動かして推定アルゴリズムを導出しているからこそ、短いコードで済むということを実感できるはずです。

3.『構造的因果モデルの基礎』(共立出版)

グラフィカルなアプローチで因果推論を扱っている書籍です。Judea Pearl流の因果推論アプローチについて記すことを目的に書かれています。基礎と書かれていますが決して簡単ではありません。ただ、扱われる数学のレベルとしては確率と線形代数がわかれば大丈夫だと思われます。余談ではありますが、1章の相関関係と因果関係の事例紹介で「おむつとビールの話」が都市伝説ではなくきちんと記事としてWall Street Journalという雑誌に掲載されていたことが明らかにされています。

4.『現場で使える!PyTorch開発入門 深層学習モデルの作成とアプリケーションへの実装 (AI & TECHNOLOGY)』(翔泳社)

PyTorchを触ったことがないが、深層学習の手法について知っている層を対象とした本です。6章まではGoogleのColabで動かせるのでGoogleに課金することなく深層学習による回帰、CNN、GAN、RNN、Encoder-Decoderモデル、ニューラル行列因子分解をPyTorchで試すことができます。写経したものはこちら。転移学習や高解像度化や画像生成、文章のクラス分類、文書生成、機械翻訳などもできるので、PyTorchでこれくらいの量をコーディングしたらこれくらいのことができるのかという学びや、他の人の書いたPyTorchコードを読みやすくなるなどの便益は十分にあると思いました。

5.『作ってわかる! アンサンブル学習アルゴリズム入門』(シーアンドアール研究所)

会社で行っているPythonもくもく会用に買った本で、scikit-learnを使わずに機械学習のアルゴリズム(アンサンブル系)をコーディングするための本です。pythonのコードについて逐次、細かい解説が行われているわけではないので、1行1行自分でコメントを加えながら写経をしていけば力が付くという本かなと思われます。sklearnはそれはそれで素晴らしいですが、こういう本でフルスクラッチで修行できるのはいいですね。

6.『数理統計学―基礎から学ぶデータ解析』(内田老鶴圃)

統計検定1級を合格された方のブログで紹介されていた教科書です。理系の大学生レベルの数学知識があれば、数理統計学の基礎を学べると思います。中心極限定理の証明や、様々な分布の期待値や分散、様々な分布の性質について数式を用いてしっかり理解することができます。数式もほどよく端折られているので、無論ですがノートが数冊必要になります。各章毎にある練習問題も解くことで力が付くと思います。日本の大学の授業の教科書がこれだったらジェノサイド(再履修者の大量発生)が起きるんだろうなと思ってしまった。

7.『44の例題で学ぶ統計的検定と推定の解き方』(オーム社)

統計の検定に関してだけ扱った珍しい本です。第3部までは統計学の普通の教科書ですが、それ以降であらゆる検定の例題が44件も載せられています。パラメトリックな検定から、ノンパラメトリックな検定まで幅広く扱われています。一番気にいっているのは仮説検定法の分類の表です。これさえあれば、どのデータに対してどの検定を行えばいいかが一目瞭然です。

8.『わけがわかる機械学習 ── 現実の問題を解くために、しくみを理解する』(技術評論社)

機械学習の原理を手早く数式を交えて学べる本です。かゆいところに手が届いていると言うか、既出の教科書では捨象されがちな、条件付き確率における2変数以上の条件づけでの表現に紙面を割いていたりしてくれるのが嬉しいです。ある程度数学の話はわかるが、だいぶ忘れているビジネスパーソンには大変にありがたいコンテンツと言えると思います。ベイズ線形回帰に関しても行列を用いた、わかりやすい導出方法が紹介されています。またコラムで紹介されている、測度論にどう向き合えばいいかの著者の見解は参考になります。

9.『Statistical Rethinking: A Bayesian Course with Examples in R and Stan (Chapman & Hall/CRC Texts in Statistical Science)

R言語とstanを用いてベイズ統計学を入門レベルから学べる本です。各トピックごとにそれなりの紙面が割かれています。例題も豊富にあるので、線形回帰・MCMC・情報量基準・階層ベイズモデルまで、ベイズ統計学を基礎から応用までしっかりと学べると思います。youtubeで著者の講義も配信されているので、留学気分を味わえます。

10.『scikit-learnとTensorFlowによる実践機械学習』(オライリージャパン)

2019年に日本で開かれたML SummitでTFの開発者がおすすめしていた教科書です。前半部分で機械学習の入門から応用までをわかりやすい説明で学ぶことができます。数式は少ないですが、図とソースコード(Python)がちりばめられており、手を動かして理解を進めることができます。後半部分はTensorFlowを用いた深層学習の基礎を同様に手を動かして学ぶことができます。ただ、TFのバージョンも変わってきているので前半の説明をアテにして読むのも良いと思います。

11.『AIアルゴリズムマーケティング 自動化のための機械学習/経済モデル、ベストプラクティス、アーキテクチャ (impress top gear)

マーケティングへのデータサイエンスの適用に関する珍しい書籍です。ソースコードはついていないですが、業務で使う際のアイデアが手に入ることもあります。一般的な回帰、生存時間分析、オークション、アトリビューション分析、アップリフトモデリング以外にも、情報検索やレコメンデーションやトピックモデルなどマーケティングながら学際的なトピックも扱われています。レコメンドなどで使われる、ランク学習に関して詳しく書かれた書籍をあまり知らないので、この本はその点においてもありがたい本でもあります。

12.『入門 統計的因果推論』(朝倉書店)

ほぼ全ての章でグラフィカルなアプローチで因果推論を扱っています。例題も豊富なので、一つ一つ丁寧にやれば理解が捗ります。おそらく、例題の多さを含め一番丁寧にd分離性、do演算子、バックドア基準、フロントドア基準に関する説明をしてくれている本なのかなと思いました。グラフでの因果推論に関して初めての人でも、確率さえ知っていれば読み進めることができるはずです。また、途中で操作変数法の紹介もされ、経済学出身者としては読みやすい。ただ、傾向スコアのくだりや、DIDなどのくだりはあまり出てきません。あと、やってないですが章末の練習問題に対するSolution Manualが提供されているようです。

13.『実践 ベイズモデリング -解析技法と認知モデル-』(朝倉書店)

ベイズモデリングを様々な事例に適用する方法がオムニバス形式で記された本です。ワイブル分布や異質性を考慮した二項分布、無制限複数選択形式のアンケートデータに対する手法、トピックモデル、項目反応理論などが扱われています。マーケティングの実務で使える事例が多いように感じました。こちらはサポートサイトでRコードとstanコードが提供されています。あと、appendixにあるプレート表現の見方も参考になります。

14.『機械学習スタートアップシリーズ ベイズ推論による機械学習入門 (KS情報科学専門書)

機械学習などで用いるベイズ推論を扱った教科書です。入門とありますが、入門者は書かれた数式をそのまま見ていても頭に入らないのではないでしょうか。手を動かしてなんぼの本だと思います。ノート2冊は絶対に必要です。たぶん、数式の展開を丁寧に記すと倍以上の厚みの本になると思います。各々のモデルに関してグラフィカルモデルが記されているのや、サンプルコードとしてGitHubにJuliaで書かれたソースコードが提供されているのも良いです。

15.『その問題、数理モデルが解決します』(ベレ出版)

物語形式で、様々な問題に対して数理モデリングのアプローチが紹介されています。途中でマッチング理論やゲーム理論やオークションなども登場することから、経済学出身者も喜ぶ内容かもしれません。社会人になってからナッシュ均衡という言葉が書かれた本は中々出会って来なかった。

16.『ヤバい予測学 ― 「何を買うか」から「いつ死ぬか」まであなたの行動はすべて読まれている』(CCCメディアハウス)

2013年と結構古い本ですが、データ分析を様々な事象に対して適用した事例紹介本です。アップリフトモデリングへの言及もあり、こういったものに関して日本は何年も遅れてブームが来るんだなという実感を与えてくれた本でもありました。appendixに分析事例が147個ほどあげられているのも参考になります。

17.『たのしいベイズモデリング2: 事例で拓く研究のフロンティア』(北大路書房)

主にstanを用いたベイズモデリングによる分析事例が1と2で38本もオムニバス形式で載っています。ほとんどの事例で階層ベイズモデルが扱われています。2では若干マーケティングに近い内容の題材も扱われ、データサイエンティストの人にも嬉しい内容かもしれません。もちろんデータとstanとRのコードがサポートサイトで提供されています。

18.『カルマンフィルタ ―Rを使った時系列予測と状態空間モデル― (統計学One Point 2)』(共立出版)

状態空間モデルで時系列予測を行うための手法が記されている本です。RのKFASパッケージが全面に渡って扱われています。トレンドを考慮したり、カレンダー効果を追加したり、共変量を追加したりなど様々なアプローチが紹介されコードも伴っているわけですから、業務でも抜群に役に立ちました。

19.『機械学習のエッセンス -実装しながら学ぶPython,数学,アルゴリズム- (Machine Learning)』(SBクリエイティブ)

自分のいる会社で最低限の数学がわかると思われる若いメンバーに買ってもらうように言っている本です。微積分・線形代数だけでなく、カルシュ・キューン・タッカー条件(最適化数学)に関しても扱ってくれているので、ここで出てくる数学がわかれば大体の論文に立ち向かえると思います。さらに、Pythonの基礎もこれで学ぶことができるので一石二鳥な素敵な本ですね。また、最後の方でスクラッチでアルゴリズムを書くパートがあり、こちらも勉強になります。

20.『機械学習のための特徴量エンジニアリング ―その原理とPythonによる実践 (オライリー・ジャパン)』(オライリー・ジャパン)

機械学習における前処理の指針を与えてくれる本です。Pythonのコードが提供されています。例えばですが、「テストデータにだけある、新しい単語は取り除いてしまえばいい」などの細かいアドバイスが何気に嬉しいです。「Effectコーディング」「特徴量ハッシング」「ビンカウンティング」「バックオフ」「leakage-proof統計量」などは読むまで知らないところだったので勉強になりました。

21.『データサイエンスのための統計学入門 ―予測、分類、統計モデリング、統計的機械学習とRプログラミング』(オライリージャパン)

データ分析の仕事をする上で最低限必要な知識を幅広く抑えることができる本です。数式は少なく、ところどころ出てくるコードはR言語です。参考文献などがブログだったりするため厳密さがめちゃあるわけではないですが、業務で使う分には問題ないと思います。分類問題において、AUCなどの評価指標だけでなく、予測値自体の探索的分析のすすめなどが書かれており、参考になりました。また、特徴量エンジンとしてのk-NN法の話も面白いと思いました。

[+α]『プログラマのためのGoogle Cloud Platform入門 サービスの全体像からクラウドネイティブアプリケーション構築まで』(翔泳社)

Google Cloud Platformを初めて触るデータ分析者にはちょうど良い本です。説明もわかりやすいので、いきなりアカウントを作ってドキュメントを解読するよりかは戸惑いは減るはずです。この本を土台に、GCS・GCEを駆使してML系のAPIを呼び出して使うなどの最低限の操作は私でもできるようになりました。GCPの画面や機能もどんどん変わっていくので書籍を買ってもアレなんですが、歴史的な背景も若干記述されているので、それはそれで勉強になります。ただ、エンジニアにこの本を買うべきか聞いた際にネガティブな意見があったのですが、たぶん現役プログラマからすると簡単過ぎるからなんだろうなと思います。

終わりに

2019年もぼちぼち勉強できましたが、2020年もこれまで同様にノートとペンを大事にする勉強を続けていき、コーディングも分析ももっともっと数をこなして会社や社会に求められるようなデータ分析官を目指していこうと思います。あぁ、英会話などの勉強をする時間を作るのが難しい。

[Python]機械学習などでテキストデータを特徴量にする際のソースコード集

テキストデータの特徴量化について

仕事ではテキストデータを多用するので、機械学習などで扱うためにテキストデータを特徴量にするためのアプローチを色々と整理してソースコードを残しておきたいと思います。今回はあくまでも私の知っているものだけなので、網羅性はないかもしれませんが悪しからず。
(2019/08/18 追記)Stackingをカジュアルに行えるvecstackというモジュールを用いた予測も試してみました。下の方の追記をご覧ください。

アプローチ

テキストデータを特徴量にする際のアプローチとしては、以下の3つが良く使っているものとなります。
・単語ベース
・クラスタ、トピック、分散表現ベース
・文書間の類似度ベース

今回扱うデータ

ひょんなことから、昨年10月くらいに取りためたマンションの施設情報のテキストです。

緑色が印象的な某不動産紹介サイトをクローリングしました。全部で1864件ほどの文書数となります。

加えて、デザイナーズマンションかどうかのフラグを作成しました(17%くらいがデザイナーズマンションの割合)。これでもって、マンションの施設情報からデザイナーズマンションかどうかを分類できるかチャレンジしたいと思います。
ここにデータを置いていますので、興味のある方はご利用ください。

今回扱うモデル

ランダムフォレストです。10foldsクロスバリデーションによるAUCの結果を各手法のスコアとして扱います。

こちらは、任意の手法に関して10foldsクロスバリデーションで実行し、AUCのグラフを生成してくれるソースコードです。主にscikit-learnのサイトに載っているものです。引数のclassifierをsklearnの任意のモデルのインスタンスで渡せば動きます。

単語ベース

シンプルに単語をそのまま特徴量にするというものですが、文書によっては単語数が多すぎて収集がつかないと思います。そこで単語を簡単に選択できるDocumentFeatureSelectionというパッケージを利用します。

このパッケージでは
・TF-IDFベースの特徴量選択
・PMI(Pointwise Mutual Information)ベースの特徴量選択
・SOA(Strength of association)ベースの特徴量選択
・BNS(Bi-Normal Separation)ベースの特徴量選択
を行うことができます。

まずは今回のベースラインとして、単語のカウントベースでの特徴量を扱いたいと思います。
その前に、GitHubに上がっているデータに対して以下のように簡単な前処理をしておきます。

ようやくベースラインの予測となります。以下のコードを実行すると、ROCが描かれた図がJupyter上で表示されます。

AUC82%というのはベースラインとしてはなかなか強敵なのではないでしょうか。

さて、本題の特徴量選択パッケージの適用をするためのソースコードを以下に記します。

以上のソースコードを実行すれば、tf_idf_scored_df、pmi_scored_df、soa_scored_df、bns_scored_dfにスコアを付与された単語のリストが手に入ります。

ここでは各スコアに関してアドホックに閾値を設けて、特徴量として利用することにします。

TF-IDFベースの特徴量選択

PMIベースの特徴量選択

SOAベースの特徴量選択

BNSベースの特徴量選択

クラスタ、トピック、分散表現ベース

続いて、k-meansやLDAやword2vecを用いて特徴量を作成する方法です。今回はk-means、ミニバッチk-means、LDA、FastTextによる分散表現を扱います。

k-means、ミニバッチk-means

LDA

こちらはgensimでLDAを推定し、推定したトピックの割合をデータフレームで返すコードです。

トピック数をとりあえず30個くらいに指定して推定したトピックの割合を特徴量として文書分類を行います。そのため、特徴量の数は30個になります。

FastTextによる分散表現

今回はデータ数が少ないことから、学習済みの分散表現を用います。日本語のコーパスに対して、FastTextで推定された分散表現となります。学習済み分散表現はこちらから拝借しました。

分散表現は単語に対して計算されるので、単語に対して分散表現を足し合わせたものを特徴量として扱います。ここでは分散表現の合計値、平均値、TF-IDFで重みを付けた平均値の3つのパターンを試します。

合計値ベース

平均値ベース

TF-IDFで単語を重みづけた平均値ベース

文書間の類似度ベース

今回は、デザイナーズマンションの定義文に似ているかどうかという観点で類似度ベースの特徴量を作ってみたいと思います。

今回は変数が一つだけなので、機械学習はせず、デザイナーズマンション割合との関係を図示するにとどめておきます。横軸がデザイナーズマンションの定義と施設情報の類似度で、縦軸がデザイナーズマンション割合です。

どうやら、途中でデザイナーズマンション割合がピークを迎えるようです。

おわりに

最先端の手法は調べれていないですが、テキストデータを特徴量に落とし込む手段を備忘録として残しておきました。今回あげた中では、SOAベースの特徴量選択のAUCが83%と一番高かったですが、ベースラインが82%と僅差でした。そして、分散表現形のものは80%に届いた程度です。余力があれば新しい特徴量の作り方が分かり次第アップデートしようと思います。

追記

“Automate Stacking In Python How to Boost Your Performance While Saving Time”という記事を見つけたので、紹介されているvecstackモジュールを使って今回のモデルに関して簡単にstackingしてみようと思います。
コードに関しては、こちらのGitHubに上げています。試してみた所、AUCは88%になりました。結構上がりましたね。しかもコードはめちゃ短いので楽です。

参考文献

[1]Julian Avila et al(2019), 『Python機械学習ライブラリ scikit-learn活用レシピ80+』, impress top gear
[2]Receiver Operating Characteristic (ROC) with cross validation
[3]@Kensuke-Mitsuzawa(2016), “テキストデータで特徴量選択をする”, Qiita
[4]JapaneseTokenizer 1.6
[5]DocumentFeatureSelection 1.5
[6]自然言語処理における自己相互情報量 (Pointwise Mutual Information, PMI)
[7]【Techの道も一歩から】第3回「第11回テキストアナリティクス・シンポジウム」
[8]文書分類タスクでよく利用されるfeature selection

Python/Rもくもく会をプライベートで開催するための参考図書・資料をまとめる

はじめに

社内で定時後に有志で勉強会というか、その場に集まってPythonやRをもくもくと勉強をするもくもく会を開きたいと考えています。目的としては分析スキルの向上や機械学習ができるようになりたいとかいう個々人の願いを叶えることです。
色々なスキルレベルのメンバーが参加することが予想されるので、皆を幸せにするためにもレベルに応じた良い教材が必要だと思いました。
ここでは、レベルに応じて適切な教材などを忘備録として残していきたいと思います。
(私自身、全てのレベルの対象者に適切な教材を網羅しているわけではないので、随時更新していこうと思います。)

受講対象について

受講対象(PythonやRをまともに触ったことがない人)は2軸で分けるとすると以下のようになると思います。

・プログラミング経験あり/経験なし
・数学の心得あり/心得なし

  • プログラミング経験なし&数学の心得あり(アルキメデス)
    理系出身の人がメインだと思います。学部・学科によっては全然扱わないですよね。数的な思考は得意だが、それを活かすスキルが不足しているような人でしょう。眼の前におかれた数学の問題を紙とペンで解くことはできるが、仕事で使えないという感じ。私も偉そうなことは言えないですが、コードが荒れがちなので周りに良い先生がいたほうが良いと思います。

  • プログラミング経験なし&数学の心得なし(葉っぱ隊)
    一番習得に時間がかかると思います。野球やったことないのに、野球選手になりたいという人に皆さんは違和感を感じるでしょう。イメージはそんな感じです。一番時間がかかるからこそ、挫折しないための教材選びが重要かもしれません。スキル的に全裸なので、葉っぱ隊と名付けましょう。

  • プログラミング経験あり&数学の心得あり(デーサイ候補)
    最も頼もしい存在です。教科書をお渡ししておけば勝手に成長すると思います。ある程度経験を積めば分析業務を任せても良いと思います。

  • プログラミング経験あり&数学の心得なし(進捗ありマン)
    各種手法の原理を知るまではそれなりに時間がかかると思いますが、手を動かして何ができるかをすぐに味わえるので、モチベーションを維持しながら学んでいきやすいと思います。コード自体は実行できるので進捗ありマンと名付けてみましょう。

この2軸でPythonとRに関する便利な資料を探したいと思います。
ただし、どの本に関してもどのレベルの人が買っても良いとは思います。ただ、数学の心得がない中で、テイラー展開とか平均値の定理とかラグランジュ未定乗数法などの表現を目にした際に、挫折してしまう可能性があるので、適した書籍から順次広げていくのが良いと思います。なお、今回はPCでもくもくと進めれそうな書籍を選んでいます。紙とペンで進める本も重要なのですが、そのようなかた向けの書籍は取り上げていません。

アルキメデス向けの教材

Python

R

  • みんなのR 第2版
    『Rによるデータサイエンス』と迷ったのですが、プログラムの実行結果がそのまま載っている印象だったので、こちらの本がプログラミング初心者には優しいと判断しました。ほとんど数式は出てこないのですが、一般化線形モデルや時系列解析などもカバーしてくれています。また、データの前処理に関する記述もこちらの本の方が手厚いです。

葉っぱ隊向けの教材

Python

  • Pythonスタートブック [増補改訂版]
    本当にプログラミングがはじめての人向けの本です。まずはプログラミング自体に慣れたほうが良いと思います。

  • プロゲートのPython入門講座
    妻におすすめされた講座です。無料枠でもある程度学びがあるようです。環境を構築しなくても良いという点が非常に葉っぱ隊に適しているとのことです。

R

  • Rによるやさしい統計学
    Rのインストールあるいは統計学の初歩のところから、応用まで幅広く説明している本です。数式はあまり出てきませんがコードが載っているので、手を動かすことができると思います。

読み物

デーサイ候補向けの教材

Python

R

進捗ありマン向けの教材

R

  • RStudioではじめるRプログラミング入門
    プログラミング経験のある進捗ありマンであれば、R言語の扱い方をまずは知りたいだろうと思います。関数の書き方やヘルプページの使い方、オブジェクトの説明、S3の話などが詳しく書かれています。

  • 新米探偵、データ分析に挑む
    R Studioのインストール方法なども載っているので、進捗ありマンなら最初から最後まで実践できると思います。数式もほとんど出てきません。色んな分析事例をRで取り組むことで分析業務のイメージも付いてくると思います。

  • RユーザのためのRStudio[実践]入門−tidyverseによるモダンな分析フローの世界−
    R言語について何となくつかめた進捗ありマンがモダンな記法であるtidyverseを効率よく学べる良い本です。データ整形・クロス集計・可視化がモダンな記法で書けるようになると結構楽しいと思います。

Python

今後について

そもそもPythonやRに触れたことがない人にとって、Tokyo.Rの初心者セッションは少し適していないのかなと思ったので、今回は取り上げていないですが、一通り使い方をわかってもらえたら初心者セッションの資料を使ったもくもく会も開きたいと思います。最終的にはKaggle部とかを作るとかになるのかもしれませんが、そこまで行けるか行けないか。

Uplift Modeling用のパッケージtools4upliftを使ってみた

はじめに

今回は、今後仕事で使いたいという思いもあり、RでUplift Modelingに関して便利なパッケージがないか探した結果、2019年に登場したばかりのtools4upliftの存在を知りました。アップリフトモデリングのモチベーションに関しても簡単に説明しながら、サンプルデータで実践してみようと思います。

・Uplift Modelingとはなにか
・Uplift Modelingの卑近な例え話
・Uplift Modelingのサンプルデータ
・tools4upliftについて
・tools4upliftでCriteoデータを試してみる
・『仕事ではじめる機械学習』の9章のコードをCriteoデータに試してみる
・おわりに
・参考文献

Uplift Modelingとはなにか

きちんとした説明は、あまりにも今更感があるので説明は端折りたいと思います。既出の文献がありますので、そちらを熟読ください。

Uplift Modelingの卑近な例え話

自分が吉野家のマーケティング担当だとしましょう。吉野家のアプリで割引クーポンを顧客にばらまくことができるとします。
マーケターとして重要なのは、割引クーポンを渡したことをきっかけとして吉野家に足を運び購入する顧客を増やせるかどうかになります。

マーケターの手元にあるのは、割引クーポンをばらまいた顧客とばらまかなかった顧客、そして吉野家で牛丼を食べたかどうかのデータです。
以前のマーケティング担当者がランダムにクーポンをばらまいていたことが重要なポイントです。

このデータから、顧客は以下の4分類に分かれます。

  • 無関心:割引クーポンをばらまこうが我関せず。そもそも吉野家に行く気はない。
  • 説得可能:普段、牛丼が安いすき屋にばかり行っているが、割高に感じている吉野家に負い目を感じている。割引クーポンで揺さぶられ来店する。
  • 天の邪鬼:吉野家コピペのように、割引クーポンを握りしめた家族連れに遭遇したくないので、割引クーポンをばらまかれたら来店しないような客。
  • 鉄板:毎日決まった時間に吉野家に行くことを心に決めている客。

マーケターは割引クーポンをばらまいた顧客と割引クーポンをばらまいていない顧客にデータを二分し、それぞれ機械学習のための訓練用データとテスト用データを用意します。

つまり、「割引クーポンをばらまいた顧客」の訓練用データとテスト用データと「割引クーポンをばらまいていない顧客」の訓練用データとテスト用データの計4つのデータセットを用意します。

まず、牛丼の購入の有無を教師とした訓練用データでロジスティック回帰モデルなどを推定します。
その結果、「割引クーポンをばらまいた顧客」から推定したモデルと、「割引クーポンをばらまいていない顧客」から推定したモデルが手元に残ります。

2つのテスト用データを1つにまとめて、先程推定したモデルを用いて、牛丼の購入確率を求めます。モデルは2つあるので、予測結果がテスト用データ1つに対して2つあることになります。

その予測結果の比(「割引クーポンをばらまいた顧客」モデルベースの予測値÷「割引クーポンをばらまいていない顧客」モデルベースの予測値)をアップリフトとみなします。

以下の図はこれまでの説明を図にしたものです。

アップリフトがどの程度の水準であれば、説得可能なユーザーが多いのかを探っていくことで、吉野家のアプリにおいて、どのユーザーに割引クーポンを発行するべきかがわかることになります。

Uplift Modelingのサンプルデータ

残念なことに吉野家のアプリのデータはありません。そこで今回は公開データを利用します。
以前より、The MineThatData E-Mail Analytics And Data Mining ChallengeのメールのデータがUplift Modelingで非常にしばしば取り上げられるデータでしたが、Twitterで他にデータないのかとぼやいたところ、2名の方にCriteo Uplift Prediction Datasetを紹介していただきました。

余談ですが、Criteo社と言えばディスプレイ広告のキング的な存在で、少し商品のリンクを踏んだだけであっという間に広告がレコメンドされますよね。自社で出稿用バナーを作っていましたが、CVRが高くなる良いクリエイティブを作ってきたのか、単にCriteo社のアルゴリズムが優秀なだけなのか非常に気になるところでしたね。

Criteo社が提供してくれている今回のデータは、2500万行に及ぶユーザーのデータで、プライバシー保護の観点から特徴量は復元できないような形式で提供されています。バイナリーのラベルとしては訪問やコンバージョンなどがあり、データ全体に占める処置群の割合は84.6%となっています。要は、吉野家で言う割引クーポンをばらまいた顧客が全体の84.6%に及ぶということです。

tools4upliftについて

2019年1月に公開されたRのUplift Modeling用のパッケージです。

  • 特徴量における連続値をカテゴリ変数にする際に、最適な階級値を求めてくれる関数
  • アップリフトモデリングの可視化する関数
  • アップリフトモデリングにおける特徴量選択ができる関数
  • アップリフトモデリングにおけるモデルのバリデーションを行う関数

などが提供されており、ちょいとRを触れるマーケターにとって、アップリフトモデリングにおける試行錯誤がかなりしやすくなる便利なパッケージだと思いました。
なお、このパッケージで扱っているモデルはロジスティック回帰になります。介入データをもとに推定したモデルの条件付き確率と非介入データをもとに推定したモデルの条件付き確率の差をアップリフトとして推定しています。

このパッケージの解説論文においては、アップリフトモデリングの評価指標としてQini曲線というものが提案されていました。Qini曲線はローレンツ曲線のようなもので、Qini曲線とランダムに割り当てた際のアップリフト量の差分の合計をQini係数と定義しています。

tools4upliftでCriteoデータを試してみる

こちらはアップリフト値の予測値の上位から右に並べた際のアップリフトの増大のグラフになります。20%あたりでピークになるようです。

こちらはアップリフト量の棒グラフです。20%の階級値を超えたらガクンと下がるのがわかります。

なお、Qini係数は0.03233551でした。

『仕事ではじめる機械学習』の9章のコードをCriteoデータに試してみる

tools4upliftの結果を鵜呑みにするのもあれなので、『仕事ではじめる機械学習』の9章のコードを使ってアップリフトモデリングを実践してみます。コードは丸パクリですが、謹んで掲載させていただきます。

こちらの図はアップリフト値の階級値ごとのCVRです。最上位のアップリフト値はCVRの差が大きいですが、上位40~50%程度のアップリフト値のときにCVRの差が最も大きいようです。

アップリフト値の順位とCVRの図です。順位が低くても処置群のほうがCVRがわずかに高いようです。

アップリフトのスコアとCVRの関係です。2未満であればCVRは処置群が上回っていますが、一様な傾向はなさそうです。

コンバージョンレートの差に対象群の人数を掛けることでliftを算出したものです。アップリフトスコアが1~2点であれば儲かるようです。

tools4upliftと出している指標が違うので比較ができないのが難点に思いました。tools4upliftはオートマチックな感じで便利なのですが、『仕事ではじめる機械学習』の9章を正義として進めたいので、どうにか揃えれるようにしていきたいと思います。

おわりに

tools4upliftというマーケターにとって銀の弾丸になりそうなパッケージの存在を知ることができ、実際に非常に便利そうな関数が用意されているのがわかりました。ただ、開発されたばかりのパッケージなのでそこまで結果を信じていません。『仕事ではじめる機械学習』本の結果と揃えたいなと思いました。その点がはっきりすれば業務で使ってみるのも良いですし、任意のマーケターに安心して共有できると思います。

参考文献

[1] 有賀康顕・中山心太・西林孝 (2018) 『仕事ではじめる機械学習』 オライリージャパン
[2] Mouloud Belbahri, Alejandro Murua, Olivier Gandouet, Vahid Partovi Nia (2019). “Uplift Regression: The R Package tools4uplift”, arXiv:1901.10867 [stat.AP]
[3] ohke (2019) 「Uplift modelingで施策が効く人を見極める」 け日記
[4] usaito (2018) 「Uplift Modelingで介入効果を最適化する」 Qiita

学習済み分散表現を用いた文書分類に挑戦(一部再学習も)

はじめに

2018年9月のテキストアナリティクスシンポジウムに行った際に、学習済みの分散表現で事前学習したモデルを使って分類してうまくいく事例が紹介されていました。
全てのタスクにおいてうまくいくとは思えませんが、試すコストはあまりかからないので試してみます。

2017年のテキストアナリティクスシンポジウムにおいても、メルカリやGunosyでは分散表現を用いた手法が一番精度が高いと言われていましたし、今年の会ではNLP系の学会でも分散表現はデファクトスタンダードになっているという話も伺いました。
2013~14年はLDAを使った研究が多かった気がしますが、徐々にシフトしていっているんですね。

これまで(Word2Vecを用いて蒙古タンメン中本の口コミ評価を予測してみる)は4000件程度の蒙古タンメン中本の口コミの情報を元に分散表現を手に入れていましたが、学習済みの分散表現を用いたアプローチも有効かもしれないと思い、試してみようと思います。

分類タスク

某グルメ口コミサイトの蒙古タンメン中本の口コミのテキストから、3.5点以上の評価かどうかを予測するタスクを扱います。
本当は、ポケモン図鑑の説明文から水やら炎やらのタイプを予測するとかをしたいのですが、あいにく手元にデータがないので、以前集めた蒙古タンメン中本の口コミを使います。(実は後日、ポケモン図鑑のデータを集めたのですが、平仮名にまみれたデータな上に、データ数も800件しかなかったので、どのみち厳しかったです。)

学習済み分散表現

Word2Vecなどで大量の文書をもとに学習させた分散表現のことを指します。
大規模コーパスで分散表現を手に入れる際は、数十GBにも相当するテキストデータを数時間かけて推定するので、学習済みのモデルは非常にありがたいです。(4年前に会社のPCで計算した際は、12時間くらいかかったこともありました。)

無料で提供してくださっている分散表現については、すでにこちらのブログで紹介されています。そこで紹介されているものに少し付け足すと、日本語の分散表現に関しては以下のようなものがあります。

  • 白ヤギコーポレーションのモデル:Gensim
  • 東北大学 乾・岡崎研究室のモデル:Gensim
  • Facebookの学習済みFastTextモデル:Gensim
  • NWJC から取得した単語の分散表現データ (nwjc2vec):Gensim
  • NNLM embedding trained on Google News:TensorFlow

そこで、今回は各種学習済み分散表現と蒙古タンメン中本コーパスで求めた分散表現の文書分類の性能バトルをしてみたいと思います。
ただ、分散表現ではなく、単語の頻度をもとに特徴量を作ったものが一番精度が高いのですが、分散表現同士の比較でもってどの学習済み分散表現が中本の口コミ分類に役に立ちそうなのかを明らかにしようと思います。(本来は分析という観点から即でボツですが、見苦しくも比較していきます。)

前処理

前処理は以下の通りで、テキストデータを分かち書きして、数値や低頻度・高頻度語を除外しています。

処理を施すとこのようなデータになります。

特徴量は、scikit-learnのCountVectorizerやTfidfVectorizer、分散表現の合計・平均・TF-IDFを求めたものを用意します。

蒙古タンメン中本の口コミ4000件から作成した分散表現:Gensim

まず、以前のブログで紹介した蒙古タンメン中本の分散表現ですが、以下のように推定しています。

Pipelineを用いてExtraTreesClassifierによる学習をします。特徴量は先程あげた、テキストベースのCountVectorizerやTfidfVectorizer、分散表現の合計・平均・TF-IDFで、評価指標はAUCのクロスバリデーションスコアとします。

汗に関してコンテキストの似ている単語を抽出しています。

結果は、以下の通りで、分散表現を使わない方がAUCが高いです。ただ、w2v_tfidf(分散表現のTF-IDFを特徴量にしたもの)が分散表現の中でAUCが高いようです。今回はこの60.5%をベースラインに比較していこうと思います。

白ヤギコーポレーションのモデル:Gensim

こちらのリンク、「word2vecの学習済み日本語モデルを公開します」から、ダウンロードしてそのまま以下のコードでモデルを扱えます。

汗の関連語を抽出していますが、中国の歴史の何かですか?可汗とかいう単語は聞いたことあるかも。

まずは白ヤギさんの分散表現をそのまま使って予測してみます。(コードは先程のものとほぼ重複するので省略しています。)
残念ながら、ベースラインの60.5%には至りませんでした。

hogehoge.modelというフルモデル形式の場合は、再学習が可能です。詳しくはこちら(models.word2vec – Word2vec embeddings model)に書かれています。

今回は、白ヤギさんの分散表現に対して、追加で蒙古タンメン中本のテキストを食わせて再学習させます。

ベースラインの60.5%よりも下回り、さきほどの白ヤギさんのもともとの分散表現よりも下回りました。

再学習してもかえって精度が下がったりすることから、簡単に精度が出るわけではなさそうです。まぁ、理想はその適用領域での大量のテキストデータがあることで、Wikipediaを元に作成した分散表現に強く依存しても駄目なのだろうと思われます。

東北大学 乾・岡崎研究室のモデル:Gensim

日本語 Wikipedia エンティティベクトルからダウンロードした学習済み分散表現を用います。ダウンロード後は普通に「gzip -d file.txt.gz」みたいにターミナル上で解凍します。以下のコードを実行すればすぐに使うことができます。
ただし、KeyedVectors形式のものは白ヤギさんのように再学習ができません。(Why use KeyedVectors instead of a full model?

汗の類似語に関しては、難しい単語が高めに出ているようです。

残念ながら、ベースラインの60.5%には至りませんでした。

Facebookの学習済みFastTextモデル:Gensim

FastTextはGoogleにいたTomas Mikolov氏がFacebookに転職されて作られた分散表現を求めるためのモデルです。Gensimでも呼び出せます。学習済みのものはこちらのGitHub(Pre-trained word vectors)にあるのですが、NEologdで形態素解析したものをベースに学習し公開されている方がいるとのことで、こちら(fastTextの学習済みモデルを公開しました)からダウンロードしたものを使わせていただきました。

何だこれはレベルの結果が返ってきました。中国の歴史上の人物か何かなんでしょうか。

若干ですがベースラインの60.5%よりも良い結果が得られましたが、 誤差の範囲な気がします。

NWJC から取得した単語の分散表現データ (nwjc2vec):Gensim

国立国語研究所の収集されたテキストデータを元に学習した分散表現が提供されています。ただし、利用するためには申請する必要があります。申請が受理されたらこちら(NWJC から取得した単語の分散表現データ (nwjc2vec) を頒布)からダウンロードして使えます。

汗の関連語ですが、うまく関連付けれているように思われます。少なくとも中国史ぽくはありません。しかしながら、顔文字まで学習していたとは。

ベースラインの60.5%よりも1%ポイントほど高い結果となりました。

NNLM embedding trained on Google News:TensorFlow

こちら(tensorflow-hubで超簡単にテキスト分類モデルが作成できる)で紹介されているように、GoogleがTensorFlowでGoogleニュースのテキストをもとに学習した分散表現が提供されています。

こちらのGitHub(NNLM embedding trained on Google News)から、Japaneseのnnlm-ja-dim50、nnlm-ja-dim50-with-normalizationなどが使えます。分散表現の説明についてはこちらのドキュメント(Token based text embedding trained on Japanese Google News 6B corpus.)にあります。