Pythonでロジスティック回帰を使って、VTuberの動画タイトルから投稿者を推論してみる。
ただ、投稿者を推論するといっても、二値分類なので、投稿者が A か B かを分類するのみ。

使用するライブラリ

今回は以下のライブラリを使用する。

  • scikit-learn : テキストのベクトル化、ロジスティック回帰
  • MeCab : 日本語形態素解析

データセット

適当に選んだRan Channel / 日ノ隈らん 【あにまーれ】さんとKuzuha Channelさんの動画タイトルをデータセットとして使う。

動画タイトルはYouTube Data APIを使って取得した。
1日のAPIリクエスト上限に引っかかって、すべては取得できなかったが、日ノ隈らんさんのタイトルは475個、葛葉さんのタイトルは456個取得できた。

タイトル取得に使用したプログラムは以下に置いてある。

また、タイトル中の【】内には大体投稿者名が入っている。
これを使うと簡単に分類できてしまうと思うので、今回は削除する。
(まあ、【】内でなくても、投稿者名が入っていることがあるので結局、というところもあるが…)

プログラムと推論結果

今回推論に使用したプログラムは以下に置いてある。

テストデータは直近(このプログラムを作成中)に投稿された以下のタイトルを使う。

Ice breaker / ChroNoiR
けんきさんとあびつんさんとランクいってくる!!!

1行目が葛葉さんの動画タイトルで、2行目が日ノ隈らんさんの動画タイトルになっている。

推論結果

推論結果は以下のようになった。

[0.45 0.69]

なお、1個目が1行目の結果で、2個目が2行目の結果になる。
また、この結果が 1.0 に近いほど日ノ隈らんさんのタイトル、 0 に近いほど葛葉さんのタイトル"っぽい"と判断できる。

推論結果の分析

どういった理由で今回の推論結果が出たのか分析する。
ロジスティック回帰では各特徴量の係数(重み)と切片(バイアス)を見ることができる。 今回の特徴量はタイトルに含まれる単語なので、各単語について係数(重み)を見てみる。

まず1行目のタイトルの各単語の結果は以下の通り。
以下でwordtf_idfというラベルで出力しているものが、それぞれ単語名及びtf-idfという手法によって得られた、各単語の重要度になる。
ただ、このデータに関してはすべての単語について、学習元データに含まれていなかったため、this word does not existと表示されている。
つまり、上記推論結果で0.45と出ているが、これは切片(バイアス)成分によるものである。

title_index:  0
word:  Ice
tf_idf: this word dose not exist
word:  breaker
tf_idf: this word dose not exist
word:  /
tf_idf: this word dose not exist
word:  ChroNoiR
tf_idf: this word dose not exist

次に2行目のタイトルの各単語の結果は以下の通り。
こちらに関しては学習元に含まれる単語があるため、tf-idfによる重要度が出力されている。
また、最後にcoefというラベルで出力しているものが各単語の係数(重み)になる。
この例では「くる」という単語の係数が最も絶対値の大きい正の値を持っており、“日ノ隈らんさんのタイトルっぽい"単語といえる。
確かに学習元データをみると、日ノ隈らんさんのタイトルは「くる」という単語が入っていることが多い。

title_index:  1
word:  けん
tf_idf:  0.543427527727261
word:  き
tf_idf: this word dose not exist
word:  さん
tf_idf:  0.3682797658199599
word:  と
tf_idf: this word dose not exist
word:  あ
tf_idf: this word dose not exist
word:  びつんさんと
tf_idf: this word dose not exist
word:  ランク
tf_idf:  0.407136077797198
word:  いっ
tf_idf:  0.4598608078047089
word:  て
tf_idf: this word dose not exist
word:  くる
tf_idf:  0.43797806771223935
word:  !
tf_idf: this word dose not exist
word:  !
tf_idf: this word dose not exist
word:  !
tf_idf: this word dose not exist
model.coef:
[[ 0.13 -0.27 -0.4  ... -0.61 -0.36 -0.36]]
word:  けん coef:  0.17567560417510206
word:  さん coef:  0.3083888173761661
word:  ランク coef:  0.2137489896925166
word:  いっ coef:  0.6840435462897954
word:  くる coef:  0.9504970445317464