ydata-profiling
データ分析、特にEDA(探索的データ解析)で使われる。元はpandas-profilingという名前だった。
EDA
- 探索的データ解析(Explanatory Data Analysis)
何らかの、統計や機械学習に使うことを想定して集められた調査データがあるとする。
はじめて触れるデータなので詳細は不明だ、という場合、
- 欠損だらけとか、カラムの内容的にあり得ない値が含まれまくってるとか、重大な欠陥があるかもしれない
- データからなにか特徴的な傾向を見つけて意味のあることを言いたいので、それを見つけやすくしたい
という留意点や要求がある。そんな時、とりあえずデータ全体を俯瞰したい時に使う。
PythonでのEDAライブラリは、主に以下の3つがよく使われているっぽい。基本的にはpandas.DataFrameで表現するような2次元データを扱うのに特化している。
- ydata-profiling
- autoviz
- sweetviz
日本語化
ydata-profilingは、自動でseabornを使って相関グラフなどを描いてくれるが、 そのままの設定ではフォントが英語なので日本語が豆腐(□)になってしまう。
パッと分析できるのが利点なのに、いちいちカラム名を英数字化するのは煩わしい。日本語フォントで書けるようにする。
- 環境
- Windows 10
- Python 3.10
- matplotlib 3.5.2
- seaborn 0.11.2
- ydata-profiling 4.1.2
現状、調べた範囲ではあまり綺麗な解決方法が見つからず、sites-packages 内のファイルをいじることになる。
検索すると古いバージョンにおける解決策などが出てくるが、今は以下をすればよくなるはず。
(日本語を Meiryo で描画したいとする)
- .\site-packages\ydata-profiling\visualisation\context.py の書き換え
- l.80-81
matplotlib.rcParams.update(customRcParams) sns.set_style(style="white") matplotlib.rcParams['font.family'] = ['Meiryo', 'sans-serif'] # ←この行を追加 yield
(これは一例で、rcParams['font.family'] に日本語フォントを設定する記述なら何でもよい)
なぜこのような対策になってしまうか
まぁ、簡単に言えばライブラリが設定をハードコーディングしてるからなんですけど。
ydata-profiling では、グラフ描画にseabornを使っていて、seabornはmatplotlibを使っている。
matplotlibは、描画設定を rcParams という辞書で設定するのだが、ydataは、描画時に「グラフはこの設定で書きます!」というのをハードコーディングしている。
あまりにユーザーに自由にさせすぎるとそれはそれで収拾が付かなくなるので仕方ないか。
また、ハードコーディングの箇所が複数あるため、一部を変更しても反映されないということがあったりする。
- 一箇所目: ydata-profiling/visualisation/context.py 内 manage_matplotlib_context()
- 「描画前に matplotlib.rcParams を書き換える→描画後に元に戻す」ということをするためのデコレータを定義している
- ydataの各グラフを描画する関数は、このデコレータ経由で実行される
- ここで、font.family が sans-serif に、sans-serifの候補も日本語非対応のものに書き換わってしまう
しかし、context.py のハードコーディングされた設定を直接書き換えても、依然として豆腐のままとなる。
- 二箇所目: seaborn/rcmod.py 内 set_style()
- manage_matplotlib_context() ではrcParamsを設定した後、seabornの「sns.set_style(style=“white”)」を呼んでいる
- sns.set_style() では、style引数が文字列の場合、rcParamsをハードコーディングされた所定の設定に変更している
- ここで再度、一部の設定が上書きされてしまう。
- ここでも font.family が sans-serif、font.sans-serif も日本語非対応のものに書き換わってしまう
- → それ以前にいくら設定していようが無駄となる
- ※sns.set_style()関数自体は、2つめの引数にrcParamsの設定を辞書型で与えることで、辞書にある項目は変更しないようになっている。あくまで、ydataが呼ぶときにそうなっていないという話。
よって、manage_matplotlib_context() 内で、sns.set_style() が呼ばれた後に rcParams を変更すると上手くいく。
まぁ、seabornの方を変更してもいいのだが……、seaborn単独で使う場合は sns.set() などで後から変更できるので、 あくまで「sns.set_style() から描画までが一直線」なydata-profilingを使うときに困る、つまりydata-profilingに起因する問題なわけで、 ダーティな解決策をとるにしてもなるべくydata-profiling側をいじりたい、という気持ちはある。
ただ、他にもseabornに依存したライブラリを使っていて同様の問題があって、それらをseaborn側をいじることでまとめて解決できるなら、そっちでもいいかも。
置き換えるフォントの確認方法
上記ではMeiryoを例としたが、変更する日本語フォントは、matplotlibが認識しているフォントである必要がある。
フォント名を確認するには、
import matplotlib as mpl print(mpl.get_cachedir())
として、matplotlibのキャッシュディレクトリを表示させる。
そこに fontlist-v330.json(数字部分はバージョンによって変わる)というキャッシュファイルがあるはずなので、
その中に登録されているかで確認できる。
登録されていない場合、以下のいずれかの方法で認識させる。
- Windowsにフォントをインストールする
- 自動的に認識されるはず
- インストール後、キャッシュ(fontlist-v330.json)を消す。次回 import matplotlib 時に再作成される
- Pythonコード内で追加する