自分のキャリアをあれこれ考えながら、Pythonで様々なデータを分析していくブログです

(その3-3) タイタニックのデータセットの外れ値の処理

Data Analytics
Data Analytics

前回の記事ではタイタニックのデータセットの欠損値処理をまとめていました。

今回は 2. 外れ値処理 (outlier processing)の作業をしようと思います。

外れ値処理に関してはKaggleの下記コードが参考になりました。
https://www.kaggle.com/code/nareshbhat/outlier-the-silent-killer
https://www.kaggle.com/code/aimack/how-to-handle-outliers

外れ値かどうかを判断するため、外れ値の検定を試してみた記事もあります。

Pythonで外れ値の検定を2種類試してみた
以前の記事にて外れ値の検定として下記三つを挙げました・Grubbs' Test・Tietjen-Moore Test・Generalized Extreme Studentized Deviate (ESD) Test今回、外れ値の検定とし...

それでは、外れ値の処理をしていきたいと思います。

スポンサーリンク

タイタニックのデータセットの読み込み

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

png

Pclass

png

Age

png

SibSp

png

Parch

png

Fare

png

QQプロットは直線にプロットが沿っていると正規分布に従っているという解釈になるようです。

Ageだけおおよそ正規分布に従っているようです。

Kolmogorov-Smirnov testとShapiro-Wilk testでも確認

Ageがおおよそ正規分布に従っていそうなので、正規性テストをしてみようと思います。

# 正規分布かどうかのテスト
# Kolmogorov–Smirnov test
# H0=分布が正規分布である
from scipy import stats
stats.kstest(df["Age"].dropna(),"norm")
Out[0]
    KstestResult(statistic=0.9650366565902186, pvalue=0.0)
# Shapiro–Wilk test
# H0=分布が正規分布である
stats.shapiro(df["Age"].dropna())
Out[0]
    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)
Out[0]
    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)
Out[0]
    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())
Out[0]
    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"])
Out[0]
    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"])
Out[0]
    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"])
Out[0]
    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"])
Out[0]
    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"])
Out[0]
    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"])
Out[0]
    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
Out[0]
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/

タイトルとURLをコピーしました