概要
PandasにはDataFrameが持つplotの他にpandas.plottingというメソッド群を持っており、これを使うことで通常のplotメソッドとは一風異なったグラフを作成することができます。しかしこれらは以下のページに多少の説明があるものの、全体を網羅した説明や中身の詳細は確認できずあまり使いこなせていませんでした。そこで本記事では、PandasのPlottingにあるグラフ描画をするための全メソッドを試して効果を検証してみました。 なお、Pandasのバージョンは0.23.4を使っています。
https://pandas.pydata.org/pandas-docs/stable/user_guide/visualization.html
メソッド一覧
コンソール上でdir(pandas.plotting)と入力すると、メンバの一覧が取得できます。その中でグラフ描画をするためのメソッド(かつplotでは実装されていない)は以下7メソッドがありました。
andrews_curves | autocorrelation_plot | bootstrap_plot | lag_plot |
parallel_coordinates | radviz | scatter_matrix |
上記を検証するために、irisのデータとsinの時系列データを使います。
import pandas as pd import numpy as np from pandas.plotting import * #irisのデータ df_iris = pd.read_csv("iris.csv", index_col=0) #時系列データ df_sin = pd.Series(np.sin(np.arange(0, 6.28*2, 0.01)))
それぞれのデータは以下のようになっています。(上位5件を表示)
df_iris
SepalLength | SepalWidth | PetalLength | PetalWidth | Name | |
---|---|---|---|---|---|
0 | 5.1 | 3.5 | 1.4 | 0.2 | Iris-setosa |
1 | 4.9 | 3.0 | 1.4 | 0.2 | Iris-setosa |
2 | 4.7 | 3.2 | 1.3 | 0.2 | Iris-setosa |
3 | 4.6 | 3.1 | 1.5 | 0.2 | Iris-setosa |
4 | 5.0 | 3.6 | 1.4 | 0.2 | Iris-setosa |
df_sin
Value | |
---|---|
0 | 0.00 |
1 | 0.01 |
2 | 0.019999 |
3 | 0.029996 |
4 | 0.039989 |
andrews_curves
andrews curvesはandrews plotとも呼ばれ、andrewsさんが考案した多変量データの可視化テクニックのようです。
https://en.wikipedia.org/wiki/Andrews_plot
https://www.jstor.org/stable/2528964
とりあえずまずは描画してみます。最初の引数にデータフレームを、2番目の引数にパターンの列を指定する必要があります。
andrews_curves(df_iris, "Name")
グラフを見ると多数の曲線が引かれており、それぞれがIrisのNameに対応した色になっていますので、1本1本がデータの1行1行に対応していることが読み取れます。また、グラフの形状からなんとなくNameごとに分かれそうなことが見て取れるのですが、初めて見ると縦軸と横軸の意味が良く分からないです。マニュアルに当たると、以下の式に基づいて描画しているということが記載されていました。
f(t) = x_1/sqrt(2) + x_2 sin(t) + x_3 cos(t) +x_4 sin(2t) + x_5 cos(2t) + …
上式において、x_1は1つ目の説明変数(SepalLength)、x_2は2つ目の説明変数(SepalWidth)、x_3は3つ目、、、という風に対応しており、SepalLength の値に差があると0点に差が出る、SepalWidth とPetalLengthの値に差があると、基本周期の振幅や位相に差が出る、PetalWidthの値に差があると、2倍周期の振幅に差が出る、、、という具合に、多変量の違いを可視化できる手法であることが分かります。振幅に値を使うということで正規化が推奨されます。
正規化の処理を組み込んでもう一度描画してみます。
from sklearn.preprocessing import MaxAbsScaler df_iris_normal = df_iris.copy() df_iris_normal.loc[:, :'PetalWidth'] = MaxAbsScaler().fit_transform(df_iris_normal.loc[:, :'PetalWidth']) andrews_curves(df_iris_normal, "Name")
規化前と比べて、周波数2倍の成分(PetalWidth)の影響もよく見えるようになりました。このグラフでは要因の追求までは難しそう(どの周波数にどの説明変数が対応しているかを把握しておく必要があるため)ですが、この説明変数で分類できそうか?というのを見るときに有効な可視化手法といえそうです。
autocorrelation_plot
autocorrelationは自己相関という意味で、主に時系列データの周期性を確認するときに用いる可視化方法です。
https://ja.wikipedia.org/wiki/自己相関
とりあえずまずは描画してみます。最初の引数にシリーズを指定する必要があります。
autocorrelation_plot(df_sin)
縦軸が相関係数、横軸がLag(時間ずれ)を表していることが分かります。フーリエ変換よりもお手軽に周期性をチェックしたいときに使える可視化方法と言えそうです。
Pandasのドキュメントは見あたらなかったのですが、ソースコードを抜粋して見ると以下のようになっており、x軸にhを取り、最初からhまでのデータと最後からhまでのデータの共分散を計算して(h/n)倍した上で、データの分散で規格化しているようです。(h/n)倍するため 、完全な繰り返し波形でも値は1にならず減衰していくことは知っておいたほうがよさそうです。
灰色の線は1.959963984540054と2.5758293035489004と正規分布の95%ライン、99%ラインを示していそうですが、それと自己相関にどういう関係があるかは理解できませんでした。ご存知の方がいたら教えてください。
pandas\plotting\_misc.pydef r(h): return ((data[:n - h] - mean) * (data[h:] - mean)).sum() / float(n) / c0 x = np.arange(n) + 1 y = lmap(r, x) z95 = 1.959963984540054 z99 = 2.5758293035489004 ax.axhline(y=z99 / np.sqrt(n), linestyle='--', color='grey') ax.axhline(y=z95 / np.sqrt(n), color='grey') ax.axhline(y=0.0, color='black') ax.axhline(y=-z95 / np.sqrt(n), color='grey') ax.axhline(y=-z99 / np.sqrt(n), linestyle='--', color='grey') ax.set_xlabel("Lag") ax.set_ylabel("Autocorrelation") ax.plot(x, y, **kwds)
bootstrap_plot
bootstrap_plotは、ドキュメントを見てもあまりはっきりしたことは書いていないのですが、ソールコードを見ると、Series, size(デフォルト50), samples(デフォルト500)を引数に与え、Seriesからsizeの数だけデータを抽出するのをsamples回繰り返し、各sampleの平均や、中央値、(最大-最小)÷2を可視化するメソッドのようです。まずは試してみましょう。
fig = bootstrap_plot(df.loc[:, "SepalLength"], size=50, samples=500)
これを見ると、irisのSepalLengthから50点のデータを選んで平均等を500回評価すると、平均(Mean)の最頻値は5.85程度で、最小で5.5程度、最大は6.1程度であることを読み取ることができます。中央値や (最大-最小)÷2 についてもそれぞれ確認できます。
本プロットを使うと、交差検証をした際の各データの塊の平均等がとれだけ安定するか(内部共変量シフトがあるかどうか)を確認することができそうです。具体的には、サンプル数を減らすと平均等のばらつきが大きくなると考えられるので、ばらつきが大きくなり過ぎないサンプル数を把握すれば、そこから適切な交差検証の分割数を検討できるというイメージです。
lag_plot
lag_plotは、Seriesとlagを指定すると、lagだけずらした散布図を作成してくれるメソッドです。まずは試してみます。
lag_plot(df_sin, lag=50)
横軸にSeriesの値、縦軸にlagだけ時間をずらしたSeriesの値を取り、散布図が作成されています。これは分かりやすく説明は不要ですね。
parallel_coordinates
parallel_coordinates(及び後述のradviz)はパターン分類の多変量解析でよく用いられる可視化方法と言えます。 使うためには、最初の引数にデータフレームを、2番目の引数にパターンの列を指定する必要があります。
parallel_coordinates(df_iris, 'Name')
上記グラフにおいては、各データ項目が横軸に並び、1本1本の線が1行1行のデータ(色はName)を表しています。これを使うことで、多変量の可視化も比較的容易にできますので私はよく使っています。本グラフは標準化しておいたほうが汎用的に使うことができます。
from sklearn.preprocessing import StandardScaler df_iris_normal = df_iris.copy() df_iris_normal.loc[:, :'PetalWidth'] = StandardScaler().fit_transform(df_iris_normal.loc[:, :'PetalWidth']) parallel_coordinates(df_iris_normal, 'Name')
標準化することで、先ほどはあまり変化が見えなかったSepalWidthの効果もよく見えるようになりました。
radviz
radvizもparallel_coordinatesと同様、パターン分類の多変量解析でよく用いられる可視化方法と言えます。 使うためには、最初の引数にデータフレームを、2番目の引数にパターンの列を指定する必要があります。
radviz(df_iris, 'Name')
きちんと調べたわけではないのですが、各説明変数ごとに値をベクトル化し、合成した値をプロットしているものと考えられます。このプロットは分かりやすい反面、PetalLengthとSepalLengthのベクトルが同じだと打ち消しあって同じところにプロットされてしまうという問題もありますので注意が必要です。
scatter_matrix
scatter_matrixは全変数の組み合わせで散布図やヒストグラムを作成してくれるメソッドです。seabornのpairplotのほうがhueで指定した列で色分けすることもできるためより便利かと思いますが、import seabornをしなくても使える点はメリットといえるかもしれません。
fig = scatter_matrix(df_iris)
まとめ
PandasのPlottingにあるグラフ描画をするための全メソッドを試して効果を検証してみました。 多変量や時系列に向いた可視化メソッドが多く含まれており、これらの機能も活用していきたいです。
非常に重宝しています。いつも利用させていただいています。
どうもありがとうございます!励みになります。
pandasのplotファンクションは簡易な記載で描画できるので自分も重宝してます。
RadViz、ちょっと惜しいですよね。私も理解するまでに時間かかりました。。。
コメントありがとうございます!私はとりあえず書かせて傾向を見るなら、この中ではparallel_coordinatesが一番分かり易いかな、という印象です。RadVizは特徴量のバランスを見るときに使っています。