前回の記事ではタイタニックのデータセットの欠損値処理をまとめていました。
今回は 2. 外れ値処理 (outlier processing)の作業をしようと思います。
外れ値処理に関してはKaggleの下記コードが参考になりました。
https://www.kaggle.com/code/nareshbhat/outlier-the-silent-killer
https://www.kaggle.com/code/aimack/how-to-handle-outliers
外れ値かどうかを判断するため、外れ値の検定を試してみた記事もあります。
それでは、外れ値の処理をしていきたいと思います。
タイタニックのデータセットの読み込み
import pandas as pd
import numpy as np
# タイタニックデータセットの訓練データを読み込み
df = pd.read_csv("/Users/hinomaruc/Desktop/notebooks/titanic/train.csv")
正規性の確認
外れ値の検定に利用するSmirnov‐Grubbs TestやGeneralized Extreme Studentized Deviate (ESD) Testはおおよそ正規分布を仮定しているので、まずは各変数が正規分布に従っているか確認をしようと思います。
詳細はPythonで外れ値の検定を2種類試してみたに記載していますが、QQプロットというグラフを確認して正規分布に従っていそうか確認しようと思います。
せっかくなので正規性の検定の実行手順についてでも紹介されている正規性の検定も試してみようと思います。
下記2つのテストがあるようです。
・Kolmogorov-Smirnov test
・Shapiro-Wilk test (少ないサンプルのときに使用。versionによるかもしれませんが、scipyだと5000サンプル以上だとwarningがでました。
QQプロットで正規分布に従っているかどうか確認
# 描画設定
import seaborn as sns
import matplotlib.pyplot as plt
sns.set_style("whitegrid")
from matplotlib import rcParams
rcParams['font.family'] = 'Hiragino Sans' # Macの場合
#rcParams['font.family'] = 'Meiryo' # Windowsの場合
#rcParams['font.family'] = 'VL PGothic' # Linuxの場合
rcParams['xtick.labelsize'] = 12 # x軸のラベルのフォントサイズ
rcParams['ytick.labelsize'] = 12 # y軸のラベルのフォントサイズ
rcParams['axes.labelsize'] = 18 # ラベルのフォントとサイズ
rcParams['figure.figsize'] = 18,8 # 画像サイズの変更(inch)
# 正規分布に従うかどうかをQQプロットを描画して確認
from scipy import stats
CHK_COLUMNS=[
"Survived"
, "Pclass"
, "Age"
, "SibSp"
, "Parch"
, "Fare"
]
for i in CHK_COLUMNS:
print(i)
stats.probplot(df[i].dropna(), dist="norm", plot=plt)
plt.show()
Survived
Pclass
Age
SibSp
Parch
Fare
QQプロットは直線にプロットが沿っていると正規分布に従っているという解釈になるようです。
Ageだけおおよそ正規分布に従っているようです。
Kolmogorov-Smirnov testとShapiro-Wilk testでも確認
Ageがおおよそ正規分布に従っていそうなので、正規性テストをしてみようと思います。
# 正規分布かどうかのテスト
# Kolmogorov–Smirnov test
# H0=分布が正規分布である
from scipy import stats
stats.kstest(df["Age"].dropna(),"norm")
KstestResult(statistic=0.9650366565902186, pvalue=0.0)
# Shapiro–Wilk test
# H0=分布が正規分布である
stats.shapiro(df["Age"].dropna())
ShapiroResult(statistic=0.9814548492431641, pvalue=7.322165629375377e-08)
pvalue > 0.05ではないので、正規性テストだと正規分布ではないと結果になりました。QQプロットで確認することが大切ということがわかります。
正規性の確認後の手順まとめ
正規分布だった場合の処理 (if Normal distribution)
TitanicのデータセットですとAgeカラムのみが対象ですが、下記手順で外れ値を発見していきます。
- Smirnov‐Grubbs Test や generalized ESD testで外れ値の検定をする
- もしくは、ロバストZスコアが±3.5の範囲を外れる値を外れ値と定義
grabb's testを使う
# Grubb's test (max one sided)
#H0: there are no outliers in the data
#Ha: the maximum value is an outlier
def grubbs_test_onesided_max(Y):
import numpy as np
import scipy.stats as stats
# Significance level
alpha = 0.05
# Calculate G
Ymean = np.mean(Y)
s = np.std(Y, ddof=1) # use sample std
max_val = np.max(Y)
G_calculated = (max_val - Ymean) / s
# critical value of the t distribution with N-2 degrees of freedom and a significance level of α/(N).
N = len(Y)
t = stats.t.ppf(1 - (alpha / N), N - 2)
G_critical = (N - 1) / np.sqrt(N) * np.sqrt(np.square(t) / ((N - 2) + np.square(t)))
print("max_val = ", max_val)
print("G_calculated = ", G_calculated)
print("G_critical = ", G_critical)
if G_calculated > G_critical:
print("G_calculated > G_criticalなので帰無仮説は棄却され", max_val ,"は外れ値である")
else:
print("G_calculated < G_criticalなので帰無仮説は棄却されず", max_val ,"は外れ値であるとは言えない")
grubbs_test_onesided_max(df["Age"].dropna().values)
max_val = 80.0 G_calculated = 3.4626986259776564 G_critical = 3.790080012280718 G_calculated < G_criticalなので帰無仮説は棄却されず 80.0 は外れ値であるとは言えない
generalized ESD testを使う
grubb's testよりgeneralized ESD testの方が複数の外れ値検定に使えるので適していそうです。
# Generalized ESD test (https://www.itl.nist.gov/div898/handbook/eda/section3/eda35h3.htm)
# H0: There are no outliers in the data set
# Ha: There are up to r outliers in the data set
# arguments Y:numpy.ndarray、r:iteration num
def generalized_esd_test(Y,r):
import numpy as np
import scipy.stats as stats
# deepcopyしておく
from copy import deepcopy
X = deepcopy(Y)
# maximum iteration num
r = r
# Significance level
alpha = 0.05
# sample size
N = len(X)
# Calculate G
for i in range(1, r + 1):
print("i = ",i)
Xmean = np.mean(X)
s = np.std(X, ddof=1) # use sample std
max_diviation = max(abs(X - Xmean))
max_diviation_idx = np.argmax(abs(X - Xmean))
possible_outlier = Y[max_diviation_idx]
# G calculatedを計算
G_calculated = max_diviation / s
print("possible_outlier = ",possible_outlier,"(idx = ",str(max_diviation_idx) + ")")
# critical value of the t distribution with N-i-1 degrees of freedom and a significance level of α/2(N-i+1).
t = stats.t.ppf(1 - (alpha / (2 * (N - i + 1))), N - i - 1)
print("N=",N - i + 1)
print("t=",t,"degree of freedom=",N - i - 1)
# G criticalを計算
G_critical = (N - i) * t / np.sqrt((N - i - 1 + np.square(t)) * (N - i + 1))
print("G_calculated = ", G_calculated)
print("G_critical = ", G_critical)
if G_calculated > G_critical:
print("G_calculated > G_criticalなので帰無仮説は棄却され外れ値は存在する *")
else:
print("G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない")
# 外れ値と思われる値を削除し再度検定をする
X = np.delete(X,max_diviation_idx,0)
print("\n")
generalized_esd_test(df["Age"].dropna().values,100)
i = 1 possible_outlier = 80.0 (idx = 498) N= 714 t= 3.999783237713572 degree of freedom= 712 G_calculated = 3.4626986259776564 G_critical = 3.9555939826790274 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 2 possible_outlier = 4.0 (idx = 678) N= 713 t= 3.999477386217029 degree of freedom= 711 G_calculated = 3.078404668802844 G_critical = 3.9552370525253457 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 3 possible_outlier = 71.0 (idx = 74) N= 712 t= 3.999171112061637 degree of freedom= 710 G_calculated = 2.891911703546862 G_critical = 3.9548795703056583 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 4 possible_outlier = 55.0 (idx = 392) N= 711 t= 3.9988644140998093 degree of freedom= 709 G_calculated = 2.9111378503318672 G_critical = 3.95452153436388 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 5 possible_outlier = 21.0 (idx = 90) N= 710 t= 3.9985572911789533 degree of freedom= 708 G_calculated = 2.8954853105989664 G_critical = 3.9541629430362133 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 6 possible_outlier = 25.0 (idx = 527) N= 709 t= 3.998249742141604 degree of freedom= 707 G_calculated = 2.8793800856041902 G_critical = 3.9538037946512676 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 7 possible_outlier = 35.0 (idx = 587) N= 708 t= 3.9979417658255585 degree of freedom= 706 G_calculated = 2.8984548012161757 G_critical = 3.953444087530165 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 8 possible_outlier = 66.0 (idx = 25) N= 707 t= 3.9976333610640142 degree of freedom= 705 G_calculated = 2.6313045639511925 G_critical = 3.953083819986654 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 9 possible_outlier = 29.0 (idx = 39) N= 706 t= 3.997324526685705 degree of freedom= 704 G_calculated = 2.5742351258054215 G_critical = 3.9527229903272274 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 10 possible_outlier = 63.0 (idx = 221) N= 705 t= 3.997015261514277 degree of freedom= 703 G_calculated = 2.5882679256657513 G_critical = 3.95236159685049 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 11 possible_outlier = 52.0 (idx = 361) N= 704 t= 3.996705564369187 degree of freedom= 702 G_calculated = 2.6025327956320043 G_critical = 3.951999637848016 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 12 possible_outlier = 17.0 (idx = 346) N= 703 t= 3.996395434062812 degree of freedom= 701 G_calculated = 2.5441949153929966 G_critical = 3.9516371116015274 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 13 possible_outlier = 45.0 (idx = 425) N= 702 t= 3.996084869405895 degree of freedom= 700 G_calculated = 2.557840511772124 G_critical = 3.9512740163881452 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 14 possible_outlier = 35.0 (idx = 217) N= 701 t= 3.9957738692023828 degree of freedom= 699 G_calculated = 2.4982885702077184 G_critical = 3.950910350475372 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 15 possible_outlier = 23.0 (idx = 377) N= 700 t= 3.9954624322518404 degree of freedom= 698 G_calculated = 2.511306855235973 G_critical = 3.9505461121234102 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 16 possible_outlier = 24.0 (idx = 199) N= 699 t= 3.9951505573480874 degree of freedom= 697 G_calculated = 2.4505517764013174 G_critical = 3.9501812995838206 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 17 possible_outlier = 9.0 (idx = 429) N= 698 t= 3.994838243280854 degree of freedom= 696 G_calculated = 2.462937042940008 G_critical = 3.9498159111011044 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 18 possible_outlier = 27.0 (idx = 438) N= 697 t= 3.9945254888351673 degree of freedom= 695 G_calculated = 2.4755120607107415 G_critical = 3.949449944912085 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 19 possible_outlier = 39.0 (idx = 645) N= 696 t= 3.994212292789997 degree of freedom= 694 G_calculated = 2.4882817249078317 G_critical = 3.9490833992445813 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 20 possible_outlier = 1.0 (idx = 132) N= 695 t= 3.993898653919909 degree of freedom= 693 G_calculated = 2.4261735959609085 G_critical = 3.948716272318986 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 21 possible_outlier = 54.0 (idx = 254) N= 694 t= 3.993584570994465 degree of freedom= 692 G_calculated = 2.4382958727453263 G_critical = 3.9483485623476553 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 22 possible_outlier = 30.0 (idx = 478) N= 693 t= 3.9932700427776204 degree of freedom= 691 G_calculated = 2.450601733924487 G_critical = 3.9479802675343176 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 23 possible_outlier = 25.0 (idx = 284) N= 692 t= 3.9929550680293757 degree of freedom= 690 G_calculated = 2.387204801652519 G_critical = 3.947611386075636 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 24 possible_outlier = 19.0 (idx = 448) N= 691 t= 3.9926396455021944 degree of freedom= 689 G_calculated = 2.3988556870656685 G_critical = 3.947241916157731 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 25 possible_outlier = 58.0 (idx = 520) N= 690 t= 3.9923237739463784 degree of freedom= 688 G_calculated = 2.41067888567203 G_critical = 3.946871855961351 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 26 possible_outlier = 43.0 (idx = 528) N= 689 t= 3.9920074521050073 degree of freedom= 687 G_calculated = 2.422678687196788 G_critical = 3.9465012036569584 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 27 possible_outlier = 46.0 (idx = 71) N= 688 t= 3.9916906787163304 degree of freedom= 686 G_calculated = 2.357900927060036 G_critical = 3.946129957407021 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 28 possible_outlier = 22.0 (idx = 181) N= 687 t= 3.991373452513177 degree of freedom= 685 G_calculated = 2.369234145475613 G_critical = 3.945758115365416 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 29 possible_outlier = 58.0 (idx = 10) N= 686 t= 3.9910557722238655 degree of freedom= 684 G_calculated = 2.303254501256145 G_critical = 3.945385675678287 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 30 possible_outlier = 40.0 (idx = 149) N= 685 t= 3.9907376365701297 degree of freedom= 683 G_calculated = 2.3139232737964557 G_critical = 3.945012636482019 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 31 possible_outlier = 29.0 (idx = 206) N= 684 t= 3.9904190442695064 degree of freedom= 682 G_calculated = 2.324741726981293 G_critical = 3.9446389959055144 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 32 possible_outlier = 47.0 (idx = 370) N= 683 t= 3.99009999403402 degree of freedom= 681 G_calculated = 2.3357133938377737 G_critical = 3.9442647520689107 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 33 possible_outlier = 61.0 (idx = 494) N= 682 t= 3.9897804845696037 degree of freedom= 680 G_calculated = 2.346841925254589 G_critical = 3.9438899030829844 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 34 possible_outlier = 37.0 (idx = 470) N= 681 t= 3.9894605145762734 degree of freedom= 679 G_calculated = 2.2793853838286444 G_critical = 3.943514447049302 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 35 possible_outlier = 23.0 (idx = 584) N= 680 t= 3.9891400827512284 degree of freedom= 678 G_calculated = 2.289835850562417 G_critical = 3.943138382063194 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 36 possible_outlier = 9.0 (idx = 133) N= 679 t= 3.9888191877824073 degree of freedom= 677 G_calculated = 2.221192039308914 G_critical = 3.942761706207495 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 37 possible_outlier = 25.0 (idx = 355) N= 678 t= 3.9884978283552677 degree of freedom= 676 G_calculated = 2.230971106397375 G_critical = 3.942384417559079 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 38 possible_outlier = 35.0 (idx = 483) N= 677 t= 3.9881760031478155 degree of freedom= 675 G_calculated = 2.2408805180919487 G_critical = 3.942006514184027 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 39 possible_outlier = 23.0 (idx = 665) N= 676 t= 3.9878537108337153 degree of freedom= 674 G_calculated = 2.25092319595566 G_critical = 3.941627994140605 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 40 possible_outlier = 27.0 (idx = 117) N= 675 t= 3.9875309500795306 degree of freedom= 673 G_calculated = 2.221008172763438 G_critical = 3.94124885547658 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 41 possible_outlier = 28.0 (idx = 603) N= 674 t= 3.9872077195485485 degree of freedom= 672 G_calculated = 2.1988959016534033 G_critical = 3.9408690962328783 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 42 possible_outlier = 14.0 (idx = 13) N= 673 t= 3.986884017895129 degree of freedom= 671 G_calculated = 2.193644628203823 G_critical = 3.940488714438114 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 43 possible_outlier = 34.0 (idx = 369) N= 672 t= 3.9865598437706993 degree of freedom= 670 G_calculated = 2.20318804614288 G_critical = 3.940107708114341 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 44 possible_outlier = 24.0 (idx = 564) N= 671 t= 3.986235195819574 degree of freedom= 669 G_calculated = 2.1943520453747536 G_critical = 3.939726075272998 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 45 possible_outlier = 45.0 (idx = 353) N= 670 t= 3.9859100726805825 degree of freedom= 668 G_calculated = 2.1974242007647864 G_critical = 3.9393438139164494 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 46 possible_outlier = 35.0 (idx = 476) N= 669 t= 3.9855844729872496 degree of freedom= 667 G_calculated = 2.2070548064778417 G_critical = 3.9389609220381336 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 47 possible_outlier = 21.0 (idx = 55) N= 668 t= 3.985258395365088 degree of freedom= 666 G_calculated = 2.210267206834921 G_critical = 3.938577397619925 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 48 possible_outlier = 5.0 (idx = 619) N= 667 t= 3.984931838436839 degree of freedom= 665 G_calculated = 2.2200783632778047 G_critical = 3.9381932386371616 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 49 possible_outlier = 28.0 (idx = 226) N= 666 t= 3.9846048008168773 degree of freedom= 664 G_calculated = 2.2226135745633253 G_critical = 3.93780844305322 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 50 possible_outlier = 55.5 (idx = 123) N= 665 t= 3.984277281115008 degree of freedom= 663 G_calculated = 2.2259977084637446 G_critical = 3.937423008823151 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 51 possible_outlier = 30.0 (idx = 127) N= 664 t= 3.983949277933772 degree of freedom= 662 G_calculated = 2.236042165050184 G_critical = 3.9370369338910507 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 52 possible_outlier = 9.0 (idx = 133) N= 663 t= 3.983620789871513 degree of freedom= 661 G_calculated = 2.2462238711911198 G_critical = 3.9366502161929953 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 53 possible_outlier = 23.0 (idx = 282) N= 662 t= 3.9832918155182546 degree of freedom= 660 G_calculated = 2.2565459813095283 G_critical = 3.936262853653029 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 54 possible_outlier = 28.0 (idx = 285) N= 661 t= 3.982962353460204 degree of freedom= 659 G_calculated = 2.267011752266979 G_critical = 3.9358748441874867 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 55 possible_outlier = 25.0 (idx = 579) N= 660 t= 3.9826324022756374 degree of freedom= 658 G_calculated = 2.2776245476807944 G_critical = 3.935486185700989 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 56 possible_outlier = 16.0 (idx = 610) N= 659 t= 3.9823019605372534 degree of freedom= 657 G_calculated = 2.288387842465697 G_critical = 3.9350968760886897 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 57 possible_outlier = 2.0 (idx = 6) N= 658 t= 3.981971026811647 degree of freedom= 656 G_calculated = 2.214929406980869 G_critical = 3.934706913235736 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 58 possible_outlier = 39.0 (idx = 12) N= 657 t= 3.9816395996588003 degree of freedom= 655 G_calculated = 2.2249470920643737 G_critical = 3.934316295016746 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 59 possible_outlier = 38.0 (idx = 84) N= 656 t= 3.9813076776336986 degree of freedom= 654 G_calculated = 2.235101981832808 G_critical = 3.9339250192973414 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 60 possible_outlier = 9.0 (idx = 145) N= 655 t= 3.9809752592829826 degree of freedom= 653 G_calculated = 2.2453972371411317 G_critical = 3.933533083930884 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 61 possible_outlier = 58.0 (idx = 216) N= 654 t= 3.980642343148702 degree of freedom= 652 G_calculated = 2.255836121736949 G_critical = 3.9331404867620714 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 62 possible_outlier = 30.0 (idx = 246) N= 653 t= 3.9803089277656785 degree of freedom= 651 G_calculated = 2.2664220066072676 G_critical = 3.9327472256243556 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 63 possible_outlier = 50.0 (idx = 347) N= 652 t= 3.9799750116617205 degree of freedom= 650 G_calculated = 2.2771583745518145 G_critical = 3.9323532983401255 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 64 possible_outlier = 22.0 (idx = 381) N= 651 t= 3.9796405933599415 degree of freedom= 649 G_calculated = 2.2880488249970146 G_critical = 3.931958702722907 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 65 possible_outlier = 39.0 (idx = 460) N= 650 t= 3.9793056713754487 degree of freedom= 648 G_calculated = 2.299097079065728 G_critical = 3.931563436574142 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 66 possible_outlier = 23.0 (idx = 600) N= 649 t= 3.9789702442169568 degree of freedom= 647 G_calculated = 2.3103069849189697 G_critical = 3.9311674976847097 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 67 possible_outlier = 21.0 (idx = 28) N= 648 t= 3.9786343103870094 degree of freedom= 646 G_calculated = 2.2345841458524522 G_critical = 3.9307708838351085 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 68 possible_outlier = 61.0 (idx = 136) N= 647 t= 3.978297868381481 degree of freedom= 645 G_calculated = 2.245001057889017 G_critical = 3.930373592794945 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 69 possible_outlier = 59.0 (idx = 187) N= 646 t= 3.9779609166897973 degree of freedom= 644 G_calculated = 2.255565064846227 G_critical = 3.9299756223231124 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 70 possible_outlier = 26.0 (idx = 249) N= 645 t= 3.9776234537937536 degree of freedom= 643 G_calculated = 2.2662796614586846 G_critical = 3.929576970166619 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 71 possible_outlier = 45.5 (idx = 266) N= 644 t= 3.977285478169829 degree of freedom= 642 G_calculated = 2.277148459815918 G_critical = 3.9291776340627864 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 72 possible_outlier = 60.0 (idx = 293) N= 643 t= 3.976946988285918 degree of freedom= 641 G_calculated = 2.288175194478235 G_critical = 3.9287776117360615 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 73 possible_outlier = 54.0 (idx = 5) N= 642 t= 3.9766079826050404 degree of freedom= 640 G_calculated = 2.2291034707997412 G_critical = 3.928376900901566 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 74 possible_outlier = 47.0 (idx = 85) N= 641 t= 3.976268459581386 degree of freedom= 639 G_calculated = 2.23954959840261 G_critical = 3.9279754992612403 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 75 possible_outlier = 16.0 (idx = 177) N= 640 t= 3.9759284176647154 degree of freedom= 638 G_calculated = 2.2501440187748436 G_critical = 3.927573404508062 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 76 possible_outlier = 45.0 (idx = 222) N= 639 t= 3.9755878552950294 degree of freedom= 637 G_calculated = 2.260890274046948 G_critical = 3.927170614320862 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 77 possible_outlier = 42.0 (idx = 345) N= 638 t= 3.975246770907657 degree of freedom= 636 G_calculated = 2.2717920259414215 G_critical = 3.9267671263692 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 78 possible_outlier = 4.0 (idx = 357) N= 637 t= 3.974905162929331 degree of freedom= 635 G_calculated = 2.2828530610146864 G_critical = 3.9263629383095484 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 79 possible_outlier = 26.0 (idx = 405) N= 636 t= 3.9745630297811894 degree of freedom= 634 G_calculated = 2.2940772961826297 G_critical = 3.9259580477881406 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 80 possible_outlier = 15.0 (idx = 546) N= 635 t= 3.974220369876243 degree of freedom= 633 G_calculated = 2.3054687845480206 G_critical = 3.9255524524385046 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 81 possible_outlier = 27.0 (idx = 7) N= 634 t= 3.9738771816196206 degree of freedom= 632 G_calculated = 2.240262165223447 G_critical = 3.9251461498816558 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 82 possible_outlier = 29.0 (idx = 39) N= 633 t= 3.9735334634108774 degree of freedom= 631 G_calculated = 2.250983662689736 G_critical = 3.9247391377282876 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 83 possible_outlier = 9.0 (idx = 118) N= 632 t= 3.9731892136421596 degree of freedom= 630 G_calculated = 2.2618606277080033 G_critical = 3.9243314135769665 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 84 possible_outlier = 40.5 (idx = 124) N= 631 t= 3.972844430697086 degree of freedom= 629 G_calculated = 2.2728968542395607 G_critical = 3.9239229750130127 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 85 possible_outlier = 17.0 (idx = 311) N= 630 t= 3.9724991129523652 degree of freedom= 628 G_calculated = 2.284096267142741 G_critical = 3.923513819610027 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 86 possible_outlier = 7.0 (idx = 424) N= 629 t= 3.972153258778723 degree of freedom= 627 G_calculated = 2.2954629280371437 G_critical = 3.923103944930742 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 87 possible_outlier = 44.0 (idx = 475) N= 628 t= 3.971806866537733 degree of freedom= 626 G_calculated = 2.307001041492208 G_critical = 3.9226933485239304 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 88 possible_outlier = 50.0 (idx = 521) N= 627 t= 3.9714599345841224 degree of freedom= 625 G_calculated = 2.3187149615615392 G_critical = 3.922282027926588 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 89 possible_outlier = 70.0 (idx = 592) N= 626 t= 3.9711124612660185 degree of freedom= 624 G_calculated = 2.3306091986860378 G_critical = 3.921869980664134 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 90 possible_outlier = 33.0 (idx = 606) N= 625 t= 3.970764444921807 degree of freedom= 623 G_calculated = 2.3426884269907013 G_critical = 3.921457204247342 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 91 possible_outlier = 21.0 (idx = 391) N= 624 t= 3.970415883885145 degree of freedom= 622 G_calculated = 2.265794627323651 G_critical = 3.9210436961771307 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 92 possible_outlier = 19.0 (idx = 34) N= 623 t= 3.9700667764791144 degree of freedom= 621 G_calculated = 2.2645723128019624 G_critical = 3.9206294539388926 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 93 possible_outlier = 28.0 (idx = 159) N= 622 t= 3.969717121021226 degree of freedom= 620 G_calculated = 2.275805433247651 G_critical = 3.92021447500727 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 94 possible_outlier = 17.0 (idx = 311) N= 621 t= 3.969366915820979 degree of freedom= 619 G_calculated = 2.287207440606989 G_critical = 3.919798756843768 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 95 possible_outlier = 18.0 (idx = 535) N= 620 t= 3.969016159179446 degree of freedom= 618 G_calculated = 2.298782609684593 G_critical = 3.9193822968963126 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 96 possible_outlier = 21.0 (idx = 493) N= 619 t= 3.9686648493895524 degree of freedom= 617 G_calculated = 2.214618166720857 G_critical = 3.918965092599473 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 97 possible_outlier = 18.0 (idx = 516) N= 618 t= 3.968312984737016 degree of freedom= 616 G_calculated = 2.2252682557758834 G_critical = 3.9185471413753317 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 98 possible_outlier = 45.0 (idx = 561) N= 617 t= 3.967960563499946 degree of freedom= 615 G_calculated = 2.2360735337856017 G_critical = 3.9181284406330468 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 99 possible_outlier = 27.0 (idx = 178) N= 616 t= 3.967607583948444 degree of freedom= 614 G_calculated = 2.2080463865610183 G_critical = 3.9177089877684375 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない i = 100 possible_outlier = 36.0 (idx = 310) N= 615 t= 3.967254044343545 degree of freedom= 613 G_calculated = 2.218664082829254 G_critical = 3.917288780162909 G_calculated < G_criticalなので帰無仮説は棄却されず外れ値は存在するとは言えない
r=100でtestしてみましたが、外れ値は存在するとは言えないという結果になりました。
ロバストZスコアを使う (Modified Zscoreとも言われるようです)
通常のZスコアは平均値(mean)と標準偏差(standard deviation)を利用するので外れ値の影響を受けやすいですが、ロバストZスコアでは中央値(median)と中央絶対偏差(median absolute deviation)を利用するので外れ値の影響を軽減できるようです。
※ 中央絶対偏差を使う以外にもNormalized IQRなどを使う方法もあるようです。
# ロバストZスコア基準での外れ値の検出
# MAD is scaled. please check below link for reference
# https://stats.stackexchange.com/questions/523865/calculating-robust-z-scores-with-median-and-mad
def outlier_detector_robust_zscore(Y):
import numpy as np
import scipy.stats as stats
x = Y
x = x[~np.isnan(x)]
median = np.median(x)
MAD = stats.median_abs_deviation(x, scale='normal') # scale to fit sample standard deviation
print("median =",median,"MAD =",MAD)
outliers_list=[]
for val in x:
robust_zscore = 0.6745 * (val - median) / MAD
if np.abs(robust_zscore) > 3.5:
outliers_list.append(val)
if(len(outliers_list) == 0):
return 'no possible outliers'
else:
return print(outliers_list)
outlier_detector_robust_zscore(df["Age"].dropna())
median = 28.0 MAD = 13.343419966550417 'no possible outliers'
正規分布ではない場合の処理 (if Skewed distribution)
QQプロットを確認する限り、SibSp・Parch・Fareに外れ値が存在していそうです。
その場合IQRで外れ値かどうかを判断できるようです。
- Q1 – 1.5 x IQR より小さい値、Q3 + 1.5 x IQR より大きい値を外れ値と定義
IQRを使う
# IQRでの外れ値検出を試す
def outlier_detector_iqr(Y):
import numpy as np
q1 = np.quantile(Y, 0.25)
q3 = np.quantile(Y,0.75)
IQR = q3 - q1
print("q1 =",q1,"q3 =",q3)
lower_bound = q1 - 1.5 * IQR
upper_bound = q3 + 1.5 * IQR
print("lower_bound =",lower_bound,"upper_bound =",upper_bound)
outliers_list=[]
for val in Y:
if val < lower_bound:
outliers_list.append(val)
elif val > upper_bound:
outliers_list.append(val)
if (len(outliers_list) == 0):
return 'no possible outliers'
else:
return print(outliers_list)
outlier_detector_iqr(df["Fare"])
q1 = 7.9104 q3 = 31.0 lower_bound = -26.724 upper_bound = 65.6344 [71.2833, 263.0, 146.5208, 82.1708, 76.7292, 80.0, 83.475, 73.5, 263.0, 77.2875, 247.5208, 73.5, 77.2875, 79.2, 66.6, 69.55, 69.55, 146.5208, 69.55, 113.275, 76.2917, 90.0, 83.475, 90.0, 79.2, 86.5, 512.3292, 79.65, 153.4625, 135.6333, 77.9583, 78.85, 91.0792, 151.55, 247.5208, 151.55, 110.8833, 108.9, 83.1583, 262.375, 164.8667, 134.5, 69.55, 135.6333, 153.4625, 133.65, 66.6, 134.5, 263.0, 75.25, 69.3, 135.6333, 82.1708, 211.5, 227.525, 73.5, 120.0, 113.275, 90.0, 120.0, 263.0, 81.8583, 89.1042, 91.0792, 90.0, 78.2667, 151.55, 86.5, 108.9, 93.5, 221.7792, 106.425, 71.0, 106.425, 110.8833, 227.525, 79.65, 110.8833, 79.65, 79.2, 78.2667, 153.4625, 77.9583, 69.3, 76.7292, 73.5, 113.275, 133.65, 73.5, 512.3292, 76.7292, 211.3375, 110.8833, 227.525, 151.55, 227.525, 211.3375, 512.3292, 78.85, 262.375, 71.0, 86.5, 120.0, 77.9583, 211.3375, 79.2, 69.55, 120.0, 93.5, 80.0, 83.1583, 69.55, 89.1042, 164.8667, 69.55, 83.1583]
outlier_detector_iqr(df["SibSp"])
q1 = 0.0 q3 = 1.0 lower_bound = -1.5 upper_bound = 2.5 [3, 4, 3, 3, 4, 5, 3, 4, 5, 3, 3, 4, 8, 4, 4, 3, 8, 4, 8, 3, 4, 4, 4, 4, 8, 3, 3, 5, 3, 5, 3, 4, 4, 3, 3, 5, 4, 3, 4, 8, 4, 3, 4, 8, 4, 8]
outlier_detector_iqr(df["Parch"])
q1 = 0.0 q3 = 0.0 lower_bound = 0.0 upper_bound = 0.0 [1, 2, 1, 5, 1, 1, 5, 2, 2, 1, 1, 2, 2, 2, 1, 2, 2, 2, 3, 2, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 2, 2, 2, 1, 2, 1, 1, 2, 1, 4, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 2, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 4, 1, 1, 2, 2, 2, 2, 2, 1, 1, 1, 2, 2, 1, 1, 2, 2, 3, 4, 1, 2, 1, 1, 2, 1, 2, 1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 1, 1, 2, 1, 4, 1, 1, 2, 1, 2, 1, 1, 2, 5, 2, 1, 1, 1, 2, 1, 5, 2, 1, 1, 1, 2, 1, 6, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1, 1, 2, 1, 2, 3, 1, 2, 1, 2, 2, 1, 1, 2, 1, 2, 1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1, 1, 3, 2, 1, 1, 1, 1, 5, 2]
(正規分布・傾斜分布どちらでも可) パーセンタイルで外れ値かどうかの閾値を定義
汎用的に使えるのがパーセンタイルのようです。
- 1パーセンタイルより小さい値、99パーセンタイルより大きい値を外れ値と定義
パーセンタイルを使う
# パーセンタイルで外れ値を検出する
def outlier_detector_percentile(Y):
import numpy as np
pct_001 = np.quantile(Y, 0.01)
pct_099 = np.quantile(Y,0.99)
print("pct_001 =",pct_001,"pct_099 =",pct_099)
lower_bound = pct_001
upper_bound = pct_099
print("lower_bound =",lower_bound,"upper_bound =",upper_bound)
outliers_list=[]
for val in Y:
if val < lower_bound:
outliers_list.append(val)
elif val > upper_bound:
outliers_list.append(val)
if (len(outliers_list) == 0):
return 'no possible outliers'
else:
return print(outliers_list)
outlier_detector_percentile(df["Fare"])
pct_001 = 0.0 pct_099 = 249.00622000000035 lower_bound = 0.0 upper_bound = 249.00622000000035 [263.0, 263.0, 512.3292, 262.375, 263.0, 263.0, 512.3292, 512.3292, 262.375]
outlier_detector_percentile(df["SibSp"])
pct_001 = 0.0 pct_099 = 5.0 lower_bound = 0.0 upper_bound = 5.0 [8, 8, 8, 8, 8, 8, 8]
outlier_detector_percentile(df["Parch"])
pct_001 = 0.0 pct_099 = 4.0 lower_bound = 0.0 upper_bound = 4.0 [5, 5, 5, 5, 6, 5]
percentileの方がIQRより外れ値の基準が厳しそうです。
より扱いやすいのはパーセンタイルですかね。
外れ値の扱いを検討する
Ageの扱い
外れ値が存在しないようなのでそのまま
SibSp・Parch・Fareの扱い
外れ値と検出されても間違ったデータではないのでそのまま。
同行家族が多く、運賃も人数分合算されたものが入ってきているようだった。
確認内容
# パーセンタイルで外れ値という結果になるデータを表示
df.loc[(df["Fare"] > np.quantile(df["Fare"], 0.99)) | (df["Fare"] < np.quantile(df["Fare"], 0.01) )]
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
27 | 28 | 0 | 1 | Fortune, Mr. Charles Alexander | male | 19.0 | 3 | 2 | 19950 | 263.0000 | C23 C25 C27 | S |
88 | 89 | 1 | 1 | Fortune, Miss. Mabel Helen | female | 23.0 | 3 | 2 | 19950 | 263.0000 | C23 C25 C27 | S |
258 | 259 | 1 | 1 | Ward, Miss. Anna | female | 35.0 | 0 | 0 | PC 17755 | 512.3292 | NaN | C |
311 | 312 | 1 | 1 | Ryerson, Miss. Emily Borie | female | 18.0 | 2 | 2 | PC 17608 | 262.3750 | B57 B59 B63 B66 | C |
341 | 342 | 1 | 1 | Fortune, Miss. Alice Elizabeth | female | 24.0 | 3 | 2 | 19950 | 263.0000 | C23 C25 C27 | S |
438 | 439 | 0 | 1 | Fortune, Mr. Mark | male | 64.0 | 1 | 4 | 19950 | 263.0000 | C23 C25 C27 | S |
679 | 680 | 1 | 1 | Cardeza, Mr. Thomas Drake Martinez | male | 36.0 | 0 | 1 | PC 17755 | 512.3292 | B51 B53 B55 | C |
737 | 738 | 1 | 1 | Lesurer, Mr. Gustave J | male | 35.0 | 0 | 0 | PC 17755 | 512.3292 | B101 | C |
742 | 743 | 1 | 1 | Ryerson, Miss. Susan Parker "Suzette" | female | 21.0 | 2 | 2 | PC 17608 | 262.3750 | B57 B59 B63 B66 | C |
同じ家族は同じチケット番号や運賃になっているようです。
人数が多いFortune家を詳しく見ていきます。
# チケット番号が19950を表示
df.loc[(df["Ticket"] == '19950')]
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
27 | 28 | 0 | 1 | Fortune, Mr. Charles Alexander | male | 19.0 | 3 | 2 | 19950 | 263.0 | C23 C25 C27 | S |
88 | 89 | 1 | 1 | Fortune, Miss. Mabel Helen | female | 23.0 | 3 | 2 | 19950 | 263.0 | C23 C25 C27 | S |
341 | 342 | 1 | 1 | Fortune, Miss. Alice Elizabeth | female | 24.0 | 3 | 2 | 19950 | 263.0 | C23 C25 C27 | S |
438 | 439 | 0 | 1 | Fortune, Mr. Mark | male | 64.0 | 1 | 4 | 19950 | 263.0 | C23 C25 C27 | S |
ParchとSibSpの数が合わないような気がします。
うまく抽出できていないのでしょうか?
Fortune, Mr. Markが64才でSibSpが1になっています。
同年代の人が抽出されなければ変ですね。
# 他にParchが4の人を表示
df.loc[(df["Parch"] == 4)]
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
167 | 168 | 0 | 3 | Skoog, Mrs. William (Anna Bernhardina Karlsson) | female | 45.0 | 1 | 4 | 347088 | 27.900 | NaN | S |
360 | 361 | 0 | 3 | Skoog, Mr. Wilhelm | male | 40.0 | 1 | 4 | 347088 | 27.900 | NaN | S |
438 | 439 | 0 | 1 | Fortune, Mr. Mark | male | 64.0 | 1 | 4 | 19950 | 263.000 | C23 C25 C27 | S |
567 | 568 | 0 | 3 | Palsson, Mrs. Nils (Alma Cornelia Berglund) | female | 29.0 | 0 | 4 | 349909 | 21.075 | NaN | S |
他にParchが4の人を抽出してみましたが、Fortune家の人はFortune, Mr. Markさんしかいなそうです。他の情報と照らし合わせても別名になっているわけでもなさそうです。
# 名前にFortuneという文字列が含まれる人を表示
df.loc[(df["Name"].str.contains('Fortune'))]
PassengerId | Survived | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
27 | 28 | 0 | 1 | Fortune, Mr. Charles Alexander | male | 19.0 | 3 | 2 | 19950 | 263.0 | C23 C25 C27 | S |
88 | 89 | 1 | 1 | Fortune, Miss. Mabel Helen | female | 23.0 | 3 | 2 | 19950 | 263.0 | C23 C25 C27 | S |
341 | 342 | 1 | 1 | Fortune, Miss. Alice Elizabeth | female | 24.0 | 3 | 2 | 19950 | 263.0 | C23 C25 C27 | S |
438 | 439 | 0 | 1 | Fortune, Mr. Mark | male | 64.0 | 1 | 4 | 19950 | 263.0 | C23 C25 C27 | S |
ここまで見てきましたが、全部で6人(両親/子供・兄弟・親戚・自分)のはずですが、やっぱり数が合いません。
ここまできたら、testデータに他のFortune家のメンバーが含まれているのかも知れないので確認してみます。
# テストデータの読み込み
df_test = pd.read_csv("/Users/hinomaruc/Desktop/notebooks/titanic/test.csv")
# 名前にFortuneという文字列が含まれる人を表示
df_test.loc[(df_test["Name"].str.contains('Fortune'))]
PassengerId | Pclass | Name | Sex | Age | SibSp | Parch | Ticket | Fare | Cabin | Embarked | |
---|---|---|---|---|---|---|---|---|---|---|---|
53 | 945 | 1 | Fortune, Miss. Ethel Flora | female | 28.0 | 3 | 2 | 19950 | 263.0 | C23 C25 C27 | S |
69 | 961 | 1 | Fortune, Mrs. Mark (Mary McDougald) | female | 60.0 | 1 | 4 | 19950 | 263.0 | C23 C25 C27 | S |
ビンゴです!Fortune, Miss. Ethel FloraさんとFortune, Mrs. Markさんが抽出されました。TicketもFareも同じです。
次は、Fareの263.0という値が合計料金なのか1人当たりの料金なのか検討をつけようと思います。
# PclassごとのFareの中央値を確認
df.groupby(["Pclass"]).median()
PassengerId | Survived | Age | SibSp | Parch | Fare | |
---|---|---|---|---|---|---|
Pclass | ||||||
1 | 472.0 | 1.0 | 37.0 | 0.0 | 0.0 | 60.2875 |
2 | 435.5 | 0.0 | 29.0 | 0.0 | 0.0 | 14.2500 |
3 | 432.0 | 0.0 | 24.0 | 0.0 | 0.0 | 8.0500 |
Pclass=1の人物全体の中央値の料金は60.2875のようです。
# PclassごとにSibSpとParchが0の中央値を確認 (一人当たりの料金を確認できる)
df.loc[(df["SibSp"] == 0) & (df["Parch"] == 0)].groupby(["Pclass"]).median()
PassengerId | Survived | Age | SibSp | Parch | Fare | |
---|---|---|---|---|---|---|
Pclass | ||||||
1 | 494.0 | 1.0 | 38.5 | 0.0 | 0.0 | 31.0000 |
2 | 399.5 | 0.0 | 31.0 | 0.0 | 0.0 | 13.0000 |
3 | 473.5 | 0.0 | 26.0 | 0.0 | 0.0 | 7.8958 |
Pclass=1の1人当たりの中央値の料金は31のようです。
# PclassごとにSibSpが1とParchが0の中央値を確認 (2人での料金を確認できる)
df.loc[(df["SibSp"] == 1) & (df["Parch"] == 0)].groupby(["Pclass"]).median()
PassengerId | Survived | Age | SibSp | Parch | Fare | |
---|---|---|---|---|---|---|
Pclass | ||||||
1 | 454.0 | 1.0 | 36.0 | 1.0 | 0.0 | 76.7292 |
2 | 384.0 | 0.0 | 29.5 | 1.0 | 0.0 | 26.0000 |
3 | 359.5 | 0.0 | 25.0 | 1.0 | 0.0 | 15.0000 |
Pclass=1の2人当たりの料金の中央値は77のようです。
# Fortune家の一人当たりの料金を計算 (263が合算だった場合を仮定)
263.0 / 6
43.833333333333336
# PclassごとにSibSpとParchが0の平均値を確認 (一人当たりの料金を確認できる)
df.loc[(df["SibSp"] == 0) & (df["Parch"] == 0)].groupby(["Pclass"]).mean()
PassengerId | Survived | Age | SibSp | Parch | Fare | |
---|---|---|---|---|---|---|
Pclass | ||||||
1 | 478.458716 | 0.532110 | 41.005814 | 0.0 | 0.0 | 63.672514 |
2 | 432.086538 | 0.346154 | 33.736559 | 0.0 | 0.0 | 14.066106 |
3 | 459.435185 | 0.212963 | 28.235556 | 0.0 | 0.0 | 9.272052 |
Pclass=1の1人当たりの平均運賃は64のようです。
ここまでの結果をまとめ
・Pclass=1の1人当たりの中央値の料金は31
・Pclass=1の2人当たりの中央値の料金は77
・Pclass=1の1人当たりの平均料金は64
・Fortune家のFareは263で、合計値と仮定して一人当たりに換算すると43.8
上記結果から、Fareの値は(Fortune家に限っては)同行家族全員の合算値になっていると考えれます。
ですので、Fareの料金やSibSpの数値が大きいとしても外れ値ではないと判断しました。
2022/04/26追記
Pclass=2とPclass=3の場合も確認すると、同行家族がいてもチケット番号が異なる人と同じ人両方のパターンがありました。
チケット番号が異なる場合は、Fareは合算にはなっていないと思われますのでご認識ください。
2022/04/27追記
Fareについて調べてみました。
Fare turns out to be a really complicated variable. It's based on the price of the ticket sold to a traveling group (often a family). It's not the cost of the ticket for each individual (unless the Fare was for 1 person). So if you sort the table by Ticket, you'll see that people who share the same Ticket had the same Fare. 引用: https://www.kaggle.com/c/titanic/discussion/33087
チケットは家族などのグループ単位で販売されているので、1人でない限りやはり合算値になっているようです。
また、年齢によるディスカウントや関係者など無料で乗船した人のFareは0になっているようです。
そのため1人1人の運賃を正確に計算することは難しいようです。
まとめ
タイタニックのデータセットの外れ値の検出と処理をしてみました。
今回はきれいなデータでしたので処理をするものがありませんでしたが、ウェブデータで何回もPVが飛んできてしまった場合などで極端に数値が多くなる場合があります。その場合は機械学習にかける前に除外や数値を丸めたりする必要がありますので、また他のデータセットの分析をする際に取り組みたいと思います。
参考
・https://ja.wikipedia.org/wiki/外れ値
・https://statisticsbyjim.com/basics/interquartile-range/
・https://statisticsbyjim.com/basics/outliers/
・https://www.statisticshowto.com/grubbs-test/
・https://www.degruyter.com/document/doi/10.1515/dema-2021-0041/html
・https://stats.stackexchange.com/questions/355943/how-to-estimate-the-scale-factor-for-mad-for-a-non-normal-distribution
・https://www.statology.org/modified-z-score/