活用テクニック2026年4月3日

特徴量関連性分析の完全ガイド — 冗長な特徴量を見つけて特徴量選択に活かす

特徴量間の関連度マトリクス、階層クラスタリング、冗長性の検出——高次元データから本当に必要な特徴量を見極めるための分析手法とQastでの実践方法を解説します。

Qast の特徴量関連性分析画面。階層クラスタリングのデンドログラムが表示されている。

機械学習モデルの精度を高めるには、良質な特徴量を選ぶことが不可欠です。しかし、手元のデータに数十〜数百のカラムがある場合、すべてを投入すると多重共線性や過学習のリスクが高まり、モデルの学習時間も長くなります。特徴量関連性分析は、特徴量同士の「似ている度合い」を体系的に評価し、冗長な特徴量を検出・整理するための手法です。この記事では、関連度マトリクス・階層クラスタリング・特徴量フィルタリングの手法を解説します。

特徴量選択はなぜ重要か

特徴量選択(Feature Selection)とは、モデルに投入する特徴量の中から、予測に寄与するものを選び、不要なものを除外するプロセスです。不要な特徴量を除外することで、(1) モデルの過学習を防ぐ、(2) 学習・推論速度を向上させる、(3) モデルの解釈性を高める、(4) データ収集コストを削減する、という4つのメリットが得られます。

特徴量選択のアプローチは大きく3つに分類されます。フィルター法(統計指標で足切りする)、ラッパー法(モデルの性能を基準に選ぶ)、組み込み法(Lasso、ランダムフォレストなどモデル自身が特徴量を選ぶ)です。特徴量関連性分析は、このうちフィルター法の高度版であり、モデル学習前の段階で冗長な特徴量グループを発見できます。

関連度マトリクス — 相関を超えた統合指標

関連度マトリクス(Association Matrix)は、すべての特徴量ペア間の関連度を1つの行列にまとめたものです。単純な相関マトリクスとの違いは、変数の型に応じて最適な指標を自動選択する点です。数値×数値には Pearson/Spearman 相関、数値×カテゴリには相関比(η²)、カテゴリ×カテゴリには Cramér's V を適用し、すべてを 0〜1 の範囲に正規化して統一的に比較できるようにします。

Qast の特徴量関連性分析では、この統合的な関連度マトリクスをヒートマップとして可視化します。どの特徴量ペアが最も「似ているか」を直感的に把握でき、冗長な特徴量の候補を素早く特定できます。

python
import pandas as pd
import numpy as np
from scipy.stats import pearsonr, spearmanr
from sklearn.feature_selection import mutual_info_regression

def association_matrix(df: pd.DataFrame) -> pd.DataFrame:
    """
    数値・カテゴリ混在データの統合関連度マトリクスを計算する。
    数値×数値: |Spearman|、数値×カテゴリ: 相関比、カテゴリ×カテゴリ: Cramér's V
    """
    cols = df.columns
    n = len(cols)
    matrix = pd.DataFrame(np.eye(n), index=cols, columns=cols)

    numeric_cols = df.select_dtypes(include="number").columns
    cat_cols = df.select_dtypes(exclude="number").columns

    for i in range(n):
        for j in range(i + 1, n):
            ci, cj = cols[i], cols[j]
            if ci in numeric_cols and cj in numeric_cols:
                # 数値 × 数値: |Spearman|
                val = abs(spearmanr(df[ci], df[cj]).statistic)
            elif ci in cat_cols and cj in cat_cols:
                # カテゴリ × カテゴリ: Cramér's V
                val = cramers_v(df[ci], df[cj])
            else:
                # 数値 × カテゴリ: 相関比 η²
                num_col = ci if ci in numeric_cols else cj
                cat_col = cj if cj in cat_cols else ci
                val = correlation_ratio(df[cat_col], df[num_col])
            matrix.iloc[i, j] = val
            matrix.iloc[j, i] = val

    return matrix

# 使い方
# assoc = association_matrix(df)
# sns.heatmap(assoc, annot=True, cmap="YlOrRd")

階層クラスタリング — 似た特徴量をグルーピングする

関連度マトリクスを用いて、似た特徴量同士をグルーピングするのが階層クラスタリング(Hierarchical Clustering)です。関連度が高い特徴量ペアから順にクラスターを統合していき、デンドログラム(樹形図)として可視化します。デンドログラムを適切な閾値でカットすることで、冗長な特徴量グループを発見できます。

階層クラスタリングの距離指標には、関連度マトリクスから変換した「1 - 関連度」を使います。関連度が 1(完全に関連)の特徴量ペアは距離 0、関連度が 0(完全に独立)のペアは距離 1 となります。統合方法(リンケージ法)には、Ward 法や完全連結法(Complete Linkage)が一般的です。

python
import numpy as np
import pandas as pd
from scipy.cluster.hierarchy import linkage, dendrogram, fcluster
from scipy.spatial.distance import squareform
import matplotlib.pyplot as plt

# 関連度マトリクスから距離行列を計算
# assoc_matrix は association_matrix() で計算済みの DataFrame
assoc_matrix = pd.DataFrame(
    np.random.uniform(0.1, 0.9, (8, 8)),
    index=[f"特徴量_{i}" for i in range(8)],
    columns=[f"特徴量_{i}" for i in range(8)],
)
np.fill_diagonal(assoc_matrix.values, 1.0)
assoc_matrix = (assoc_matrix + assoc_matrix.T) / 2  # 対称化

distance_matrix = 1 - assoc_matrix
condensed = squareform(distance_matrix, checks=False)

# 階層クラスタリング
Z = linkage(condensed, method="complete")

# デンドログラムの描画
fig, ax = plt.subplots(figsize=(10, 5))
dendrogram(Z, labels=assoc_matrix.columns, ax=ax, leaf_rotation=45)
ax.set_ylabel("距離 (1 - 関連度)")
ax.set_title("特徴量の階層クラスタリング")
ax.axhline(y=0.3, color="r", linestyle="--", label="閾値 0.3")
ax.legend()
plt.tight_layout()
plt.show()

# 閾値でクラスターを取得
clusters = fcluster(Z, t=0.3, criterion="distance")
for i, col in enumerate(assoc_matrix.columns):
    print(f"{col}: クラスター {clusters[i]}")

デンドログラムの閾値を低く設定すると少数の大きなクラスターに、高く設定すると多数の小さなクラスターに分かれます。Qast では閾値をスライダーで動的に調整でき、リアルタイムでクラスターの変化を確認できます。

冗長特徴量の検出と除外戦略

階層クラスタリングで同じクラスターに属する特徴量は「冗長」である可能性が高いです。冗長な特徴量グループが見つかったら、各グループからターゲット変数との関連が最も強い特徴量を1つだけ残し、残りを除外する戦略が有効です。これにより、情報量を大きく損なうことなく特徴量数を削減できます。

  1. 1

    Step 1: 冗長グループを特定する

    階層クラスタリングの結果から、関連度が高い(距離が小さい)特徴量グループを抽出します。関連度 0.8 以上のペアは冗長候補です。

  2. 2

    Step 2: ターゲットとの関連度でランキングする

    各グループ内の特徴量について、ターゲット変数との相互情報量や相関を計算し、最も関連が強い特徴量を選びます。

  3. 3

    Step 3: 代表特徴量を残して他を除外する

    各グループから代表特徴量を1つ選び、残りを除外します。ドメイン知識がある場合は、解釈しやすい特徴量を優先的に残しましょう。

  4. 4

    Step 4: モデルで検証する

    特徴量を削減した後のモデル性能を検証します。精度がほぼ変わらなければ、削減は成功です。

特徴量重要度と特徴量関連性の違い

特徴量関連性と混同されやすい概念に「特徴量重要度」があります。特徴量重要度は、各特徴量がモデルの予測にどれだけ寄与しているかを測る指標で、ランダムフォレストの Gini 重要度や SHAP 値が代表的です。一方、特徴量関連性は、特徴量同士の「似ている度合い」を測る指標です。

重要なのは、「特徴量重要度が高い」ことと「他の特徴量と冗長でない」ことは別の問題だということです。ある特徴量の重要度が高くても、同じ情報を持つ別の特徴量が存在するなら、片方を除外しても精度は落ちません。逆に、重要度が低い特徴量でも、他の特徴量にない独自の情報を持っていれば、除外すると精度が下がる可能性があります。最適な特徴量選択には、重要度と関連性の両方を考慮する必要があります。

相互情報量による特徴量フィルタリング

相互情報量(MI)を使った特徴量フィルタリングは、ターゲット変数との MI が高い特徴量を選び、MI が低い特徴量を除外する手法です。MI はあらゆる種類の依存関係を検出できるため、Pearson 相関では見逃してしまう非線形な関係も拾えます。

python
import pandas as pd
import numpy as np
from sklearn.feature_selection import mutual_info_classif, mutual_info_regression
from sklearn.datasets import make_classification

# サンプルデータの作成(分類タスク)
X, y = make_classification(
    n_samples=1000,
    n_features=20,
    n_informative=5,   # 有用な特徴量は 5 つ
    n_redundant=5,      # 冗長な特徴量は 5 つ
    n_repeated=0,
    random_state=42,
)
feature_names = [f"特徴量_{i}" for i in range(20)]

# ターゲットとの相互情報量を計算
mi_scores = mutual_info_classif(X, y, random_state=42)

# ランキング表示
mi_ranking = pd.DataFrame({
    "特徴量": feature_names,
    "MI": mi_scores,
}).sort_values("MI", ascending=False)

print("ターゲットとの相互情報量ランキング:")
print(mi_ranking.to_string(index=False))

# 閾値でフィルタリング(上位 10 特徴量を選択)
top_features = mi_ranking.head(10)["特徴量"].tolist()
print(f"\n選択された特徴量: {top_features}")

次元削減への橋渡し — なぜ特徴量関連性分析が先か

PCA(主成分分析)や t-SNE などの次元削減手法は、高次元データを低次元に圧縮する強力なツールです。しかし、次元削減は「すべての特徴量を入力として使う」前提で動作するため、ノイズの多い特徴量や冗長な特徴量が含まれていると結果が歪む可能性があります。

特徴量関連性分析を先に行い、明らかにノイズな特徴量や極端に冗長な特徴量を除外してから次元削減を適用する方が、より意味のある低次元表現が得られます。Qast の分析パイプラインでは、特徴量関連性分析 → 多変量分析(PCA/t-SNE)の順で実行されるため、この流れが自然に実践できます。

特徴量の数がサンプル数を大幅に上回る「次元の呪い」が起きているデータでは、特徴量関連性分析による事前フィルタリングが特に効果的です。まず冗長グループを整理し、次に MI でターゲットとの関連が弱い特徴量を除外してから、モデル学習に進みましょう。

Qast の特徴量関連性ダッシュボード

Qast の EDA 機能では、特徴量関連性分析が自動的に実行されます。関連度マトリクスのヒートマップ、階層クラスタリングのデンドログラム、冗長特徴量グループのリストが統合的なダッシュボードとして表示されます。デンドログラムの閾値はスライダーで動的に調整でき、閾値を変えるとリアルタイムでクラスターの変化が反映されます。

さらに、各特徴量のターゲットとの MI スコアも併せて表示されるため、「冗長なグループの中でどの特徴量を残すべきか」の判断も容易です。選定した特徴量のセットは、そのまま学習ジョブの設定に反映できるため、EDA の知見をモデル学習にスムーズに活かせます。

まとめ — 特徴量関連性分析の実践フロー

特徴量関連性分析は、(1) 関連度マトリクスで特徴量ペア間の「似ている度合い」を数値化し、(2) 階層クラスタリングで冗長な特徴量グループを可視化し、(3) ターゲットとの関連度に基づいて代表特徴量を選定する、という3ステップのプロセスです。この分析を通じて、情報量を維持しながら特徴量数を削減でき、モデルの精度・速度・解釈性のすべてを向上させることができます。Qast はこのプロセスを自動化し、直感的なダッシュボードで提供します。

  1. 1

    関連度マトリクスを確認する

    ヒートマップで関連度が高い特徴量ペアを特定します。色が濃いセルに注目しましょう。

  2. 2

    デンドログラムでグルーピングする

    階層クラスタリングの結果を確認し、冗長な特徴量グループを把握します。閾値の調整で粒度を制御できます。

  3. 3

    代表特徴量を選定する

    各グループから、ターゲットとの MI が最も高い特徴量を代表として選びます。ドメイン知識も加味して判断しましょう。

特徴量関連性分析は一度やって終わりではありません。特徴量エンジニアリング(新しい特徴量の作成)を行ったら、再度関連性分析を実行して、新しい特徴量が既存のものと冗長でないか確認しましょう。

Qast を導入してみませんか?

導入のご相談やデモのご依頼は、お気軽にお問い合わせください。