欠損値とは何か
欠損値とはデータセットの中の空白のデータを示します。空白のデータとは何かしらの理由で、収集されていないデータのことを言います。PythonなどではNanと表示されます。
例えばアンケート調査データの場合の無回答項目やカルテデータの未検査項目等が該当します。カルテデータの未検査項目などは意図している欠損値ですが人的ミスなどによる意図しない欠損値も存在します。
意図しない欠損値とはデータの収集漏れや、システム上に不具合があってデータの変換に失敗した場合などです。また、もともとある測定項目に新しい測定項目を追加した場合も、古いデータでは測定していない項目となるため、欠損値になってしまう場合もあります。
このような欠損値のデータは除外するか、または他の値へ置き換える必要があります。
欠損値の具体例
- アンケート調査データの場合の無回答項目
- カルテデータの未検査項目
欠損値の問題点
一般的に欠損値があるデータを集計する場合、その行は削除して集計されることがほとんどです。matplotlibやseabornを使用した場合も同様で、欠損値があるデータをグラフ化した場合、欠損値があるデータは除外されてグラフ化されます。そのため気付かないうちに母数が少なくなってしまうことが起こります。
欠損値は一つも無いことが望ましいですが、そのようなデータは稀でほとんどの場合は何かしら欠損値があります。そのため、欠損値の扱いについてマスターしておく必要があります。
このページで解説する内容
- 欠損値の確認方法
- 欠損値の列/行の削除方法
- 欠損値の代入方法(平均値、中央値、最小値、最大値、固有値)
使用するサンプルデータ
Titanic: Machine Learning from Disaster
サンプルデータとして、kaggleで提供されているデータセット、Titanic: Machine Learning from Disasterを使用します。Titanic: Machine Learning from Disasterのデータはtitanic号が沈没したときの乗客員のデータです。titanic号の沈没では、多くの乗客が死亡してしまったために後から確認できない項目も多く欠損値が含まれるデータになっています。
事前準備
事前にデータセットを用意しておいてください。
訓練用ファイル:train.csv
試験用ファイル:test.csv
データセットが無い場合はkaggleのサイトからデータをダウンロードしてください。
https://www.kaggle.com/c/titanic
[crayon-673f31217eeef476223064/]
[crayon-673f31217eef7096685749/]
データの先頭を表示してみましょう。
[crayon-673f31217eefa491604284/]
それぞれのカラムの意味は次のようになります。
PassengerId – 乗客識別ユニークID
Survived – 生存フラグ(0=死亡、1=生存)
Pclass – チケットクラス
Name – 乗客の名前
Sex – 性別(male=男性、female=女性)
Age – 年齢
SibSp – タイタニックに同乗している兄弟/配偶者の数
parch – タイタニックに同乗している親/子供の数
ticket – チケット番号
fare – 料金
cabin – 客室番号
Embarked – 出港地(タイタニックへ乗った港)
データの詳細を表示してみましょう。
[crayon-673f31217eefd663756519/]
それぞれの項目の意味は次のようになります。
count–データの個数
mean–データの平均
std–データの標準偏差
min–データの最小値
25%–第一四分位数
50%–第二四分位数
75%–第三四分位数
max–データの最小値
データの要素数を表示してみましょう。
[crayon-673f31217ef00780305647/]
[crayon-673f31217ef04298344193/]
この結果により891行、12列のデータが格納されているということが分かりました。
これで一通り事前準備が完了しました。引き続き欠損値の確認を行っていきます。
欠損値の確認方法
info()を使用して総合的な情報を表示する
[crayon-673f31217ef07233076548/]
[crayon-673f31217ef0c105480362/]
先ほど計算した通り、 タイタニックのデータは891行、12列のデータの要素になっています。しかし、Age,Cabin,Embarkedが891個に対して不足してます。つまり欠損値はAge,Cabin,Embarkedに存在していることになります。
isnull()を使用して欠損値の有無を表示する
[crayon-673f31217ef0f906720775/]
[crayon-673f31217ef12861466187/]
先ほどよりも分かりやすく欠損値の有無が分かるようになりました。
False:欠損無し
True:欠損あり
Age,Cabin,Embarkedに存在していることが一目で分かります。
isnull().sum()を使用して欠損値のカウントを表示する
[crayon-673f31217ef16936758803/]
[crayon-673f31217ef18444129979/]
欠損値の個数を示しています。Ageが177個、Cabinが687個、Embarkedが2個の欠損値があります。
pandasの表形式で欠損値のカウントを表示する
[crayon-673f31217ef1a752613129/]
pandasの表形式で欠損値を表示しています。先ほどと同じくAgeが177個、Cabinが687個、Embarkedが2個の欠損値となっています。
pandasの表形式で欠損値の欠損率を表示する
[crayon-673f31217ef1c540667069/]
pandasの表形式で欠損率を表示しています。
欠損値の対処法(何かしらの設定値で埋める)
続いて欠損値の対処方法について説明します。平均値、中央値、最小値、最大値、固有値で欠損値の項目を埋めていきます。今回はのAge部分について埋めて行きます。どのインデックスがのAge欠損値になっているかを見てみます。
[crayon-673f31217ef1f152387866/]
Ageの欠損値の部分について先頭5行を表示しました。インデックス5番、17番、19番、26番、28番が欠損値となっています。
平均値で埋める
[crayon-673f31217ef21339395274/]
train_df.Age.mean()を指定することににより平均値で埋められます。
[crayon-673f31217ef23823338103/]
AgeのTureが0となっており欠損値がなくなったことが分かります。実際に何の値に更新されたか確認してみましょう。
[crayon-673f31217ef25863496318/]
Ageの値が29.699118になっています。平均値になっていることが分かります。
中央値で埋める
[crayon-673f31217ef27990411447/]
train_df.Age.median()を指定することににより中央値で埋められます。
[crayon-673f31217ef29150175327/]
AgeのTureが0となっており欠損値がなくなったことが分かります。実際に何の値に更新されたか確認してみましょう。
[crayon-673f31217ef2b547158626/]
Ageの値が28.0になっています。中央値になっていることが分かります。
最小値で埋める
[crayon-673f31217ef2d308024216/]
train_df.Age.min()を指定することににより最小値で埋められます。
[crayon-673f31217ef2f198316696/]
AgeのTureが0となっており欠損値がなくなったことが分かります。実際に何の値に更新されたか確認してみましょう。
[crayon-673f31217ef31510280594/]
Ageの値が0.42になっています。最小値になっていることが分かります。
最大値で埋める
[crayon-673f31217ef3c782344104/]
train_df.Age.max()を指定することににより最大値で埋められます。
[crayon-673f31217ef3e991736054/]
AgeのTureが0となっており欠損値がなくなったことが分かります。実際に何の値に更新されたか確認してみましょう。
[crayon-673f31217ef40908288719/]
Ageの値が80.0になっています。最大値になっていることが分かります。
固有値で埋める
[crayon-673f31217ef44096030616/]
固有値として10を指定しました。
[crayon-673f31217ef46111749755/]
AgeのTureが0となっており欠損値がなくなったことが分かります。実際に何の値に更新されたか確認してみましょう。
[crayon-673f31217ef49481475493/]
Ageの値が10になっています。指定した設定値になっていることが分かります。
欠損値の対処法(欠損部分を削除する)
続いて欠損値の列または行の削除を行っていきます。
欠損値の列削除
[crayon-673f31217ef4b752785150/]
読み込んだばかりの列を表示します。Age,Cabin,Embarkedが存在していることを確認してください。
[crayon-673f31217ef4d011921599/]
列を削除しました。axis=1が指定されている場合は列を示しています。
[crayon-673f31217ef4f248028647/]
欠損値の列を削除後を表示します。Age,Cabin,Embarkedが存在しないことを確認してください。
欠損値の行削除
[crayon-673f31217ef51173945360/]
[crayon-673f31217ef53270336382/]
読み込んだばかりの要素を表示します。891行、12列となっていることを確認してください。
[crayon-673f31217ef55104423051/]
行を削除しました。axis=0が指定されている場合は行を示しています。
[crayon-673f31217ef57694599291/]
[crayon-673f31217ef5b059424066/]
欠損値の行を削除後を表示します。891行→183行に減っています。
まとめ
欠損値があるデータを集計する場合、その行は削除して集計されることがほとんどなので、気付かずにグラフの母数が少なくなっていたということがあります。データ集計における母数は重要となり、結果の妥当性に関わってくるもののです。しっかりと欠損値の扱いについて理解しておくようにしましょう。