泰坦尼克数据集Logistic Regression测试集可视化报错求助
解决泰坦尼克逻辑回归可视化的特征不匹配问题
问题描述
使用泰坦尼克生存数据集训练逻辑回归模型后,运行可视化代码时触发ValueError: X has 2 features, but LogisticRegression is expecting 6 features as input.错误,无法生成目标样式的决策边界可视化。
错误原因
训练模型时使用了6个特征(Pclass、Age、SibSp、Parch、Fare、male),但可视化代码仅生成了两个特征的网格数据用于预测,特征数量与模型训练时的输入维度不匹配,导致模型拒绝预测。
解决方案
方案一:仅用两个特征重新训练模型
选择你想可视化的两个特征(比如Age和Fare),重新训练模型,让可视化时的特征维度与模型匹配。
修改后的完整代码:
import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from matplotlib.colors import ListedColormap # 数据加载与清洗 training_set = pd.read_csv('Train_Titanic.csv') training_set.drop(['Cabin', 'Name', 'Ticket', 'Embarked', 'PassengerId'], axis=1, inplace=True) # 填充缺失年龄 def Fill_Age(data): age = data[0] sex = data[1] if pd.isnull(age): return 29 if sex == 'male' else 25 return age training_set['Age'] = training_set[['Age','Sex']].apply(Fill_Age, axis=1) # 性别编码 male = pd.get_dummies(training_set['Sex'], drop_first=True, dtype=int) training_set.drop('Sex', axis=1, inplace=True) training_set = pd.concat([training_set, male], axis=1) # 仅选择两个特征用于训练与可视化(示例选Age和Fare) X = training_set[['Age', 'Fare']].values y = training_set['Survived'].values # 拆分数据集并训练模型 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=10) classifier = LogisticRegression(random_state=0) classifier.fit(X_train, y_train) # 可视化决策边界 X_set, y_set = X_test, y_test X1, X2 = np.meshgrid( np.arange(start=X_set[:,0].min()-1, stop=X_set[:,0].max()+1, step=0.01), np.arange(start=X_set[:,1].min()-1, stop=X_set[:,1].max()+1, step=0.01) ) plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape), alpha=0.75, cmap=ListedColormap(('magenta', 'blue'))) plt.xlim(X1.min(), X1.max()) plt.ylim(X2.min(), X2.max()) # 绘制测试集样本 for i, j in enumerate(np.unique(y_set)): plt.scatter(X_set[y_set==j,0], X_set[y_set==j,1], c=ListedColormap(('magenta', 'blue'))(i), label='生存' if j==1 else '未生存') plt.xlabel('年龄') plt.ylabel('票价') plt.legend() plt.show()
方案二:为网格数据补充其他特征的默认值
保留原6特征模型,为可视化用的网格数据补充其余4个特征的默认值(如训练集的均值),使输入特征数量与模型要求一致。
修改后的核心代码:
# 数据处理部分保留原逻辑,仅修改可视化相关代码 import pandas as pd import numpy as np import seaborn as sns import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.linear_model import LogisticRegression from matplotlib.colors import ListedColormap # 数据加载与清洗(同原代码) training_set = pd.read_csv('Train_Titanic.csv') training_set.drop(['Cabin', 'Name', 'Ticket', 'Embarked', 'PassengerId'], axis=1, inplace=True) def Fill_Age(data): age = data[0] sex = data[1] if pd.isnull(age): return 29 if sex == 'male' else 25 return age training_set['Age'] = training_set[['Age','Sex']].apply(Fill_Age, axis=1) male = pd.get_dummies(training_set['Sex'], drop_first=True, dtype=int) training_set.drop('Sex', axis=1, inplace=True) training_set = pd.concat([training_set, male], axis=1) # 保留DataFrame格式方便后续处理 X_df = training_set.drop('Survived', axis=1) y = training_set['Survived'].values X_train_df, X_test_df, y_train, y_test = train_test_split(X_df, y, test_size=0.2, random_state=10) classifier = LogisticRegression(random_state=0) classifier.fit(X_train_df, y_train) # 选择要可视化的两个特征 feat1, feat2 = 'Age', 'Fare' # 计算其他特征的均值作为默认值 default_vals = X_train_df.mean().to_dict() # 生成网格数据 x_min, x_max = X_test_df[feat1].min()-1, X_test_df[feat1].max()+1 y_min, y_max = X_test_df[feat2].min()-1, X_test_df[feat2].max()+1 X1, X2 = np.meshgrid(np.arange(x_min, x_max, 0.01), np.arange(y_min, y_max, 0.01)) # 构建完整特征矩阵 grid_data = pd.DataFrame({ feat1: X1.ravel(), feat2: X2.ravel() }) for col in X_df.columns: if col not in [feat1, feat2]: grid_data[col] = default_vals[col] # 预测并可视化 predictions = classifier.predict(grid_data.values).reshape(X1.shape) plt.contourf(X1, X2, predictions, alpha=0.75, cmap=ListedColormap(('magenta', 'blue'))) # 绘制测试集样本 for i, j in enumerate(np.unique(y_test)): mask = y_test == j plt.scatter( X_test_df[feat1][mask], X_test_df[feat2][mask], c=ListedColormap(('magenta', 'blue'))(i), label='生存' if j==1 else '未生存' ) plt.xlabel(feat1) plt.ylabel(feat2) plt.legend() plt.xlim(X1.min(), X1.max()) plt.ylim(X2.min(), X2.max()) plt.show()
方案对比
- 方案一:操作简单,可视化结果直观,但仅展示两个特征的决策边界,忽略了其他特征的影响。
- 方案二:更贴近原模型的实际预测逻辑,但默认值的选择(均值/中位数)会影响可视化的决策边界形态。
内容的提问来源于stack exchange,提问作者SH_IQ
相关产品推荐
相关产品推荐

