こんにちは、データ分析部でバイトをしている子田(id:woody_kawagoe)です。
ニュースパスのログを集計して分析するといった業務を行っています。Gunosyで分析に利用しているツールとしては主にJupyter, Pandas, matplotlibがあります。 この組み合わせは非常に相性が良く、研究でも役立つと思います。 そこで今回のブログではデータ分析に役立つtipsや学んだことをまとめます。
Jupyter
ブラウザ上で利用できる開発環境です。 対話型で、作成したスクリプトと出力結果の対応関係が非常に見やすいです。 スクリプトでprint文をかかなくても最終行に変数おけば表示してくれます。 またgithub上にJupyterで作成できるipynbファイルを置くと他のユーザからでもJupyterと同様のUIで確認出来ます。 そのためipynbファイルをそのまま解析結果の資料として職場が学校で報告することが可能です。
これは僕がJupyterで作成したコードです。 データ分析ではなく自然言語処理100本ノックの第1章の解答ですが、出力結果と合わせて見ることができて見やすいかと思います。
またvimを使う人にとっても親切なことに、Jupyter上でvimが使える拡張機能が公開されています。 以下のリンクを参考に設定してみてください。
Pandas
Python Data Analysis Library — pandas: Python Data Analysis Library
pythonで利用できるデータ分析用ライブラリです。 表形式のデータをSQLやRのように操作し、高速で処理できて便利です。
Pandasで扱うデータ型としてDataFrameとSeriesがあります。 DataFrameは複数の列を持ち、Seriesは1列のみのデータ型です。 DataFrameから1列を抽出した場合も勝手にSeriesになります。 この2つの型で使用できるメソッドが異なる場合があるので注意が必要です。
以下、pythonの対話モードでの実行例です。
>>> import pandas as pd >>> df = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD')) >>> df ''' A B C D 0 0.563617 2.232149 0.246438 -1.582011 1 -0.865735 -0.092077 -1.117475 -0.832390 2 0.464084 -0.713113 -0.859806 1.683599 3 -0.569110 -0.343353 -0.054545 0.380017 4 0.232089 1.577586 -0.550634 1.990078 5 0.436252 -0.293231 -0.033918 0.738073 ''' >>> type(df) ''' <class 'pandas.core.frame.DataFrame'> ''' >>> df.A ''' 0 0.563617 1 -0.865735 2 0.464084 3 -0.569110 4 0.232089 5 0.436252 ''' >>> type(df.A) ''' <class 'pandas.core.series.Series'> '''
例えばvalue_counts()というユニークな値の個数をカウントするというメソッドがあります。 よく利用されるメソッドですが、Seriesのみでしか使えません。
df['E'] = ['one', 'one','two','three','four','three'] >>> df ''' A B C D E 0 0.563617 2.232149 0.246438 -1.582011 one 1 -0.865735 -0.092077 -1.117475 -0.832390 one 2 0.464084 -0.713113 -0.859806 1.683599 two 3 -0.569110 -0.343353 -0.054545 0.380017 three 4 0.232089 1.577586 -0.550634 1.990078 four 5 0.436252 -0.293231 -0.033918 0.738073 three ''' >>> df.E.value_counts() ''' three 2 one 2 four 1 two 1 Name: E, dtype: int64 ''' >>> df.value_counts() ''' (中略) AttributeError: 'DataFrame' object has no attribute 'value_counts' '''
よく使うメソッドとしてgroupby()があります。これはSQLのGROUPBY文に似ています。 ユニークにしたいカラム(複数でも可)を指定し、その後に集計関数(sum(),max()など)をつけると他カラムの集計結果を返します。
>>> df.groupby('E').sum() ''' A B C D E four 0.232089 1.577586 -0.550634 1.990078 one -0.302118 2.140072 -0.871037 -2.414401 three -0.132858 -0.636584 -0.088463 1.118090 two 0.464084 -0.713113 -0.859806 1.683599 ''' >>> df.groupby('E').max() ''' A B C D E four 0.232089 1.577586 -0.550634 1.990078 one 0.563617 2.232149 0.246438 -0.832390 three 0.436252 -0.293231 -0.033918 0.738073 two 0.464084 -0.713113 -0.859806 1.683599 '''
またDataFrameは自分で中身を作らなくてもread_csv()でCSVファイルを読み込んだり、 read_sql_query()を使ってSQLをDBに送って作成することもできます。
matplotlab
matplotlib: python plotting — Matplotlib 1.5.3 documentation
pythonのデータ可視化ライブラリです。
PandasのDataFrameを元にプロットができ、出力したグラフはそのままJupyter上に表示されます。
最低plot()
をDataFrame型かSeries型につければグラフの表示が出来ます。
以下、Jupyter上での実装例です。
import pandas as pd import numpy as np import matplotlib.pyplot as plt %pylab inline --no-import-all ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000)) ts = ts.cumsum() # 各要素に直前のデータと合計した値を格納する、つまり累計する ts.plot()
スタイルをggplotにしておく良い感じの見た目になります。
plt.style.use('ggplot') ts.plot()
plot内のオプションを変更することでグラフの設定を変更できます。 試しにヒストグラムを表示してみます。
ts.plot(kind='hist')
データ分析の基本的な流れ
データ分析の基本的な流れは以下のような形になります。
1. SQLを飛ばしてデータを取得
2. Pandasでガチャガチャいじる
3. matplotlibでグラフ出力
それぞれの処理について詳しく説明します。
1.SQLを飛ばしてデータを取得
まずPandasのread_sql_query()を使ってDBから大まかなデータを集計してDataFrameを作ります。 Pandasをほとんど使わなくてもSQLで十分データを整形できるというパターンもあるかもしれませんが、 一回クエリを送って取得したデータを繰り返し使うということが多いです。 理由としては何度もクエリを送ると時間がかかってしまったり、 DBに負荷を与えてしまう可能性があるためです。 余談ですが僕は上司に「重いクエリ投げたら(そのクエリを)すぐ殺すから安心して」と言われて一瞬ビビったことがあります。 SQLとPandasのどちらに力をいれるかはケースバイケースですが、 データサイズが大きい程クエリの回数は少なくすべきかと思います。 解析対象がCSVファイルの場合はread_csv()を使ってDataFrameを作ります。
2.Pandasでガチャガチャいじる
先ほどのDataFrameを様々な方法で整形します。 場合によってはそのまま表を結果として表示することもあります。 グラフ出力したい場合もここで中身を確認しつつ解析するのが良いと思います。
またSeries型をそのままJupyter上で出力するとテキストのみの表示になってしまうのですが、
pd.DataFrame(<Series型の変数>)
と無理矢理DataFrameに変えて出力すると表形式で表示されて見やすいです。
3.matplotlibでグラフ出力
整形したDataFrameをグラフにします。
ただ全体をプロットしてもいいですが、特徴的な部分をplt.xlim()
やplt.ylim()
で範囲指定した方が見やすい場合もあります。
他にもpltのメソッドで色々指定ができるので見やすく整形しましょう。
参考資料
Pythonによるデータ分析入門 https://www.amazon.co.jp/Pythonによるデータ分析入門-―NumPy、pandasを使ったデータ処理-Wes-McKinney/dp/4873116554www.amazon.co.jp
今回紹介したツールについて詳しく解説している本です。Pandasについて解説している書籍は少ないようで、Pandasを学びたい人に役立つ一冊となりそうです。
10 Minutes to pandas(英語) 10 Minutes to pandas — pandas 0.19.2 documentation
Pandasの公式サイトにある解説ページです。たぶん10分じゃ終わらないと思いますが、役立つ機能が1ページにまとまっていてわかりやすいです。