Kaggle实战:用Python脚本一键整理EyePacs眼底数据集(附分类代码)
当你第一次从Kaggle下载EyePacs数据集时,面对混在一起的数万张眼底图片和CSV标签文件,可能会感到无从下手。作为数据工程师或算法初学者,如何高效地完成数据预处理的第一步——分类整理?本文将手把手教你用Python脚本实现自动化分类,解决这个实际痛点。
1. 准备工作与环境配置
在开始编写脚本前,我们需要先了解数据集的基本结构和准备必要的工具。EyePacs数据集通常包含两个核心部分:
train文件夹:存放所有未分类的眼底图片(JPEG格式)trainLabels.csv文件:包含每张图片对应的分类标签(0-4级)
推荐工具栈:
import pandas as pd # 处理CSV文件 import shutil # 文件操作 import os # 路径管理 from tqdm import tqdm # 进度条显示注意:建议使用Jupyter Notebook或VS Code等支持交互式编程的环境,方便调试和验证每一步操作。
2. 数据集目录结构设计
合理的目录结构是后续机器学习项目的基础。我们建议采用以下结构:
eyepacs_project/ ├── raw_data/ │ ├── train/ # 原始未分类图片 │ └── trainLabels.csv # 原始标签文件 └── processed_data/ ├── class_0/ # 分级为0的图片 ├── class_1/ # 分级为1的图片 ├── class_2/ # 分级为2的图片 ├── class_3/ # 分级为3的图片 └── class_4/ # 分级为4的图片提示:保持原始数据(raw_data)不变,所有处理都在processed_data中进行,这是数据科学项目的黄金实践。
3. 核心分类脚本实现
下面是一个健壮的分类脚本,包含错误处理和进度显示:
def classify_eyepacs_images(csv_path, src_img_dir, dest_dir): """ 根据CSV标签分类眼底图片 参数: csv_path: CSV标签文件路径 src_img_dir: 原始图片目录 dest_dir: 分类后目标目录 """ # 读取CSV文件 try: labels_df = pd.read_csv(csv_path) print(f"成功读取CSV文件,共{len(labels_df)}条记录") except Exception as e: print(f"读取CSV文件失败: {e}") return # 创建目标目录 for class_id in range(5): class_dir = os.path.join(dest_dir, f"class_{class_id}") os.makedirs(class_dir, exist_ok=True) # 分类图片 moved_count = 0 missing_count = 0 for _, row in tqdm(labels_df.iterrows(), total=len(labels_df)): img_name = row['image'] class_id = row['level'] src_path = os.path.join(src_img_dir, f"{img_name}.jpeg") dest_path = os.path.join(dest_dir, f"class_{class_id}", f"{img_name}.jpeg") try: if os.path.exists(src_path): shutil.copy2(src_path, dest_path) moved_count += 1 else: missing_count += 1 except Exception as e: print(f"移动{img_name}时出错: {e}") print(f"\n分类完成!成功移动{moved_count}张图片,{missing_count}张图片缺失")关键改进点:
- 使用
copy2代替move保留原始文件 - 添加了完善的错误处理
- 包含进度显示和统计信息
4. 实际应用与异常处理
在实际操作中,你可能会遇到以下常见问题及解决方案:
| 问题类型 | 可能原因 | 解决方案 |
|---|---|---|
| 文件不存在 | 文件名不匹配或下载不完整 | 检查文件扩展名(.jpeg/.jpg),验证下载完整性 |
| 权限错误 | 没有写入权限 | 检查目标目录权限,或更换有权限的目录 |
| 内存不足 | 数据集太大 | 分批处理,或使用更高效的数据结构 |
推荐执行方式:
# 配置路径 csv_path = "path/to/trainLabels.csv" src_img_dir = "path/to/train" dest_dir = "path/to/processed_data" # 执行分类 classify_eyepacs_images(csv_path, src_img_dir, dest_dir)5. 分类后验证与质量检查
完成分类后,建议进行以下验证步骤:
数量核对:
# 检查每个类别的图片数量 for class_id in range(5): class_dir = os.path.join(dest_dir, f"class_{class_id}") print(f"类别{class_id}图片数量: {len(os.listdir(class_dir))}")随机抽样检查:
- 从每个类别随机选择5-10张图片
- 肉眼检查图片是否与标签匹配
数据分布分析:
import matplotlib.pyplot as plt # 绘制类别分布图 class_counts = labels_df['level'].value_counts().sort_index() plt.bar(class_counts.index, class_counts.values) plt.xlabel('DR Level') plt.ylabel('Count') plt.title('Class Distribution') plt.show()
6. 进阶技巧与优化建议
对于大型数据集处理,可以考虑以下优化方案:
多进程加速:
from multiprocessing import Pool def process_image(row, src_img_dir, dest_dir): # 实现单张图片处理逻辑 pass with Pool(processes=4) as pool: results = pool.starmap(process_image, [(row, src_img_dir, dest_dir) for _, row in labels_df.iterrows()])增量处理:
- 记录已处理的图片名
- 支持断点续处理
- 避免重复处理相同文件
日志记录:
import logging logging.basicConfig(filename='classification.log', level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')7. 后续数据处理流程建议
完成基础分类后,通常还需要:
数据清洗:
- 去除低质量图片(模糊、过暗/过曝)
- 处理类别不平衡问题
标准化处理:
- 统一图片尺寸
- 去除黑色边框
- 应用CLAHE等增强技术
数据集划分:
from sklearn.model_selection import train_test_split # 按比例划分训练集和验证集 train_df, val_df = train_test_split(labels_df, test_size=0.2, stratify=labels_df['level'], random_state=42)
在实际项目中,这套分类脚本帮我节省了大量手动整理时间。特别是在处理35,000+图片的大数据集时,自动化流程的优势更加明显。记得在处理完成后,检查各类别的样本分布情况,这对后续建模策略有重要影响。