はじめての探索的データ解析に挑戦
Pandasを使って探索的データ解析を簡単に行う方法を紹介します。データを読み込み、データを俯瞰した後、変数を探索してmatplotlibのグラフを描きます。
Pandasはデータの加工や探索的データ解析のためのすぐれたツールです。Pandasはあらゆる種類のフォーマット(テキストやバイナリのファイル)を読み込み、テーブルとして例えばグループごとに集計を行うなどさまざまな操作ができます。
準備
Pythonによるデータ解析を進める環境としてJupyter Notebookを使います。導入方法や基本的な使用方法は連載の第1回記事本格的なPythonデータ解析環境を手軽に!「Jupyter Notebook」の導入から可視化までを参照してください。
今回は対象のデータとして、テニス(ATP:男子プロテニス協会)の2017年の試合データを用います。
これにはテニスの試合に関するさまざまなデータが含まれます。例えば試合が行われたコートの種類・試合時間といった属性データ、また勝者と敗者それぞれのポイント獲得数やエース・ダブルフォルトの数といった集計データです。
データソースとしては以下のクリエイティブ・コモンズのライセンスで公開されているデータを使います。
試合においてテニスプレーヤーは「勝つため」にプレーしています。勝敗が決まるまでのプロセスである試合内容のデータを用いて、どの項目がどの程度勝敗に関係しているのかを分析します。
結論
先に、今回のデータ解析によって得られる結論をコードとグラフで見てみましょう。
#ライブラリをインポートする
from datetime import datetime
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline
#データをロードする
df_raw = pd.read_csv('https://github.com/JeffSackmann/tennis_atp/blob/master/'
'atp_matches_2017.csv?raw=true')
#データを加工する
player = 'Kei Nishikori'
df = df_raw[(df_raw['winner_name'] == player) | ( df_raw['loser_name'] == player)]
df['win'] = df['winner_name'] == player
df['2ndwon'] = df['win']*(df['w_2ndWon'])/(df['w_1stWon']) + ~df['win']*(df['l_2ndWon'])/(df['w_1stWon'])
date = pd.to_datetime(df['tourney_date'], format = '%Y%m%d')
df['date'] = date
gb = df.groupby('tourney_date')
#データを可視化する
fig, ax = plt.subplots(1, 1)
ax.plot_date(date.astype(datetime), df['2ndwon'],
alpha=.25, lw=0)
ax.plot_date(gb['date'].max().astype(datetime),
gb['2ndwon'].mean(), '-', lw=3)
ax2 = ax.twinx()
ax2.plot_date(gb['date'].max().astype(datetime),
gb['win'].mean(), '-', lw=3)
ax.set_xlabel('date')
ax.set_ylabel('2ndwon per minutes')
結果として下記の可視化ができます。オレンジの折れ線がダブルフォルトの割合の遷移、青の線が勝率の遷移です。セカンドサービスからの得点の割合と勝率の関係を表しており、相関が確認できます。
結果だけを見てみても、どういった経緯でこの結論に至ったか分かりにくいと思います。
探索的データ解析のプロセスを追っていくことで、これを理解できるようにしたいと思います。
ライブラリの導入とデータロード
まず必要なライブラリをインポートします。Numpy、pandas、matplotlibと今回はdatetimeをインポートします。
from datetime import datetime import numpy as np import pandas as pd import matplotlib.pyplot as plt %matplotlib inline
データセットはCSV形式(カンマ区切りのテキストファイル)です。pandasのDataFrameで行列/テーブルのように扱えれば解析がしやすくなります。
DataFrameとして読み込むには、read_csv関数を呼び出します。
df_raw = pd.read_csv('https://github.com/JeffSackmann/tennis_atp/blob/master/'
'atp_matches_2017.csv?raw=true')
これでデータフレームのdf_rawにデータが格納されました。
データ全体の概観を確認する
ではJupyter notebookで表示します。headメソッドを使うと最初の数行を確認できます。このメソッドを使ってデータセットを概観してみましょう。
df_raw.head()
同様にtail()メソッドは、最後の数行を表示します。引数には行数を指定できます。
df_raw.tail(3)
- surface : コートのタイプ(芝、クレーなど)
- tourney_date : トーナメントの開始日
- winner_name : 勝者の名前
- winner_ht : 勝者の身長(cm)
- w_df : 勝者のダブルフォルト数
- w_1stWon : 勝者のファーストサーブからの得点数
- w_2ndWon : 勝者のセカンドサーブからの得点数
- minutes : 試合の長さ(分)
df_raw.describe()
統計項目としていくつかのデータがでてきました。統計の対象はデータ型が数値のもの(intやfloat)になります。左端には項目が表示されており、それぞれ下記の意味になります。
| 項目 | 意味 |
|---|---|
| count | 行数(要素の数) |
| mean | 平均 |
| std | 標準偏差 |
| min | 最小値 |
| 25% | 1/4分位数 |
| 50% | 中央値 |
| 75% | 3/4分位数 |
| max | 最大値 |
例えばwinner_ht(勝者の身長)に注目してみます。mean、min、maxはそれぞれ186.367409、163、208なので、勝者の身長は「163cm~208cmで平均は約186cm」と分かります。
