Pythonですばやくクロス集計してヒートマップつくるにはどうしたらいいかな?

05/09/2020

A8バナー広告

こんなことを書くよ

  • Pythonだけでクロス集計とヒートマップ作成をやりたい。どうする?
  • 言語処理では文書数でカウントしたいときもある。どうする?

Pythonだけでクロス集計とヒートマップを表示したいんや

ただ単に「クロス集計したい」というだけならば、ExcelかGoogle Spreadsheetを使うのが最速だと思う。

クリックだけで終わる。これにまさる簡単さはない。

でも、「Pythonでクロス集計を完結させたい」というときもある。

たとえば、Jupyter Notebookで分析ノートを作っている時。

いちいちcsvに書き出して、Excelでクロス集計して、Pythonで読み込んで・・・なんてめんどいことする?しないでしょ!

で、調べてみた。

例えば、今回はアノテーション結果の「ラベル」があって、この「ラベル」を集計したい場合(自然言語処理の話ばっかりになるな、このブログ)

クロス集計処理

pandasでおしまい。

まずは、こんな感じのテーブルを作る

文書IDラベル
000000001label-name

上の記事ではちがうデータ・タイプを2種類のクロス集計するときの話をしている。

でも、アノテーション結果のラベル集計になると、「ラベルA」と「ラベルB」の共起頻度みたいな集計をしたい(要するに、共起頻度行列を作りたい)

こういうときは、1軸の頻度カウントするクロス集計操作をすればいい。

Stackover flowにも似たような質問が出てる。

(違うパターン)いやいや、共起頻度を文書数でカウントしたいねん

言語処理やっていると、「ラベルそのものの共起頻度ではなくて、共起が発生した文書数を知りたいねん」というニーズもあったりする。

つまり、カウントの基準が「ラベルの共起」ではなくて「文書内でラベルが共起したら+1」になる。

言語処理には、1データがめっちゃ長いことがある。そういうときには、1文書内に同じラベルが頻出することもある。

一方、分析の観点では「入力文書のうち、どれくらいの文書でこの共起が起きるのか?」を知りたいこともある。

こういう時に、この集計は必要。

で、どうするかというと、pandasに頼るよりも、自分で集計処理を書いてしまったほうが早い(と思う)

3重ループを使ったうんこードを置いておきますね〜。

ヒートマップ作成

pandas.Dataframeからヒートマップは簡単に実現できる。on Stackover flow

でも、このままではちょっと不都合。

1軸のクロス集計してしまっているので、対角要素の数が多くなってしまう(当たり前)

これでは、うまくヒートマックが機能しないので、対角要素を消す(つまり、三角行列化する)やり方

これとpandas.Dataframeの入力を組み合わせるとこんな感じ。

__dfが三角行列化された状態のデータフレームになってる。

共起頻度を文書数でカウントした場合