Edited at

機械学習の理論Python編 #3 Unit 2: 回帰の準備のための探索的データ解析(1) [MOOC/edX]

More than 1 year has passed since last update.

edXの「Principles of Machine Learning: Python Edition(機械学習の理論 Python編)」をまとめています。

前回の記事←→次回の記事

回帰(Regression)の解析をするための準備段階にやるべきことを学びます。


1. データの探索

機械学習を実行する準備として、データの中身やデータ同士の関係を理解するために必要な手順。


知るべきこと


  • 特徴点 - サイズ、データ型など

  • 統計的な要約 - 平均値、SD、中央値、分位点、など

  • 誤差と外れ値

  • (数値データのとき)分布

  • (カテゴリカルデータのとき)度数

  • 特徴点とラベル同士の関係 - 相関が高い特徴同士はないか、など

これらを調べつつ、誤差を修正したら再度可視化し直したりなど、手順を何回も何回も行ったり来たりして繰り返す。なので「探索」。


2. データの可視化


  • 1次元データの可視化手法


    • (数値データのとき)分布

    • (カテゴリカルデータのとき)度数




  • 2次元データの可視化手法


    • 通常の数値プロット

    • カテゴリカルデータと数値データの組み合わせ(Excelでよく使う棒グラフとか)


    • データが何次元もあるときは?



      • Aesthetics


        • Position (カテゴリカルデータ、数値データに使える)

        • Length (カテゴリカルデータ、数値データに使える)

        • Shape (カテゴリカルデータに使える)

        • Size (数値データに使える)

        • Color (カテゴリカルデータ、(彩度で)数値データに使える)



      • 多次元で表現


        • 多次元プロット

        • 多次元にプロットする代わりに一部の変数同士の関係を見る(Conditioned, Faceted, Small multiple plotsなど名前色々あるがアイデアは同じ、詳しくはこちらが参考になる)








実践1: 自動車データを探索的に見てみる

講座#1で環境構築したJupyter NotebookのVisualizingDataForRegression.ipynbで実践します。コメントを加えたりなどしたソースコード全文はこちらのModule2>VisualizingDataForRegression.ipynbにあるので、この記事では抜粋を載せます。

データセットはこんな感じ。

Screen Shot 2018-10-23 at 10.40.49.png


1) 棒グラフ ← カテゴリカルデータと数値データの関係

ex.) 企業ごとの売り上げ(下のコードで表示されるグラフのうちの一つ)

IMG_0033.PNG


棒グラフ

#auto_pricesはデータセット、colsはauto_pricesのラベルだけ取り出したやつ

def plot_bars(auto_prices, cols):

for col in cols:
fig = plt.figure(figsize=(6,6)) # define plot area
ax = fig.gca() # define axis
counts = auto_prices[col].value_counts() # find the counts for each unique category
counts.plot.bar(ax = ax, color = 'blue') # Use the plot.bar method on the counts data frame
ax.set_title('Number of autos by' + col) # Give the plot a main title
ax.set_xlabel(col) # Set text for the x axis
ax.set_ylabel('Number of autos')# Set text for y axis
plt.show()

plot_cols = ['make', 'body_style', 'num_of_cylinders']
plot_bars(auto_prices, plot_cols)



2) ヒストグラム、カーネル密度推定関数、その組み合わせ ← 数値データ

ex.) エンジンの大きさ


ヒストグラム

Screen Shot 2018-10-23 at 11.08.04.png


ヒストグラム

# binsは、ヒストグラムの区分。値を大きくすればより細かく分割される

def plot_histogram(auto_prices, cols, bins = 10):
for col in cols:
fig = plt.figure(figsize=(6,6)) # define plot area
ax = fig.gca() # define axis
auto_prices[col].plot.hist(ax = ax, bins = bins) # Use the plot.hist method on subset of the data frame
ax.set_title('Histogram of ' + col) # Give the plot a main title
ax.set_xlabel(col) # Set text for the x axis
ax.set_ylabel('Number of autos')# Set text for y axis
plt.show()

num_cols = ['curb_weight', 'engine_size', 'city_mpg', 'price']
plot_histogram(auto_prices, num_cols)



カーネル密度推定プロット(Kernel Density Estimate Plots, KDE)

Screen Shot 2018-10-23 at 11.08.13.png


KDE

# ヒストグラムとの違いは、引数にhist = Falseがあるのと、distplot()がある

def plot_density_hist(auto_prices, cols, bins = 10, hist = False):
for col in cols:
sns.set_style("whitegrid")
sns.distplot(auto_prices[col], bins = bins, rug=True, hist = hist) # rugはデータ点のx軸での位置を表示する
plt.title('Histogram of ' + col) # Give the plot a main title
plt.xlabel(col) # Set text for the x axis
plt.ylabel('Number of autos')# Set text for y axis
plt.show()

plot_density_hist(auto_prices, num_cols)


ヒストグラムとカーネル密度推定プロットを合わせることもできる。

Screen Shot 2018-10-23 at 11.11.11.png


ヒストグラムとKDE

plot_density_hist(auto_prices, num_cols, bins = 20, hist = True)        



3) 散布図 ← 数値データどうしの関係

Screen Shot 2018-10-23 at 11.12.14.png

価格とエンジンの重さの関係として分かることは、「概ね比例関係にあるが、エンジンがめちゃ小さい車とめちゃ大きい車は傾向に乗らない」。→ こういうのが、何故なのか調査するポイント。


散布図

def plot_scatter(auto_prices, cols, col_y = 'price'):

for col in cols:
fig = plt.figure(figsize=(7,6)) # define plot area
ax = fig.gca() # define axis
auto_prices.plot.scatter(x = col, y = col_y, ax = ax)
ax.set_title('Scatter plot of ' + col_y + ' vs. ' + col) # Give the plot a main title
ax.set_xlabel(col) # Set text for the x axis
ax.set_ylabel(col_y
)# Set text for y axis
plt.show()

num_cols = ['curb_weight', 'engine_size', 'horsepower', 'city_mpg']
plot_scatter(auto_prices, num_cols)


ただこれだと点が重なってしまってて、密集してる具合がよく分からない → alphaを調整することで、密集してるポイントが分かりやすくなる。

Screen Shot 2018-10-23 at 11.12.24.png


alphaで見やすくした散布図

def plot_scatter_t(auto_prices, cols, col_y = 'price', alpha = 1.0):

for col in cols:
fig = plt.figure(figsize=(7,6)) # define plot area
ax = fig.gca() # define axis
auto_prices.plot.scatter(x = col, y = col_y, ax = ax, alpha = alpha)
ax.set_title('Scatter plot of ' + col_y + ' vs. ' + col) # Give the plot a main title
ax.set_xlabel(col) # Set text for the x axis
ax.set_ylabel(col_y)# Set text for y axis
plt.show()

plot_scatter_t(auto_prices, num_cols, alpha = 0.2) # 0.2の透明具合で描画。1.0だと全然透明じゃない、0.1だとめっちゃ透明。


ただし、データ数が100000個とか多くなったら、全てをプロットするのは大変。なので、密度関数が使える。よく使われるのは、カーネル密度推定(KDE, Kernel Density Estimate plot)。

download.png

download (1).png


KDEと散布図の組み合わせ

def plot_desity_2d(auto_prices, cols, col_y = 'price', kind ='kde'):

for col in cols:
sns.set_style("whitegrid")
sns.jointplot(col, col_y, data=auto_prices, kind=kind)
plt.xlabel(col) # Set text for the x axis
plt.ylabel(col_y)# Set text for y axis
plt.show()

plot_desity_2d(auto_prices, num_cols) # 追加で何も指定しないと等高線っぽい描画
plot_desity_2d(auto_prices, num_cols, kind = 'hex') # 追加でkindを六角形にしてみる



4) 箱ひげ図 ← カテゴリカルデータと数値データの関係

Screen Shot 2018-10-23 at 11.19.36.png

gas車はdiesel車1に比べて安いが、ある一定の高価な層もある(四分位範囲から外れた外れ値)。分布がかぶっているところに注目すると、gas車のほとんどがdieselの半分(=中央値)以下で,gas車の半分(=中央値)はdiesel車の1/4(=1/4四分位)以下。


箱ひげ図

def plot_box(auto_prices, cols, col_y = 'price'):

for col in cols:
sns.set_style("whitegrid")
sns.boxplot(col, col_y, data=auto_prices)
plt.xlabel(col) # Set text for the x axis
plt.ylabel(col_y)# Set text for y axis
plt.show()

cat_cols = ['fuel_type', 'aspiration', 'num_of_doors', 'body_style',
'drive_wheels', 'engine_location', 'engine_type', 'num_of_cylinders']
plot_box(auto_prices, cat_cols)


cf.) バイオリンプロット

箱ひげ図が中に含まれてるカーネル密度プロット。外れ値はない代わりに、バイオリン的なのの形が変わるのでそれで分布を把握する。

Screen Shot 2018-10-23 at 11.20.05.png


バイオリンプロット

def plot_violin(auto_prices, cols, col_y = 'price'):

for col in cols:
sns.set_style("whitegrid")
sns.violinplot(col, col_y, data=auto_prices)
plt.xlabel(col) # Set text for the x axis
plt.ylabel(col_y)# Set text for y axis
plt.show()

plot_violin(auto_prices, cat_cols)



実践2: Aestheticsを使って高次元のデータを可視化してみる

先ほどの自動車の例での可視化は2次元の情報しか表せないので、Aesthetics(色とか大きさとか)を加味した可視化について考えてみる。次回!


今後の予定

随時記事のリンク追加予定


その他(いつか)まとめる予定の他の講座の記事一覧





  1. 車のエンジンの一種。