人間の身長・体重を集めたデータセットの中で最も有名なデータセットの1つにDavisというデータセットがあります。
しばしば機械学習や統計学の教科書、さらには論文などの多く登場するため、目にしたことがある人も多いのではないでしょうか。
かくいう私もDavisデータセットを扱う機会が多く、その度に毎回ダウンロードして加工して、というのが面倒になってきたので、Davisデータセットを入手して、簡単に可視化するまでの流れを記事にまとめます。
- Davisデータセットの解説
- Davisデータセットを簡単に用意する方法
- Pythonを用いてDavisデータセットの可視化
Davisデータセットの解説
Davisデータセットは、200人分の身長と体重が記録されたデータセットです。データは5系列あり、性別、身長、体重、また自己申告した身長、体重になります。
Davisは統計学のプログラミングツールであるRに含まれているデータセットのため、元データはこちらのURLから取得することができます。
https://vincentarelbundock.github.io/Rdatasets/datasets.html
PythonでDavisデータセットを用意する
では、早速DavisデータセットをPythonで扱ってみます。
まず最初に必要なライブラリをインポートします。
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
続いて、Davisデータセットをダウンロードします。CSVファイルがインターネット上に落ちているため、pandas経由でダウンロードして扱います。
今回は、体重と身長のデータだけ扱うことにします。
df = pd.read_csv('https://vincentarelbundock.github.io/Rdatasets/csv/carData/Davis.csv', index_col=False)
df = df[['weight', 'height']]
df
このようなデータを得ることができました。200人分の体重(weight)、身長(height)のデータがあることがわかります。
PythobでDavisデータセットを可視化
データ数が200もあるので、データセットを可視化してみます。
まず、ヒストグラムで体重・身長ごとにデータの分布を見てみます。
data = df.to_numpy() # DataFrameをリストに変換
fig, ax = plt.subplots(1, 2, dpi=80, figsize=(10,5))
ax[0].set_title("Weight")
ax[0].hist(data[:, 0], color="green")
ax[1].set_title("Height")
ax[1].hist(data[:, 1], color="red")
このような分布になることがわかりました。体重・身長ともに、外れ値があることがわかります。
続いて、散布図を書いて、身長体重の相関やデータの分布を確認してみます。
fig, ax = plt.subplots(dpi=100, figsize=(5,5))
ax.set_facecolor('w')
ax.set_xlabel('weight')
ax.set_ylabel('height')
ax.set_aspect('equal')
ax.set_xlim(40, 200)
ax.set_ylim(40, 200)
ax.scatter(data[:, 0], data[:, 1], s=10, marker="o", facecolor='#35966e')
plt.grid(color='gray', linestyle='dotted', linewidth=1)
plt.show()
散布図として可視化することができました。
右下を見てみると外れ値があることがわかります。実際Davisのデータセットでは、体重と身長を逆に取り違えたデータが1つ含まれていることがわかっており、その点がこの右下の1点になります。
また散布図を描くことで、体重と身長に相関があることがわかり、体重が重いほど身長も大きいというデータの傾向を見ることができます。
Davisデータセットで外れ値を除く
扱いたい処理によっては、Davisデータセットの外れ値を取り除きたいことがあるかと思います。
その時は、下記のようなmaskを用意することで、外れ値をデータセットから取り除けます。
mask = ((df['weight'] < 140) & (df['height'] > 120)) # 正常なデータの範囲を指定することで外れ値を除外
df = df[mask]
data = df.to_numpy()
fig, ax = plt.subplots(dpi=100, figsize=(5,5))
ax.set_facecolor('w')
ax.set_xlabel('weight')
ax.set_ylabel('height')
ax.set_aspect('equal')
ax.scatter(data[:, 0], data[:, 1], s=10, marker="o", facecolor='#35966e')
plt.grid(color='gray', linestyle='dotted', linewidth=1)
plt.show()
このように、外れ値を排除した散布図を得ることができました。