欠損値
欠損値は実際のデータセットではよくある問題であり、欠損値の処理はデータの前処理における重要なステップです。欠損値は、データの構造と品質、データ入力エラー、送信中のデータ損失、不完全なデータ収集など、さまざまな理由で発生する可能性があります。これらの欠損値は、バイアスを導入して結果を歪める可能性があるため、機械学習モデルの精度と信頼性に影響を与える可能性があり、一部のモデルは欠損値があるとまったく機能しないことさえあります。そのため、モデルを構築する前に欠損値を適切に処理する必要があります。
この記事では、3 つの異なるレベルの方法を使用して、これらの欠損値を処理する方法を示します。
初級: 除去、平均/中央値代入、ドメイン知識を使用した推定
中級: 回帰代入、K 最近傍 (KNN) 代入
上級: 連鎖方程式 (MICE) を使用した多重代入、MICEforest
欠損値のチェック
まず、各機能に欠損値がいくつあるかを確認する必要があります。探索的データ分析の一環として、次のコードを使用してこれを行うことができます。
パンダをインポートしてデータセットで読み取ります。以下の例では、ワイン品質データセットを使用します。
import pandas as pd
df = pd.read_csv('Wine_Quality.csv')
次に、次のコード行で欠損値をチェックできます。
df.isnull().sum()
任意の機能で値が欠落している行は、次を使用して表示できます。
df_filtered = df[df.isnull().any(axis=1)]
df_filtered.head()
これで、これらの欠損値の処理を開始できます。
主な方法
最も簡単な方法は、行または列 (フィーチャ) を削除することです。これは通常、欠損値のパーセンテージが非常に大きい場合、または欠損値が分析や結果に大きな影響を与えない場合に行われます。
欠損値のある行を削除します。
df_droprows = df.dropna()
df_droprows.isnull().sum()
次を使用して列または属性を削除します。
df_dropcols = df.drop(columns=['type', 'fixed acidity', 'citric acid', 'volatile acidity', 'residual sugar', 'chlorides', 'pH', 'sulphates'])
df_dropcols.isnull().sum()
行を削除すると、データセットが短くなります。機能を削除すると、完全なデータセットになりますが、一部の機能が欠落しています。
print("Shape when dropping rows: ", df_droprows.shape)
print("Shape when dropping features: ", df_dropcols.shape)
これらの方法はどちらも最も簡単ですが、貴重なデータが失われるため、一般的にはお勧めできません。
平均/中央値補完
次の初歩的なアプローチは、欠損値を特徴の平均値または中央値に置き換えることです。この場合、フィーチャや行は失われません。ただし、この方法は数値機能にのみ使用できます (平均を使用する場合は、データセットが歪んでいないか、重要な外れ値が含まれていないことを確認する必要があります)。
たとえば、次の例では、平均を使用して欠損値を計算しています。
df = df.fillna(df.mean())
次に、見積もりの 1 つを確認してみましょう。
df[df.index==86]
中央値を使用する場合は、次を使用できます。
df = df.fillna(df.median())
df[df.index==86]
中央値と平均値の間にはまだ差があることがわかります
モード
上記のメソッドと同様に、このメソッドは欠損値を機能のモードまたは最も一般的な値に置き換えます。このアプローチは、カテゴリ機能に使用できます。
まず、1 つのカテゴリが優勢であるかどうかを確認してみましょう。これは value_counts メソッドで行うことができます:
df['type'].value_counts()
一番数が多い「白」があることがわかります。したがって、次の方法で埋めることができます。
df['type'] = df['type'].fillna(df['type'].mode())
Scikit-Learn の SimpleImputer クラス
平均値、中央値、最頻値の代入は、Scikit-learn の SimpleImputer クラスを使用して実行することもできます。戦略を「平均」、「中央値」、または「最多頻度」に設定します
df_numeric = df.drop(columns='type')
imputer_median = SimpleImputer(strategy='median')
imputer_median.fit(df_numeric)
df_imputed_median = pd.DataFrame(imputer_median.transform(df_numeric), columns=df_numeric.columns)
df_imputed_median.head()
戦略を「定数」に設定し、「fill_value」を指定して定数値を埋めることもできます。
平均値/中央値/最頻値の利点:
シンプルで迅速な実装
これにより、サンプル サイズが維持され、機械学習モデルなどのダウンストリーム分析におけるバイアスのリスクが軽減されます。
より複雑な方法よりも計算コストが低くなります。
欠点:
推定値が真の値を表していない可能性があるデータの変動性または分布は考慮されていません。
特に極端な値または外れ値を持つデータセットでは、欠損値が過小評価または過大評価される可能性があります。
分散を減らし、代入データセットの相関係数を人為的に膨らませます。
欠損値が完全に無作為に欠損している (MCAR) ことを前提としていますが、常にそうであるとは限りません。
ドメイン知識を用いた評価
欠損データを処理するもう 1 つの方法は、欠損値をドメインの知識またはビジネス ルールに基づく推定値に置き換えることです。合理的で信頼できる欠損値は、その分野の専門家に相談して専門知識を提供することで帰属させることができます。
しかし、この方法が実際にうまくいくとは限りません。なぜなら、正確で信頼性の高い見積もりを作成するには専門家が必要ですが、そのような分野の専門家は多くないからです。したがって、ここでは主要なメソッドに入れます。
中間法
これらの欠落した値を埋めるための少し高度な手法もあり、予測モデルを使用して問題を解決します。ただし、それを行う前に、欠損値の性質をよりよく理解する必要があります。
欠損値のタイプ
より高度な手法に進む前に、データセットで発生する可能性のある欠落の種類を考慮する必要があります。データセットにはさまざまなタイプの削除があり、削除のタイプを理解すると、適切な方法を決定するのに役立ちます。一般的なタイプを次に示します。
完全に無作為に欠損: このタイプでは、欠損値は完全にランダムです。つまり、値が欠損している確率は、観測された変数または観測されていない変数に依存しません。たとえば、回答者がアンケートの質問を誤ってスキップした場合、それは MCAR です。
ランダムに欠落: このタイプでは、値が欠落している確率は、値自体ではなく、観測された変数に依存します。たとえば、調査回答者がデリケートな質問に回答する可能性が低く、回答しない傾向が年齢、性別、教育などの観察可能な変数に依存する場合、これは MAR です。
ランダムではない欠落: このタイプでは、値が欠落している確率は、欠落している値自体を含む観測されていない変数に依存します。たとえば、うつ病のレベルが高い人がうつ病のレベルを報告する可能性が低く、報告しない傾向がデータで観察できない場合、これは MNAR です。
回帰代入
回帰モデルを使用して、データセット内の他の機能を分析し、それらの相関関係を使用して埋めることにより、これらの欠損値について知識に基づいた推測を行います。
回帰代入は、特定のパターン (MAR または MCAR) に従う欠損データを処理する場合に特に役立ちます。この方法は、特徴間に強い相関関係がある場合にうまく機能するためです。
ここでは、カテゴリ特徴を含まないバージョンのデータを作成します。次に、各列の欠損値に対して線形回帰モデルを当てはめます。ここでは、Scikit-learn の線形回帰モジュールを使用する必要があります。
import pandas as pd
from sklearn.linear_model import LinearRegression
# Read data
df = pd.read_csv('Wine_Quality.csv')
# Make sub dataframe with only numeric features
df = df.drop(columns='type')
# Separate the columns with missing values
missing_cols = df.columns[df.isna().any()].tolist()
non_missing_cols = list(set(df.columns) - set(missing_cols))
print(missing_cols)
# loop over each column with missing values
for col in missing_cols:
# Create a copy of the dataframe without missing values in the current column
df_temp = df.dropna(subset=[col] + non_missing_cols)
# Split the dataframe into features (X) and target variable (y)
X = df_temp[non_missing_cols]
y = df_temp[col]
# Create and fit a linear regression model
lr = LinearRegression()
lr.fit(X, y)
# Impute missing values in the current column using the fitted model
df.loc[df[col].isna(), col] = lr.predict(df.loc[df[col].isna(), non_missing_cols])
回帰代入の利点:
多数の欠損値を処理できます。
平均、分散、相関係数などのデータセットの統計的特性を保持できます。
機械学習モデルなどのダウンストリーム分析の精度は、バイアスを減らしてサンプル サイズを増やすことで改善できます。
回帰代入の欠点:
欠損変数と観測変数の間に線形関係があると仮定します。
欠損値が無作為に欠損していない場合 (MAR)、または無作為に完全に欠損している場合 (MCAR) は、バイアスが導入される可能性があります。
カテゴリ変数または順序変数には適さない場合があります。
特に大規模なデータセットの場合、計算コストと時間がかかります。
(KNN) 代入
もう 1 つのアプローチは、K-Nearest Neighbors (KNN) などのクラスタリング モデルを使用して、これらの欠損値を推定することです。これは回帰代入に似ていますが、異なるアルゴリズムを使用して欠損値を予測します。
import pandas as pd
from sklearn.impute import KNNImputer
# Read data
df = pd.read_csv('Wine_Quality.csv')
# Make sub dataframe with only numeric features
df = df.drop(columns='type')
# create a KNN imputer object
imputer = KNNImputer(n_neighbors=5)
# impute missing values using KNN
df = pd.DataFrame(imputer.fit_transform(df), columns=df.columns)
ここでは、さまざまな代入メソッドを含むパッケージ fancyimpute を紹介します。
pip install fancyimpute
使用される方法は次のとおりです。
# Import the necessary libraries
import numpy as np
import pandas as pd
from fancyimpute import KNN
# Load the dataset
df = pd.read_csv('Wine_Quality.csv')
# Drop non-numeric features
df = df.drop(columns='type')
# Get list of columns with missing values
missing_cols = df.columns[df.isna().any()].tolist()
# Create an instance of the KNN imputer
imputer = KNN()
# Fit and transform the imputer to the dataset
imputed_array = imputer.fit_transform(df[missing_cols])
# Replace the missing values in the original dataset
df[missing_cols] = imputed_array
# View the imputed dataset
df
KNN 代入の利点:
変数間の複雑な非線形関係を捉えることができます。
データの分布や変数間の相関関係について、仮定は行われませんでした。
特に小規模から中規模のデータセットの場合、平均または中央値の代入などの単純な代入方法よりも正確です。
欠点:
特に大規模なデータセットや高次元データの場合、計算コストが高くなる可能性があります。
距離メトリックの選択と、選択された最近傍の数に影響される可能性があり、精度に影響します。
非常に歪んだデータやまばらなデータではうまく機能しません。
高度な方法
連鎖方程式 (MICE) による多重代入
MICE は、欠損データを代入するために一般的に使用される方法です。データセット内の変数間の関係を考慮したモデルに基づいて、各欠損値を一連の妥当な値に置き換えることで機能します。
アルゴリズムは、他の変数の完全なセットに基づいて、データセット内の各変数の予測モデルを作成することから始めます。各変数の欠損値は、対応する予測モデルを使用して代入されます。このプロセスは、収束に達するまで、前のラウンドからの代入値をあたかも真であるかのように使用して、代入の各ラウンドで複数回繰り返されます。
次に、複数の代入データセットを組み合わせて、欠落しているすべてのデータの代入を含む最終的なデータセットを作成します。MICE は、多くの欠損値と変数間の複雑な関係を持つデータセットを処理できる強力で柔軟な方法です。社会科学、健康研究、環境科学など、多くの分野で不足しているデータを埋めるための一般的な選択肢となっています。
fancyimpute パッケージには、直接使用できるこのメソッドの実装が含まれています。
import numpy as np
import pandas as pd
from fancyimpute import IterativeImputer
# Read data
df = pd.read_csv('Wine_Quality.csv')
# Convert type column to category (so that miceforest can handle as a categorical attribute rather than string)
df= df.drop(columns='type')
# Get list of columns with missing values
missing_cols = df.columns[df.isna().any()].tolist()
# Create an instance of the MICE algorithm
imputer = IterativeImputer()
# Fit the imputer to the dataset
imputed_array = imputer.fit_transform(df[missing_cols])
# Replace the missing values in the original dataset
df[missing_cols] = imputed_array
# View the imputed dataset
df
この実装ではカテゴリ変数を埋めることができないので、カテゴリ変数についてはどうでしょうか?
MICEの森
MICEforest は、lightGBM アルゴリズムを使用してデータセット内の欠損値を代入する MICE の変形です。これは素晴らしいアイデアですよね?
mouseforest パッケージを使用してそれを実現できます
pip install miceforest
#或
conda install -c conda-forge miceforest
使い方もとても簡単です。
import pandas as pd
import miceforest as mf
# Read data
df = pd.read_csv('Wine_Quality.csv')
# Convert type column to category (so that miceforest can handle as a categorical attribute rather than string)
df['type'] = df['type'].astype('category')
# Create an instance of the MICE algorithm
imputer = mf.ImputationKernel(data=df,
save_all_iterations=True,
random_state=42)
# Fit the imputer to the dataset. Set number of iterations to 3
imputer.mice(3, verbose=True)
# Generate the imputed dataset
imputed_df = imputer.complete_data()
# View the imputed dataset
imputed_df
ご覧のとおり、カテゴリ変数「タイプ」の欠損値が埋められました
要約する
ここでは、3 つのレベルの欠損値処理方法を紹介します。これら 3 つの方法の選択は、データセット、欠損データの数、および分析の目的によって異なります。欠落データの入力が最終結果に与える潜在的な影響についても、慎重に検討する必要があります。不足しているデータを処理することは、データ分析における重要なステップです. 適切な補完方法を使用することで、データに隠された洞察を解き放つことができます。
最後に、紹介した 2 つの Python パッケージのアドレスです。興味がある場合は、以下をご覧ください。
https://pypi.org/project/fancyimpute/
https://pypi.org/project/miceforest/
作者: ホンジク ユルザ
転送: Deephub Imba
推荐阅读:
我的2022届互联网校招分享
我的2021总结
浅谈算法岗和开发岗的区别
互联网校招研发薪资汇总
2022届互联网求职现状,金9银10快变成铜9铁10!!
公众号:AI蜗牛车
保持谦逊、保持自律、保持进步
发送【蜗牛】获取一份《手把手AI项目》(AI蜗牛车著)
发送【1222】获取一份不错的leetcode刷题笔记
发送【AI四大名著】获取四本经典AI电子书