Python 実践 データ加工/可視化 100本ノック に挑戦 ノック85 

ノック85 : データの分布をみてスケーリング手法を考えよう

 

スケーリングとは、異なる範囲にあるデータを同じ範囲に統一する作業のことです。

データの扱い方によっては、スケールの大きなデータに引っ張られて、スケールの小さなデータの特長が結果に反映されにくくなります。小さな値の特長も機械学習に反映させるため、大きいデータを小さな値にスケーリングする処理が必要となります。

まず、describeで基本データを確認します。

 

import seaborn as sns
from sklearn.model_selection import train_test_split
import pandas as pd

dataset = sns.load_dataset('titanic')
label = dataset.pop('survived')

train_ds,test_ds,train_label,test_label=train_test_split(
    dataset,label,random_state=2021,stratify=label)

train_ds.drop(columns=['embark_town','alive'],inplace=True)

one_hot_encoded = pd.get_dummies(train_ds)
one_hot_encoded = pd.get_dummies(one_hot_encoded,columns=['pclass'])
train_ds = one_hot_encoded
#ノック84
q = train_ds.quantile([1/4,3/4])
q1,q3 = q.loc[1/4],q.loc[3/4]
iqr=q3-q1
mx = q3+1.5*iqr
mn = q1-1.5*iqr

#ノック85
print(train_ds.describe())

 

実行結果

              age       sibsp       parch        fare  sex_female    sex_male  embarked_C  ...     
count  531.000000  668.000000  668.000000  668.000000  668.000000  668.000000   668.00000  ...  
mean    29.694124    0.546407    0.390719   32.485822    0.353293    0.646707     0.19012  ...    
std     14.569037    1.153550    0.807594   49.198142    0.478351    0.478351     0.39269  ...    
min      0.750000    0.000000    0.000000    0.000000    0.000000    0.000000     0.00000  ...    
25%     20.250000    0.000000    0.000000    7.925000    0.000000    0.000000     0.00000  ...    
50%     28.000000    0.000000    0.000000   15.047900    0.000000    1.000000     0.00000  ...   
75%     39.000000    1.000000    0.000000   31.000000    1.000000    1.000000     0.00000  ...   
max     80.000000    8.000000    6.000000  512.329200    1.000000    1.000000     1.00000  ...  

 

age(年齢) 、sibsp(タイタニックに乗船している兄弟/配偶者の数) 、parch(タイタニックに乗船している親/子供の数) 、fare(料金)

について分布の違いを見てみます。

 

import matplotlib.pyplot as plt
fig,axes = plt.subplots(ncols=4,figsize=(15,5))
axes[0].hist(train_ds.age)
axes[1].hist(train_ds.sibsp)
axes[2].hist(train_ds.parch)
axes[3].hist(train_ds.fare)
plt.show()

 

 

データの違い

 

次にageについてカイ二乗検定を行います。

from scipy import stats
import numpy as np
bins,bin_edges = np.histogram(train_ds.age.dropna(),bins="auto")
stat,p = stats.chisquare(bins)
print(p)

 

実行結果

3.4564391399825767e-66

 

カイ2乗検定は集まったデータの当てはまり具合を確認する方法です。

あらかじめ有意水準値を設定し、カイ2乗検定から求めたP値の値が優位水準であれば、いいデータが集められているといえます。

今回は優位水準を0.05とします。値は0.05より小さい値のため、一様分布に当てはまらないことがわかります。(確率通りにデータが分布できていない)

 

次に正規分布かどうかを判断します。

正規分布とは以下のように山形になっているような分布図図のことをさします。

 

正規分布図(wikipedia参照)

 

正規分布図判定はstats.shaprioで求められます。

stat,p = stats.shapiro(bins)
print(p)

 

実行結果

0.07798287272453308

 

この値は0.05より大きいのでageのデータは正規分布であることがわかります。

 

sibsp、parch、fareについても同様に確認してみます。

※本は304ページ目ですが、図7-18:sidspと「b」が「d」の誤字があります。

 

bins,bin_edges = np.histogram(train_ds.sibsp.dropna(),bins="auto")
stat,p = stats.chisquare(bins)
print(p)
stat,p = stats.shapiro(bins)
print(p)

bins,bin_edges = np.histogram(train_ds.parch.dropna(),bins="auto")
stat,p = stats.chisquare(bins)
print(p)
stat,p = stats.shapiro(bins)
print(p)

bins,bin_edges = np.histogram(train_ds.fare.dropna(),bins="auto")
stat,p = stats.chisquare(bins)
print(p)
stat,p = stats.shapiro(bins)
print(p)

 

 

実行結果

実行結果は以下となり、sibsp parch fareどのデータも一様分布でなく、正規分布でもないことが確認できました。

 

0.0
3.933027081098883e-12
0.0
7.424870887007273e-07
0.0
5.63639770794382e-20

 

 

 

/* -----codeの行番号----- */