スキルUP!データ分析実践

データ分析の精度を高める!欠損値と外れ値への対処法(Pandas実践編)

Tags: データ分析, 前処理, 欠損値, 外れ値, Pandas

データ分析を進める上で、データの前処理は非常に重要なステップです。収集したデータは、そのままでは分析に適さない場合が多く、特に「欠損値」や「外れ値」といった問題への適切な対処が必要となります。これらの問題を見過ごすと、分析結果の精度が低下したり、誤った結論を導いてしまったりする可能性があります。

本記事では、データ分析初心者がつまずきやすい欠損値と外れ値に焦点を当て、Pythonのデータ分析ライブラリであるPandasを使用して、これらの問題を発見し、どのように対処すれば良いかを具体的なコード例とともに解説します。データ分析の質を高めるための実践的な方法を身につけていきましょう。

欠損値への対処

欠損値とは

欠損値とは、データセットの中で値が存在しない、または記録されていないセルのことです。例えば、アンケートで回答されなかった項目や、センサーが一時的にデータを取得できなかった期間などが欠損値となる原因として考えられます。Pandasでは、NaN (Not a Number)として表示されることが一般的です。

欠損値の検出

まず、データセットに欠損値がどの程度含まれているかを確認することが重要です。Pandasでは、いくつかの便利なメソッドが提供されています。

データフレームdfがあるとして、欠損値を確認するにはisnull()メソッドを使用します。これは、データフレームと同じ形状の真偽値データフレームを返します。

import pandas as pd
import numpy as np

# サンプルデータの作成
data = {'col1': [1, 2, np.nan, 4, 5],
        'col2': [np.nan, 2, 3, 4, np.nan],
        'col3': ['A', 'B', 'C', 'D', 'E']}
df = pd.DataFrame(data)

# 欠損値の確認
print(df.isnull())

各列の欠損値の合計数を把握するには、isnull()の結果に対してsum()メソッドを使用します。

# 各列の欠損値数の合計
print(df.isnull().sum())

さらに、データフレーム全体の情報(各列のデータ型や非欠損値の数など)を確認できるinfo()メソッドも欠損値の把握に役立ちます。

# データフレームの情報の確認
print(df.info())

欠損値への対処方法

欠損値への対処方法は、その性質や量、分析の目的に応じて様々な選択肢があります。代表的な方法をいくつか紹介します。

  1. 欠損値を含む行/列の削除: 欠損値がごく一部の行に集中している場合や、その行を除外しても分析に大きな影響がない場合は、該当する行や列を削除する方法があります。dropna()メソッドを使用します。

    ```python

    欠損値を含む行を削除

    df_dropped_rows = df.dropna(axis=0) print("行を削除した場合:") print(df_dropped_rows)

    欠損値を含む列を削除

    df_dropped_cols = df.dropna(axis=1) print("\n列を削除した場合:") print(df_dropped_cols) ``axis=0が行の削除、axis=1`が列の削除を指定します。ただし、多くの行や列が削除されると、データ量が減りすぎてしまい、分析が困難になる可能性があるため注意が必要です。

  2. 欠損値の補完(穴埋め): 欠損値を特定の代表値や予測値で埋める方法です。データ量が減るのを避けたい場合に有効です。fillna()メソッドを使用します。

    • 特定の定数で補完: 例えば、0や特定の文字列で埋めます。

      ```python

      欠損値を0で補完

      df_filled_zero = df.fillna(0) print("\n0で補完した場合:") print(df_filled_zero) ```

    • 平均値、中央値、最頻値で補完: 数値データの場合によく用いられます。

      ```python

      col1の欠損値を平均値で補完

      mean_col1 = df['col1'].mean() df_filled_mean = df['col1'].fillna(mean_col1) df['col1'] = df_filled_mean # 元のデータフレームを更新する場合 print("\n平均値で補完した場合:") print(df) `` 中央値(median())や最頻値(mode()`)も同様に使用できます。

    • 前後の値で補完: 時系列データなどで、直前または直後の値で補完する方法です。ffill() (forward fill)やbfill() (backward fill)を使用します。

      ```python

      前の値で補完

      df_filled_ffill = df.fillna(method='ffill') print("\n前の値で補完した場合:") print(df_filled_ffill)

      後ろの値で補完

      df_filled_bfill = df.fillna(method='bfill') print("\n後ろの値で補完した場合:") print(df_filled_bfill) ```

どの補完方法を選択するかは、データの特性や欠損のメカニズム、分析の目的に大きく依存します。安易な補完はデータの分布を歪める可能性もあるため、慎重に検討が必要です。

外れ値への対処

外れ値とは

外れ値とは、データセットの中で他の大部分の値から大きく外れた値のことです。測定ミス、データの入力間違い、あるいは単に稀な極端な事象によって発生する可能性があります。外れ値は、平均値などの統計量や、モデルの学習に大きな影響を与えることがあります。

外れ値の検出

外れ値を検出する方法はいくつかあります。

  1. 視覚化による検出: データ分布を視覚化することで、外れ値を直感的に把握できます。箱ひげ図(Box plot)や散布図(Scatter plot)がよく用いられます。

    例えば、MatplotlibやSeabornライブラリを使用します(これらのライブラリについての詳細は別途学習することをお勧めします)。

    ```python import matplotlib.pyplot as plt import seaborn as sns

    サンプルデータの作成(外れ値を含む)

    data_outlier = {'value': [10, 12, 15, 11, 13, 100, 14, 16, 12, 13]} df_outlier = pd.DataFrame(data_outlier)

    箱ひげ図の描画

    plt.figure(figsize=(5, 5)) sns.boxplot(y=df_outlier['value']) plt.title('Box Plot with Outlier') plt.show() ``` 箱ひげ図では、箱の外にある点が外れ値として表示されることが一般的です。

  2. 統計的手法による検出: 統計的な指標を用いて、定量的に外れ値を判断します。

    • Zスコア: データの平均値から標準偏差の何倍離れているかを示す指標です。一般的に、Zスコアが特定の閾値(例えば2や3)を超える値を外れ値とみなします。

      ```python from scipy.stats import zscore

      Zスコアの計算

      df_outlier['z_score'] = zscore(df_outlier['value']) print("\nZスコア:") print(df_outlier)

      Zスコアが閾値(例: 2)を超える値を外れ値とみなす

      threshold = 2 outliers_zscore = df_outlier[abs(df_outlier['z_score']) > threshold] print(f"\nZスコアが{threshold}を超える外れ値:") print(outliers_zscore) ```

    • IQR (四分位範囲): データのばらつきを示す指標で、データの中心50%が含まれる範囲です。IQRを用いた方法では、「第一四分位数(Q1) - 1.5 * IQR」より小さい値、または「第三四分位数(Q3) + 1.5 * IQR」より大きい値を外れ値とみなします。

      ```python

      IQRの計算

      Q1 = df_outlier['value'].quantile(0.25) Q3 = df_outlier['value'].quantile(0.75) IQR = Q3 - Q1

      外れ値の閾値

      lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR

      IQRに基づく外れ値の検出

      outliers_iqr = df_outlier[(df_outlier['value'] < lower_bound) | (df_outlier['value'] > upper_bound)] print(f"\nIQRに基づく外れ値 (閾値: {lower_bound} - {upper_bound}):") print(outliers_iqr) ```

外れ値への対処方法

外れ値が見つかった場合の対処も、欠損値と同様に複数の選択肢があります。

  1. 外れ値の削除: 外れ値がデータ入力の誤りなど明らかな間違いである場合や、その数が非常に少なく分析に与える影響が大きい場合は、該当するデータポイントを削除します。

    ```python

    外れ値を削除(例: IQRに基づく検出結果を使用)

    df_no_outliers = df_outlier[~((df_outlier['value'] < lower_bound) | (df_outlier['value'] > upper_bound))] print("\n外れ値を削除した場合:") print(df_no_outliers) ```

  2. 外れ値の変換: データの分布を正規分布に近づけるために、対数変換や平方根変換などの数学的変換を適用する方法です。これにより、外れ値の影響を緩和できる場合があります。

  3. 外れ値を別の値に置き換え: 外れ値を、例えば平均値、中央値、または外れ値ではない最大/最小値などに置き換える方法です。

    ```python

    外れ値を中央値に置き換え(例: IQRに基づく検出結果を使用)

    median_value = df_outlier['value'].median() df_replaced_outliers = df_outlier.copy() # 元のデータフレームに影響を与えないようにコピー df_replaced_outliers.loc[(df_replaced_outliers['value'] < lower_bound) | (df_replaced_outliers['value'] > upper_bound), 'value'] = median_value print("\n外れ値を中央値に置き換えた場合:") print(df_replaced_outliers) ```

外れ値への対処も、欠損値と同様にデータの特性や目的に応じて慎重に行う必要があります。場合によっては、外れ値自体が分析にとって重要な情報(例:不正検知における不正な取引額)であることもあります。そのような場合は、削除や変換をせず、外れ値として扱うことが適切です。

まとめ

データ分析の精度を高めるためには、データ前処理における欠損値と外れ値への適切な対処が不可欠です。本記事では、Pandasライブラリを用いて、これらの問題を発見し、一般的な方法で対処する手順を解説しました。

欠損値の処理では、削除するか補完するかをデータの性質や量に応じて検討し、補完する場合は平均値、中央値、特定の値などで埋める方法があることを紹介しました。外れ値の検出では、視覚化やZスコア、IQRといった統計的手法があり、対処としては削除や値の置き換えが考えられます。

どのような対処方法を選択するかは、データセットの特性、欠損や外れ値が発生した原因、そして最終的な分析の目的によって異なります。まずは、データセットをよく観察し、どのような問題があるかを把握することから始めてみましょう。そして、今回紹介したPandasの機能を使って、様々な検出・対処方法を実際に試してみてください。実践を重ねることで、データ分析の質を向上させるスキルが身についていきます。