延续第①篇:在“仅用训练像素拟合”的前提下,完成降维→分类→评估→整图预测的最小可用工作流,并将所有结果自动保存到时间戳文件夹。
🎯 本篇目标
- 在无数据泄露前提下:仅用训练像素
fitStandardScaler 与 PCA - 使用 k-NN 完成分类,输出 OA / AA / Kappa 与
precision / recall / F1 - 同时绘制并保存:计数版与归一化版混淆矩阵、PCA 累计解释方差曲线
- 可选:整图像素级预测并保存可视化图与
.npz结果包 - 统一一个带时间戳的结果文件夹,便于归档复现实验
📂 数据说明
- KSC.mat:高光谱数据立方体,形状
(H, W, B) - KSC_gt.mat:标签图,形状
(H, W),0 表示背景/无标签,1…C 为类别编号 - 将二者放入同一目录,例如:
your_path/
├─ KSC.mat
└─ KSC_gt.mat
只需在脚本里将
DATA_DIR = r"your_path"改为你的真实路径,其余保持默认即可一键运行。
🧩 方法要点回顾(与第①篇保持一致)
- 分层划分:仅在有标签像素上进行训练/测试划分(
stratify=labels)。 - 无泄露拟合:
scaler.fit和pca.fit只在训练像素上完成;随后对整图仅做transform。 - 统一变换:整图
(H*W, B)扁平化 →StandardScaler.transform→PCA.transform→ 还原为(H, W, PCA_DIM)。 - 评估:汇报 OA / AA / Kappa 与详细分类报告,同时保存原始与归一化混淆矩阵。
- 整图预测(可选):输出 1…C 的类别图,未标注区域可置 0 便于对照。
⚙️ 环境与依赖
- Python 3.8+
numpy、scipy、scikit-learn、matplotlib- 终端安装示例:
pip install numpy scipy scikit-learn matplotlib
💻 一键可跑完整脚本(自动保存所有结果)
复制粘贴即可运行。仅需修改第一段参数里的
DATA_DIR。
# -*- coding: utf-8 -*-
"""
Sklearn案例②-优化版:无泄露PCA + k-NN分类(结果直存)
数据:KSC / KSC_gt
1) 统一时间戳结果文件夹,所有图表/指标直接保存
2) 可视化优化:高DPI、紧凑布局、清晰坐标与标注
3) 混淆矩阵双版本:计数 & 归一化(百分比)
4) 指标保存:txt + csv;混淆矩阵保存:csv
5) 整图预测:可选,仅保存图片;同时保存预测数组(npz)
"""
import os
import time
import json
import numpy as np
import scipy.io as sio
import matplotlib
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import (confusion_matrix, classification_report,
accuracy_score, cohen_kappa_score)
# ===== 可视化中文支持 =====
matplotlib.rcParams['font.family'] = 'SimHei'
matplotlib.rcParams['axes.unicode_minus'] = False
# ===== 参数区(按需修改)=====
DATA_DIR = r"your_path" # ←←← 修改为你的数据路径
PCA_DIM = 30 # PCA主成分数
TRAIN_RATIO = 0.3 # 训练占比(仅在有标签像素上分层抽样)
SEED = 42 # 随机数种子
K = 5 # k-NN 的 k
DO_FULLMAP = True # 是否进行整图预测与保存
SAVE_ROOT = os.path.join(DATA_DIR, "knn_results")
# ===== 工具:统一保存路径 & 画图助手 =====
def make_save_dir(root):
t = time.strftime("%Y%m%d_%H%M%S")
d = os.path.join(root, f"run_{
t}")
os.makedirs(d, exist_ok=True)
return d
def save_fig(path, dpi=220):
plt.tight_layout()
plt.savefig(path, dpi=dpi, bbox_inches="tight")
plt.close()
def save_text(path, text):
with open(path, "w", encoding="utf-8") as f:
f.write(text)
# ===== 1. 加载数据 =====
X = sio.loadmat(os.path.join(DATA_DIR, "KSC.mat"))["KSC"].astype(np.float32)
Y = sio.loadmat(os.path.join(DATA_DIR, "KSC_gt.mat"))["KSC_gt"].astype(int)
h, w, b = X.shape
# 仅取非0标签像素的坐标与标签(转为0-based)
coords = np.argwhere(Y != 0) # (N,2)
labels = Y[coords[:, 0], coords[:, 1]] - 1 # (N,)
num_classes = labels.max() + 1
# ===== 结果目录 =====
SAVE_DIR = make_save_dir(SAVE_ROOT)
print

最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



