如何用DecisionBoundaryDisplay绘制多特征分类器的二维决策边界?
如何绘制含全部4个特征的鸢尾花模型的二维决策边界交线
问题描述
现有鸢尾花数据集的分类代码,希望用全部4个特征训练模型,但使用sklearn.inspection.DecisionBoundaryDisplay绘制决策边界时遇到问题:
- 直接传入全部4特征数据:方法要求输入为
(n_samples,2)的二维数据,抛出维度不匹配引发的NaN相关错误 - 仅传入2个特征给已用4特征训练的Pipeline:因为Pipeline中的
RobustScaler期望4个特征输入,抛出维度不匹配错误
需要实现:基于全4特征训练的模型,绘制任意两个特征维度上的决策边界交线(即固定另外两个特征为某一常数值,展示目标二维特征的决策边界)
解决方案
核心思路:绘制某两个特征的决策边界时,将其余特征固定为训练集的统计值(比如均值),构造包含完整4个特征的网格数据,再传入模型进行预测,以此生成符合要求的决策边界。
修改后的完整代码
# -*- coding: utf-8 -*- import seaborn as sns import pandas as pd import numpy as np from matplotlib import pyplot as plt from sklearn.neighbors import KNeighborsClassifier from sklearn.svm import SVC from sklearn import datasets from sklearn.model_selection import train_test_split from sklearn.inspection import DecisionBoundaryDisplay from sklearn.pipeline import make_pipeline from sklearn.preprocessing import RobustScaler iris = datasets.load_iris() X = pd.DataFrame(iris.data, columns=iris.feature_names) y = iris.target X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42) classifiers = { "KNN": KNeighborsClassifier(n_neighbors=5), "RBF SVM": SVC(kernel="rbf"), } intersections = [ ["sepal length (cm)", "sepal width (cm)"], ["petal length (cm)", "petal width (cm)"], ] # 计算训练集各特征的均值,用于固定非目标特征 feature_means = X_train.mean().to_dict() fig, axs = plt.subplots(len(classifiers), len(intersections), figsize=(4 * len(intersections), 4 * len(classifiers))) for i, (name, mdl) in enumerate(classifiers.items()): clf = make_pipeline(RobustScaler(), mdl) clf.fit(X_train, y_train) for j, cols in enumerate(intersections): ax = axs[i, j] if len(classifiers) > 1 else axs[j] # 绘制测试集散点图 sns.scatterplot(X_test, x=cols[0], y=cols[1], hue=y_test, ax=ax) # 生成目标二维特征的网格数据 x_min, x_max = X[cols[0]].min() - 0.5, X[cols[0]].max() + 0.5 y_min, y_max = X[cols[1]].min() - 0.5, X[cols[1]].max() + 0.5 xx, yy = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100)) # 构造完整的4特征输入数据:网格数据 + 固定其余特征为均值 grid_data = pd.DataFrame({ cols[0]: xx.ravel(), cols[1]: yy.ravel() }) # 补充其余特征的固定值 for feature in X.columns: if feature not in cols: grid_data[feature] = feature_means[feature] # 按原始特征顺序排列,保证和训练时的输入顺序一致 grid_data = grid_data[X.columns] # 绘制决策边界 DecisionBoundaryDisplay.from_estimator( clf, grid_data, xx=xx, yy=yy, alpha=0.2, ax=ax, response_method="predict" ) ax.set_title(f"{name} - {cols[0]} vs {cols[1]}") plt.tight_layout() plt.show()
关键步骤解释
- 固定非目标特征:计算训练集各特征的均值,在绘制某两个特征的边界时,将另外两个特征固定为该均值,模拟高维空间中这两个特征维度的截面
- 构造完整输入数据:生成目标二维特征的网格后,补充其余特征的固定值,确保输入数据的维度和模型训练时一致(4个特征),避免Pipeline中Scaler的维度错误
- 对齐特征顺序:将构造的网格数据按原始特征列的顺序排列,保证和模型训练时的输入特征顺序匹配,避免因列顺序不同导致的预测错误
内容的提问来源于stack exchange,提问作者ascripter
相关产品推荐
相关产品推荐

