2、数据采集与标注:公开数据集获取、爬虫基础(Requests/Scrapy)、数据清洗与标注工具(LabelImg)入门
大家好,欢迎来到第二章。
上一章我们聊了项目怎么规划,环境怎么搭。这一章,咱们得解决一个很现实的问题——数据从哪来?
说实话,我见过不少同学,模型架构背得滚瓜烂熟,一到自己动手就卡住了。为啥?手里没数据。你想想看,巧妇难为无米之炊嘛。这一章,我就带你把这「米」的问题搞定。
2.1 公开数据集:站在巨人的肩膀上
做项目最省力的办法,就是直接用别人整理好的数据集。我个人习惯,先上这几个地方翻一翻:
- Kaggle Datasets:社区活跃,质量参差不齐,但胜在种类多。我经常在上面找一些竞赛用的基准数据集。
- Papers with Code:这个好,论文和数据集绑在一起。你想复现哪篇论文,直接去这里找对应的数据。
- 天池、DataFountain:国内平台,中文场景的数据集比较多,比如电商评论、中文OCR之类的。
- UCI Machine Learning Repository:老牌数据集库,适合做基础研究,数据都比较干净。
不过要注意,公开数据集不是拿来就能用的。我在项目中遇到过一个问题:一个公开的人脸数据集,标注框的格式跟我的模型要求不一样。嗯,这里要注意,数据集的「领域匹配度」和「标注格式」,这两个点一定要先确认好。
2.2 爬虫基础:自己动手,丰衣足食
公开数据集找不到你要的?那就自己爬。说白了,爬虫就是模拟浏览器去访问网页,然后把网页上的数据拿下来。
我刚开始学爬虫时,总觉得这东西很神秘。其实核心就两件事:发请求 和 解析响应。
2.2.1 Requests 库:最基础的爬虫工具
Python 的 requests 库,是爬虫的入门标配。它帮你把 HTTP 请求封装得特别简单。
import requests
# 发一个 GET 请求
url = "https://example.com/api/data"
response = requests.get(url)
# 检查状态码
if response.status_code == 200:
# 解析 JSON 数据
data = response.json()
print(data)
else:
print(f"请求失败,状态码:{response.status_code}")
你看,就这么几行代码,就能拿到数据了。不过,真实场景没这么简单。我曾经爬一个电商网站,直接发请求返回的是 403 错误。为啥?因为网站检测到我不是真人浏览器。
解决办法也很简单——加个请求头,伪装成浏览器:
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
}
response = requests.get(url, headers=headers)
time.sleep(1),模拟人的浏览速度。尊重别人的服务器,也是保护自己的数据源。
2.2.2 Scrapy 框架:批量爬取的正确姿势
如果你要爬的数据量很大,比如几千页的商品信息,用 Requests 一个个写循环就太累了。这时候就该 Scrapy 上场了。
Scrapy 是一个异步爬虫框架。说白了,它就像一个流水线工厂:你告诉它「去哪个网站、拿什么数据」,它自动帮你并发处理,效率高得多。
一个简单的 Scrapy 爬虫大概长这样:
import scrapy
class MySpider(scrapy.Spider):
name = "example_spider"
start_urls = ["https://example.com/page/1"]
def parse(self, response):
# 提取当前页的数据
for item in response.css("div.product"):
yield {
"title": item.css("h2::text").get(),
"price": item.css("span.price::text").get(),
}
# 翻到下一页
next_page = response.css("a.next::attr(href)").get()
if next_page:
yield response.follow(next_page, self.parse)
你想想看,用 Requests 你要手动写循环、处理异常、控制并发。Scrapy 把这些都封装好了,你只需要关注「怎么提取数据」就行。
2.3 数据清洗:把「脏数据」变成「干净数据」
数据拿到手了,但别高兴太早。真实世界的数据,脏得超乎你想象。我见过一个数据集,里面居然有 HTML 标签、乱码、空值混在一起。这种数据直接喂给模型,模型能学出个啥?
数据清洗,说白了就是做三件事:
- 去重:重复的数据会让模型产生偏见。
- 处理缺失值:要么删掉,要么填充(比如用均值、中位数)。
- 格式统一:比如日期格式、文本编码,全部转成统一的格式。
举个例子,用 Pandas 清洗 CSV 文件:
import pandas as pd
# 读取数据
df = pd.read_csv("raw_data.csv")
# 去重
df = df.drop_duplicates()
# 处理缺失值:删除包含空值的行
df = df.dropna()
# 格式统一:把文本转小写
df["text"] = df["text"].str.lower()
# 保存清洗后的数据
df.to_csv("clean_data.csv", index=False)
嗯,这里要注意,清洗规则不是固定的。你得先看看数据长什么样,再决定怎么洗。我一般会先打印 df.info() 和 df.describe(),快速了解数据概况。
2.4 标注工具入门:LabelImg 实战
如果你做的是目标检测项目,那就绕不开数据标注。说白了,就是告诉模型:「这张图里,这个框框里是一只猫。」
LabelImg 是我用得最多的标注工具。它免费、开源、跨平台,支持 YOLO 和 Pascal VOC 两种主流格式。
2.4.1 安装与启动
安装很简单,一行命令:
pip install labelImg
然后在终端输入 labelImg 就能启动了。界面很简洁,左边是工具栏,中间是图片区域。
2.4.2 标注流程
- 打开图片文件夹。
- 点击「Create RectBox」,在目标周围画框。
- 输入标签名称(比如 "cat"、"dog")。
- 保存标注结果(默认生成 XML 文件)。
- 按快捷键
W继续下一张。
我个人习惯,标注前先定好标签规范。比如所有类别都用英文小写,不要混用大小写。我曾经因为 "Cat" 和 "cat" 两个标签,导致模型训练时报错,排查了半天才发现是大小写问题。
W 画框,A 上一张,D 下一张,Ctrl+S 保存。熟练之后,标注速度能快一倍。
2.5 本章小结
这一章我们走完了数据采集到标注的全流程。你想想看,从找公开数据集,到用爬虫自己抓,再到清洗脏数据,最后用 LabelImg 打标签——每一步都是在为模型准备「食物」。数据质量决定了模型的天花板,这话一点不夸张。
下一章,我们会正式进入模型训练环节。到时候你会发现,数据准备得越充分,训练过程就越顺畅。咱们下章见。