機械学習データ前処理入門

機械学習データ前処理:データ内の欠損状態を可視化する方法【Pandas+Missingno入門】

Tags: 機械学習, データ前処理, 欠損値, Pandas, Missingno

機械学習モデルの性能は、使用するデータの質に大きく左右されます。そして、データの前処理は、その質を高めるための非常に重要なステップです。データ前処理の中でも、多くの場合に直面するのが「欠損値」への対応です。

欠損値とは、データの一部が記録されていなかったり、取得できなかったりして、値が存在しない状態を指します。この欠損値を適切に処理しないと、機械学習モデルが正しく学習できなかったり、分析結果が歪んでしまったりする可能性があります。

欠損値への対応を始める前に、データの中にどれくらい欠損値があるのか、どの列に欠損値が多いのか、あるいは特定のパターンで欠損しているのか、といった「欠損値の状態」を把握することが非常に重要です。この状態把握に役立つのが「欠損値の可視化」です。データを視覚的に確認することで、欠損値の全体像を素早く、直感的に理解することができます。

この記事では、データ分析で広く使われているPythonのライブラリであるPandasと、欠損値の可視化に特化したMissingnoライブラリを使用して、データ内の欠損状態を把握する方法を解説します。プログラミング経験が少ない方でも理解できるよう、基本的な使い方から丁寧にご説明します。

なぜデータ内の欠損状態を可視化する必要があるのか

欠損値が存在するデータに対して、いきなり補完や削除といった処理を施すのは危険です。なぜなら、欠損している理由やパターンによって、最適な対処法が異なるからです。

例えば、 * 特定の列にほとんどのデータが欠損している場合、その列は分析に使わない方が良いかもしれません。 * ある列の欠損が、別の列の値に依存して発生しているパターンがあるかもしれません(例: 特定の条件を満たす場合にのみ計測されるデータなど)。 * 欠損値がランダムに発生しているのか、それとも何らかの規則性を持って発生しているのか。

このような欠損値の「特徴」を理解せずに処理を進めると、データの持つ本来の情報が失われたり、誤った分析結果を導いてしまったりする可能性があります。

欠損状態を可視化することで、以下のような情報を効率的に把握できます。

  1. 欠損値の量: 各列にどの程度の割合で欠損値が存在するか。
  2. 欠損値のパターン: 欠損値がデータ全体に散らばっているのか、特定の行や列に集中しているのか。
  3. 欠損値間の関係: ある列に欠損値がある場合に、他の列にも欠損値が発生しやすいといった相関関係があるか。

これらの情報は、欠損値を削除するべきか、それとも補完するべきか、補完する場合はどのような方法(平均値、中央値、機械学習モデルなど)が良いかを判断する上で、非常に役立ちます。

欠損値の可視化に必要な準備

Pythonを使って欠損値を可視化するためには、いくつかのライブラリが必要です。この記事では、データ操作にPandas、欠損値の可視化にMissingnoライブラリを使用します。

まだこれらのライブラリをインストールしていない場合は、以下のコマンドでインストールしてください。

pip install pandas missingno matplotlib

matplotlibは、Missingnoがグラフを描画するために内部で使用するライブラリです。

インストールが完了したら、PythonスクリプトやJupyter Notebookなどでライブラリをインポートします。

import pandas as pd
import missingno as msno
import matplotlib.pyplot as plt

# グラフのスタイル設定(任意)
plt.style.use('seaborn-v0_8-whitegrid')

次に、サンプルデータを作成します。ここでは、簡単なDataFrameを作成し、意図的に欠損値(NaN)を含めてみます。

import numpy as np

# サンプルデータの作成
data = {
    'ColumnA': [1, 2, np.nan, 4, 5],
    'ColumnB': [10, 20, 30, np.nan, 50],
    'ColumnC': [100, np.nan, np.nan, 400, 500],
    'ColumnD': ['A', 'B', 'C', 'D', np.nan],
    'ColumnE': [np.nan, np.nan, np.nan, np.nan, np.nan], # 全て欠損
    'ColumnF': [1, 2, 3, 4, 5] # 欠損なし
}
df = pd.DataFrame(data)

print("サンプルデータ(欠損値を含む):")
print(df)
print("\n各列の欠損値数:")
print(df.isnull().sum())
サンプルデータ(欠損値を含む):
   ColumnA  ColumnB  ColumnC ColumnD  ColumnE  ColumnF
0      1.0     10.0    100.0       A      NaN        1
1      2.0     20.0      NaN       B      NaN        2
2      NaN     30.0      NaN       C      NaN        3
3      4.0      NaN    400.0       D      NaN        4
4      5.0     50.0    500.0     NaN      NaN        5

各列の欠損値数:
ColumnA    1
ColumnB    1
ColumnC    2
ColumnD    1
ColumnE    5
ColumnF    0
dtype: int64

df.isnull().sum()を使うと、各列にいくつの欠損値があるかを確認できます。しかし、これだけでは欠損値がどのように分布しているか、他の列との関連性があるかといった情報は把握しづらいです。ここで、Missingnoの可視化機能が役立ちます。

Missingnoを使った欠損値の可視化手法

Missingnoライブラリは、データフレームを渡すだけで、欠損状態を視覚的に表現するいくつかの便利な関数を提供しています。代表的なものをいくつかご紹介します。

1. 欠損値マトリックス (msno.matrix())

msno.matrix()関数は、データの密度、つまり値が存在する箇所を黒い線で、欠損値(NaN)を白い線で表現した図を描画します。これにより、データ全体における欠損値の分布やパターンを直感的に把握できます。特に、データのごく一部が欠損しているのか、それとも多くのデータが欠損しているのか、あるいは特定の列や行に集中して欠損があるのか、といったことが一目でわかります。

各列は縦のバーとして表示され、各行は横の領域として表示されます。右側には、各行における非欠損値の数の合計を示すスパークラインが表示されます。

print("\n--- msno.matrix() ---")
msno.matrix(df)
plt.title('Missing Value Matrix') # タイトルを追加
plt.show()

この図を見ると、 * ColumnEは全体が白くなっており、全ての値が欠損していることがわかります。 * ColumnFは全体が黒くなっており、欠損値が全くないことがわかります。 * ColumnAColumnBColumnCColumnDには白い部分があり、それぞれ欠損値が存在することがわかります。 * 特にColumnCは2つの白い線があり、欠損値が2つあることが視覚的に確認できます。

データ量が多い場合、このマトリックスはデータの「スカスカ具合」や、欠損がランダムに見えるか、あるいは特定のブロック状にまとまっているかなどを把握するのに有効です。

2. バーチャート (msno.bar())

msno.bar()関数は、各列の非欠損値(つまり、値が存在するデータ)の数をバーグラフとして表示します。これは、各列にどれくらいのデータが「有効」であるかを比較するのに役立ちます。グラフの高さが列のデータ数を表し、色がついた部分が非欠損値の数、その上の空白部分が欠損値の数を表します。

print("\n--- msno.bar() ---")
msno.bar(df)
plt.title('Missing Value Bar Chart') # タイトルを追加
plt.show()

この図を見ると、 * ColumnFが最も高く、5つの非欠損値があることがわかります(サンプルデータの行数と同じ)。 * ColumnEはバーがなく、非欠損値が0であることがわかります。 * 他の列も、非欠損値の数がバーの高さで比較できます。例えば、ColumnCはバーの高さが他の列より少し低く、欠損値が多いことがわかります。

df.isnull().sum()で数値として確認した各列の欠損値数を、相対的な量として視覚的に比較するのに適しています。

3. ヒートマップ (msno.heatmap())

msno.heatmap()関数は、列間の欠損値の相関関係をヒートマップとして表示します。これは、「ある列に欠損値がある場合に、別の列にも欠損値がある(またはない)という傾向があるか」を把握するのに役立ちます。

相関値は-1から1の範囲で示され、 * 1に近い正の値: ある列に欠損値がある場合、もう一方の列にも欠損値がある傾向が強い(欠損が一緒に発生しやすい)。 * -1に近い負の値: ある列に欠損値がある場合、もう一方の列には欠損値がない傾向が強い(片方が欠損していればもう一方は存在する)。 * 0に近い値: 欠損の発生に相関があまりない(ランダムに近い)。

print("\n--- msno.heatmap() ---")
msno.heatmap(df)
plt.title('Missing Value Correlation Heatmap') # タイトルを追加
plt.show()

このヒートマップでは、対角線(同じ列同士)は当然1.0になります。それ以外の部分を見て、色の濃淡と数値を確認します。

サンプルデータが非常に小さいため、ヒートマップのパターンは限定的ですが、例えば実際のデータで「ユーザーがログインしていない場合にのみ、特定のアクティビティログが欠損する」といった傾向がある場合、対応する列間で高い正の相関が見られる可能性があります。このような相関が発見できれば、欠損の原因を推測したり、片方の情報を使って欠損値を補完したりするヒントになります。

注意点: msno.heatmap()は、相関を計算するためにデータのペアワイズ(2列間の)完全性に基づいています。つまり、2つの列の両方に値が存在する行だけを見て相関を計算するのではなく、「片方の列が欠損しているときに、もう片方の列が欠損している割合」のような関連性を見ます。詳細な計算方法はMissingnoのドキュメントを参照してください。

可視化結果をどのように次に活かすか

欠損値の可視化によって、データ内の欠損状態を把握できた後は、適切な前処理方法を選択する段階に進みます。可視化から得られた知見は、その判断材料となります。

どのような対処法を選択するにしても、その選択はデータの内容、欠損の割合、そして分析やモデル構築の目的によって異なります。欠損値を可視化してデータの状態を「知る」ことが、適切な判断を下すための第一歩となるのです。

まとめ

この記事では、機械学習のためのデータ前処理において非常に重要なステップである、欠損値の可視化に焦点を当てました。PandasとMissingnoライブラリを使うことで、データ内の欠損値の量、パターン、および列間の関連性を効果的に把握できることをご紹介しました。

これらの可視化手法を活用することで、データが抱える欠損値の問題をより深く理解し、その後の欠損値処理(削除や補完など)の方針をデータに基づいて決定できるようになります。データ前処理の次のステップに進む前に、ぜひ欠損値の可視化を取り入れてみてください。

データ前処理には、この記事で扱った欠損値の処理以外にも、さまざまな手法があります。当サイトでは、データ前処理に関する様々なトピックを、初心者の方にも分かりやすく解説していますので、ぜひ他の記事も参考にしていただければ幸いです。