1. 项目概述:从Yelp爬取数据到真正读懂它
做Web Scraping,很多人卡在“能抓下来”就以为结束了——其实那只是万里长征第一步。我带过不少刚入门的数据爱好者,他们花两周时间调通Selenium脚本、绕过反爬、存下几万条Yelp餐厅评论,结果打开CSV文件发呆:字段一堆,rating、review_count、price、categories、neighborhood、is_closed、photos_count……但到底哪些字段真有用?用户打分集中在什么区间?高价餐厅是不是评价更少?带“$$$$”标签的店,平均评分真的比“$”高吗?有没有大量“4.5分但只有一条评论”的刷单嫌疑?这些疑问,光靠肉眼扫Excel根本无解。这就是为什么Part 3必须是EDA(Exploratory Data Analysis):它不是炫技的图表堆砌,而是用统计思维和可视化工具,对爬回来的数据做一次系统性“体检”。你不需要立刻建模预测,但必须先搞清楚数据的脾气、缺陷和隐藏信号。比如我第一次跑完Yelp旧金山湾区数据的EDA,就发现超过23%的商家标注了“Closed”,但其中近半数仍显示有近期评论——这直接提示我后续要加一层人工校验逻辑;又比如“price”字段里有大量空值,但通过关联“categories”(如“Steakhouse”“Fine Dining”)和“review_count”,我能反推出约68%的缺失价格其实是“$$$”或“$$$$”。这些洞察,全来自清洗后的分布图、箱线图、交叉热力图和异常值标记。这篇不讲Pandas语法基础,也不列教科书式定义,只分享我在真实Yelp数据上踩过的坑、验证过的分析路径、以及那些让客户当场拍桌说“原来还能这么看”的实操结论。
2. 数据整体设计与思路拆解:为什么EDA不能跳过,也不能乱做
2.1 EDA不是“随便画几个图”,而是有明确目标的数据诊断流程
很多初学者把EDA理解成“用Seaborn画点直方图”,结果产出一堆美观但无意义的图表。真正的EDA必须服务于三个刚性目标: 数据可信度验证、业务问题锚定、建模前提检查 。以Yelp数据为例,这三个目标具体落地为:
-
可信度验证 :检查爬取逻辑是否引入系统性偏差。例如,Yelp搜索页默认按“Best Match”排序,而该算法会动态注入广告位和合作商户,导致前3页高频出现同一连锁品牌(如Cheesecake Factory)。若未记录页面序号和排序方式,EDA中就会发现“连锁品牌占比异常高”,进而倒推爬虫需增加随机滚动延迟+模拟用户点击“Sort by: Highest Rated”。
-
业务问题锚定 :把模糊需求转化为可计算指标。客户说“想了解高端餐厅的口碑现状”,这太宽泛。EDA阶段就要拆解为:① 定义“高端”(用price字段+categories关键词匹配);② 定义“口碑”(非简单均值,需结合review_count做加权评分);③ 定义“现状”(对比近3个月vs历史均值的评分波动率)。我实际处理时发现,单纯用price=“$$$$”筛选出的餐厅,其平均评分(4.21)竟低于price=“$$$”组(4.37),但前者review_count中位数是后者的3.2倍——说明高价餐厅更依赖长尾好评维持口碑,而非单次高分。
-
建模前提检查 :确认后续分析的数学基础是否成立。比如想用线性回归预测评分,就必须验证残差正态性、变量间多重共线性。Yelp数据中,“review_count”和“photos_count”相关系数高达0.89,若同时放入模型会导致系数不稳定;而“rating”本身呈强右偏分布(大量4.0–4.5分,极少低于2.5),直接建模会低估低分风险,必须做Box-Cox变换。
提示:每次开始EDA前,强制写下这三句话:“我要验证数据哪一点可信度?”“我要回答客户哪个具体问题?”“下一步建模需要满足什么统计假设?”——写在Jupyter Notebook第一行,能避免陷入“为画图而画图”的陷阱。
2.2 为什么必须先清洗再EDA?一个真实翻车案例
去年帮一家本地餐饮咨询公司分析西雅图Yelp数据,我跳过深度清洗直接跑EDA,结果得出“咖啡馆平均评分(4.42)显著高于日料店(3.98)”的结论。客户兴奋地准备报告,我复核时发现:日料店数据中混入了大量“Sushi Bar”“Japanese Restaurant”等英文名店铺,但爬虫未过滤掉名称含“Sushi”的非日料店(如“Sushi Pizza”“Sushi Burrito”),且这些混杂店铺评分普遍偏低(2.1–2.8)。清洗后重新计算,纯日料店平均分升至4.26,与咖啡馆差距缩小到0.16分——这个差异已无统计学意义(t检验p=0.12)。这个教训让我固化了一条铁律: 所有EDA代码必须包裹在清洗函数之后,且清洗步骤需生成三份报告:缺失值热力图、异常值标记表、字段一致性校验日志 。比如Yelp的“is_closed”字段,表面是布尔值,但实际存在“True”“False”“null”“Closed”“Permanently Closed”五种取值,不统一就无法做有效分组统计。
2.3 工具链选型:为什么不用Tableau/Power BI,而坚持Python原生栈
有人问:“既然EDA重可视化,为啥不直接用BI工具?”——因为Yelp数据的脏和复杂,要求分析过程必须可追溯、可复现、可嵌入业务逻辑。Tableau拖拽式操作无法处理“对每个城市子集单独计算价格中位数,再映射回原始数据做分位数标记”这类需求。我们最终采用的组合是:
-
Pandas + NumPy :核心数据操作。特别强调
pd.cut()和pd.qcut()的区别:对“review_count”这种长尾分布,必须用qcut按分位数切桶(如0–25%为Low,25–75%为Medium),而非cut按固定数值切(如0–100为Low),否则90%数据会挤在第一个桶。 -
Matplotlib + Seaborn :定制化绘图。Seaborn的
catplot()能一键生成分面柱状图,但Yelp的“categories”字段是列表格式(如["Mexican", "Tacos", "Fast Food"]),需先用explode()展开再聚合,这个细节90%的教程都忽略。 -
Plotly Express :交互式探索。当需要快速验证“某类餐厅在不同价格档位的评分分布”时,
px.box(y="rating", x="price", color="categories", data_frame=df)一行代码就能钻取任意子集,比静态图高效十倍。 -
SciPy + Statsmodels :统计验证。计算“不同neighborhood的评分差异是否显著”时,用
scipy.stats.f_oneway()做单因素方差分析,比肉眼比较均值可靠得多。
这套组合的代价是学习曲线陡峭,但收益是:每张图的代码都能直接复用到生产环境的数据监控脚本中。比如我写的“评分突降检测”函数,现在每天自动扫描新爬数据,一旦发现某商圈周环比评分下降超0.3且review_count激增200%,就触发邮件告警——这正是从EDA中沉淀出的业务规则。





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



