• トップ
  • ブログ一覧
  • 【機械学習】欠損値に対する正しい対処法
  • 【機械学習】欠損値に対する正しい対処法

    広告メディア事業部広告メディア事業部
    2020.01.31

    IT技術

    欠損値を正しく処理する方法

    データには、「欠損値」が含まれている場合が多くあります。

    機械学習を行う場合は、欠損値をどのように処理するのかによって精度は大きく変わってきます。

    本記事では、欠損値を正しく処理する方法について説明していきます。

    欠損値を見つける方法

    まずは、欠損値を処理するために、欠損値がどこにいくつあるのかを確認していきましょう。

    今回扱うデータフレームを以下に定義します。

    1import pandas as pd
    2import numpy as np
    3
    4df = pd.DataFrame([['A1', 20, 51], ['B1', 31, 67],
    5['C1', None, 48], ['D1', 42, 59]],
    6   columns=['ID', 'age', 'weight'])
    7print(df)
    8
    9# ID age weight
    10#0 A1 20.0 51
    11#1 B1 31.0 67
    12#2 C1 NaN 48
    13#3 D1 42.0 59

    欠損値を調べるには、「isnull関数」を利用します。

    欠損値であれば「True」、欠損値でなければ「False」が返ってきます。

    1print(df.isnull())
    2# ID age weight
    3#0 False False False
    4#1 False False False
    5#2 False True False
    6#3 False False False

    このように、欠損値がどこにあるかが分かります。

    しかし、このままだとデータの数が多い時に確認することが大変ですね。

    欠損値がある場所をみやすくする

    そこで、「sum関数」を利用して見やすくします。

    1print(df.isnull().sum())
    2# ID 0
    3# age 1
    4# weight 0
    5# dtype: int64
    6print(df.isnull().sum(axis=1))
    7# 0 0
    8# 1 0
    9# 2 1
    10# 3 0
    11# dtype: int64

    これで「どこに」「いくつ」欠損値があるのかが分かります。

    また、引数に axis=1 をいれると、行に対しての結果を見ることができます。

    データを扱う時は、まずこのようにして欠損値の有無を確かめます。

    欠損値を削除する

    欠損値の数が少ない場合には、欠損値ごとデータを消してしまうという方法があります。

    削除するには、「dropna関数」を使用します。

    axis=1 を指定することで、欠損値が含まれる列を削除します。

    1print(df.dropna())
    2# ID age weight
    3# 0 A1 20.0 51
    4# 1 B1 31.0 67
    5# 3 D1 42.0 59
    6print(df.dropna(axis=1))
    7# ID weight
    8# 0 A1 51
    9# 1 B1 67
    10# 2 C1 48
    11# 3 D1 59

    欠損値を削除するのは簡単ですが、削除するということは情報を減らしてしまうということになります。

    欠損値の削除は、数が少ない時のみにしましょう。

    欠損値を代表値で埋める

    欠損値を埋める最もシンプルな方法として、代表値で埋めるという方法があります。

    平均値で埋める

    最も一般的な方法は、平均値で埋める方法です。

    欠損値を埋めるには、「fillna関数」を使います。

    1print(df.fillna(df.mean()))
    2# ID age weight
    3# A1 20.0 51
    4# B1 31.0 67
    5# C1 31.0 48
    6# D1 42.0 59

    中央値や最頻値で埋める

    平均値で埋める以外にも、中央値や最頻値で埋める方法もあります。

    中央値を求める時は「median関数」、最頻値を求める場合は「mode関数」を使います。

    この他に、引数に method=’ffill 、もしくは method=’bfill を指定することによって、欠損値を前後の値で埋めることができます。

    時系列データの際に有効です。

    1print(df.fillna(method='ffill'))
    2# ID age weight
    3# 0 A1 20.0 51
    4# 1 B1 31.0 67
    5# 2 C1 31.0 48
    6# 3 D1 42.0 59
    7print(df.fillna(method='bfill'))
    8# ID age weight
    9# 0 A1 20.0 51
    10# 1 B1 31.0 67
    11# 2 C1 42.0 48
    12# 3 D1 42.0 59

    欠損値を利用して特徴量を作成する

    欠損値を埋めるのではなく、新しく特徴量として利用する方法もあります。

    簡単に特徴量に変える方法として、欠損しているかどうかの2値変数にする方法があります。

    1age_list = []
    2
    3for i in df["age"].isnull():
    4if i == True:
    5age_list.append(0)
    6else:
    7age_list.append(1)
    8
    9print(age_list)
    10
    11# [1, 1, 0, 1]

    欠損値を利用して特徴量を作ることによって、情報量を減らすことなく利用できるというメリットがあります。

    欠損値のまま利用する

    これまでは、欠損値に対して何かしらの処理をしてきましたが、欠損値をそのままにして利用するという方法もあります。

    例えば、GBDTライブラリでは欠損値があってもそのまま扱うことができるため、そのまま扱うことも多くあります。

    しかし、ニューラルネットワークやランダムフォレストなど、GBDT以外の多くの機械学習手法では、欠損値をそのまま扱うことはできないので、何かしらの処理をする必要があります。

    さいごに

    本記事では欠損値を正しく処理する方法を紹介しました。

    以下のポイントを忘れないようにしましょう。

    1. 欠損値の有無の確認
    2. 欠損値が少なければ削除
    3. データに合わせて欠損値を補完
    4. 欠損値を利用して新たに特徴量を作る
    5. GBDTを使うなら欠損値のままでもOK

    欠損値を処理する方法はたくさんありますが、重要なのはデータに合わせて正しく処理することです。

    こちらの記事もオススメ!

    featureImg2020.07.28機械学習 特集知識編人工知能・機械学習でよく使われるワード徹底まとめ!機械学習の元祖「パーセプトロン」とは?【人工知能】ニューラルネ...

    featureImg2020.07.17ライトコード的「やってみた!」シリーズ「やってみた!」を集めました!(株)ライトコードが今まで作ってきた「やってみた!」記事を集めてみました!※作成日が新し...

    ライトコードでは、エンジニアを積極採用中!

    ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。

    採用情報へ

    広告メディア事業部

    広告メディア事業部

    おすすめ記事

    エンジニア大募集中!

    ライトコードでは、エンジニアを積極採用中です。

    特に、WEBエンジニアとモバイルエンジニアは是非ご応募お待ちしております!

    また、フリーランスエンジニア様も大募集中です。

    background