Python调用KNeighborsClassifier时Jupyter出现Dead Kernel报错
问题根因
你遇到的Dead Kernel和可视化不符合预期的问题由4个代码错误导致:
- 内存溢出:深度(Depth)字段取值范围通常覆盖0~数千米,你设置的网格步长
mesh_step_size = .01会生成超千万级的网格预测点,内存占满后直接触发Jupyter内核崩溃 - 缩进错误:
plt.xlabel、plt.ylabel、plt.show()三个绘图语句被写在plot_water_knn函数外部,执行顺序完全混乱 - 逻辑不匹配:未处理字符串格式的水团标签会导致绘图接口报错;深度轴默认向上递增,不符合海洋垂直剖面的常规展示规则
- 冗余导入:重复导入了
matplotlib.patches模块
你需要实现的参考效果如下:
修复后完整代码
import numpy as np import matplotlib.pyplot as plt import pandas as pd from sklearn.model_selection import train_test_split from matplotlib.colors import ListedColormap import matplotlib.patches as mpatches from sklearn.neighbors import KNeighborsClassifier from sklearn.preprocessing import LabelEncoder # 读取数据集 index = pd.read_excel('diverty_index.xlsx') X = index[['Shannon', 'Depth']] y = index['Water_mass'] # 对字符串类型的水团标签做编码 le = LabelEncoder() y_encoded = le.fit_transform(y) class_names = le.classes_ # 自动匹配数据集中的水团名称顺序 # 拆分训练测试集 X_train, X_test, y_train, y_test = train_test_split(X, y_encoded, random_state=0) def plot_water_knn(X, y, n_neighbors, weights): X_mat = X.values y_mat = y # 定义配色:浅底色为决策面,深颜色为样本点 cmap_light = ListedColormap(['#FFAAAA', '#AAFFAA', '#AAAAFF','#AFAFAF']) cmap_bold = ListedColormap(['#FF0000', '#00FF00', '#0000FF','#AFAFAF']) # 训练KNN模型 clf = KNeighborsClassifier(n_neighbors, weights=weights) clf.fit(X_mat, y_mat) # 生成网格(控制网格点总数在100万以内,避免内存溢出) plot_symbol_size = 50 x_min, x_max = X_mat[:, 0].min() - 0.5, X_mat[:, 0].max() + 0.5 y_min, y_max = X_mat[:, 1].min() - 10, X_mat[:, 1].max() + 10 # 自适应步长,保证总网格点数不触发内存溢出 x_range = x_max - x_min y_range = y_max - y_min mesh_step_size = np.sqrt(x_range * y_range / 1000000) xx, yy = np.meshgrid(np.arange(x_min, x_max, mesh_step_size), np.arange(y_min, y_max, mesh_step_size)) Z = clf.predict(np.c_[xx.ravel(), yy.ravel()]) Z = Z.reshape(xx.shape) # 绘制决策面 plt.figure(figsize=(8,6)) plt.pcolormesh(xx, yy, Z, cmap=cmap_light, shading='auto') # 绘制样本点 plt.scatter(X_mat[:, 0], X_mat[:, 1], s=plot_symbol_size, c=y_mat, cmap=cmap_bold, edgecolor = 'black', zorder=3) plt.xlim(xx.min(), xx.max()) plt.ylim(yy.min(), yy.max()) # 反转y轴,让深度0在顶部,符合海洋深度展示习惯 plt.gca().invert_yaxis() # 添加图例、轴标签 patch0 = mpatches.Patch(color='#FF0000', label=class_names[0]) patch1 = mpatches.Patch(color='#00FF00', label=class_names[1]) patch2 = mpatches.Patch(color='#0000FF', label=class_names[2]) patch3 = mpatches.Patch(color='#AFAFAF', label=class_names[3]) plt.legend(handles=[patch0, patch1, patch2, patch3]) plt.xlabel('Shannon H') plt.ylabel('Profundidade(m)') plt.tight_layout() plt.show() # 调用绘图 plot_water_knn(X_train, y_train, 5, 'uniform') # 如需输出模型测试集准确率可放开下面注释 # print(f"测试集准确率:{clf.score(X_test, y_test):.2f}")
适配说明
- 网格步长改为自适应计算,总网格点数控制在100万以内,从根源避免Dead Kernel问题
- 修正了所有缩进错误,绘图逻辑全部封装在函数内
- 增加标签编码逻辑,自动适配字符串格式的水团标签,无需手动替换数值
- 自动反转深度轴,和参考图的垂直剖面展示逻辑一致
- 去掉了冗余导入,增加
shading='auto'参数避免matplotlib版本兼容警告 - 图例标签自动读取数据集里的水团名称,不需要硬编码修改
内容的提问来源于stack exchange,提问作者Caio Augusto
相关产品推荐
相关产品推荐

