简介:《集体智慧编程》是一本经典的机器学习与数据挖掘入门书籍。这份配套资源收录了基于 Python 3.6 重新编写的代码和数据集,适合正在阅读原书、想要动手实践推荐算法、聚类分析、搜索排序等章节的 Python 学习者。压缩包中一共有 107 个文件,大小约为 14.52MB,其中主要包含 38 个 Python 脚本、8 个 Jupyter 笔记本,以及文本、CSV、数据库等数据文件;脚本部分对应书中各个核心算法的实现,笔记本适合边看边运行,数据文件则是案例中所需要的原始输入。目前已有 244 人学习或下载,可以配合原书按章节逐步进行验证。资源中还保留了多份经典评分与匹配数据集,能够直接用于电影推荐、相似性匹配等实验;目录结构非常清晰,README 和 Markdown 说明可以帮助快速定位代码,节省自己整理数据的时间,把更多精力放在理解算法原理和运行结果上。 《集体智慧编程》这本书,在我的技术书架上是少数几本“卖了又买、买了还舍不得卖”的经典。它在机器学习还没像今天这么“卷”的时候,就把推荐系统、聚类、搜索排序这些听着唬人的概念,用最朴素的Python代码摊开在读者面前。我这次整理的这套基于Python 3.6的代码和数据集(Programming-Collective),就是当年一边啃书一边手工重写、后来又在实际项目中反复翻用的成果。
很多人看这本书最大的拦路虎,是原版代码停留在Python 2的时代,print是语句而不是函数,字典遍历顺序不确定,还有一堆Unicode编码的暗坑。我做的这件事,本质上就是“扫雷式”地重写全部代码,不改变原书的算法逻辑和参数设定,只把语法迁移到Python 3.6,并把网盘里散落的数据集归好类、整理成可以直接喂给代码的格式。这套资源适合谁?刚入门机器学习、想理解算法底层原理的自学者,备赛数据科学岗、需要快速梳理经典算法实现的求职者,以及在真实项目中想避开重复踩坑的开发者——都可以在这套代码里找到自己想要的东西。
整件事做下来,最有价值的其实不是“代码能跑了”这个结果,而是过程中对每个算法实现细节的反复推敲。这篇文章我打算从书的内容结构、代码库设计思路、数据集的坑、环境搭建、迁移避坑几个维度,把整套东西讲透,希望能给你省下实实在在的几周时间。
1. 这本书的技术脉络与代码重写的价值
《集体智慧编程》全书的组织结构是典型的“每章一个独立算法模块”,从协同过滤推荐开始,逐步过渡到聚类、搜索排序、决策树、神经网络、支持向量机等经典方法,最后以核方法和股票预测收尾。这本书最大的特点是不堆数学公式,而是用几百行Python把每个算法的来龙去脉交代得一清二楚。
1.1 从推荐系统到核方法:各章节解决的问题
第二章讲协同过滤,通过用户对物品的评分数据,用欧氏距离和皮尔逊相关系数计算用户相似度,实现“看了还看”“买了还买”的推荐逻辑,这是整本书最容易被理解也最实用的一章。第三到四章是聚类,从层次聚类到KMeans,用博客订阅源的数据集把相似用户或文章自动分组。第五章是搜索排序,核心是倒排索引和PageRank的思想在垂直搜索场景下的应用,第六章则引入了贝叶斯分类器,解决垃圾信息过滤的问题。
第七章决策树建模,把“是否点击广告”这类分类问题转化为树形规则,可解释性极强。第八章是数值预测,基于线性回归和核平滑方法,适合类似房价预测的场景。第九到十章是支持向量机和神经网络,虽然代码实现相对简洁,但概念密度很高,值得反复咀嚼。第十一章引入核方法,进一步拓宽了SVM的应用边界,最后一章是股票预测案例,把前面所有技术串联起来。
1.2 为什么必须做Python 3.6迁移
原书的代码大多是基于Python 2.x语法,这在2010年左右完全没问题,但放到今天基本跑不动。Python 2到3的核心差异说大不大,说小不小,真正动手改的时候才会发现一个个坑:print关键字变成函数、dict的keys()方法从列表变成视图对象、reduce被移动到functools模块、异常捕获语法变化等。
最烦人的其实是Unicode处理。原书在读取数据文件时习惯用普通字符串处理,在Python 2里只要不碰到特殊字符就相安无事,Python 3里则常常出现编码转换错误。我统一在代码入口处用utf-8编码打开文件,并将所有文件读取操作封装成工具函数,这样后续再往代码里加数据文件,只需要调用这一层封装,不必每次处理编码的脏活累活。
原作者写代码时的风格非常简洁,有些变量命名随意、逻辑压缩在一行里。我在保持算法思路一致的前提下,适当补充了注释,尤其是每个函数输入输出说明和核心算法的关键步骤解释。不过我没有做大规模的“重构式”改名,因为那样会让对照原书阅读的体验变差,读者要的是算法逻辑原汁原味,而不是一个面目全非的新程序。
1.3 重写后代码库的适用人群与场景
这套代码不是工业级的工程代码,没有复杂的类继承和设计模式,但它非常适合做算法入门和基础面试准备。如果你正在准备推荐算法、搜索排序相关的面试,把第二章的协同过滤和第五章的PageRank代码吃透,比背十篇面试总结都管用。
另外有一类人群也很适合:工作中需要做算法POC(概念验证)的工程师。我经常遇到的情况是,一个功能用scikit-learn一行搞定,但领导想知道“这个效果的底层逻辑是什么”,这时候翻开这本书对应的章节,用这套代码跑一遍,马上就能讲清楚原理和实现边界。我自己曾经在做一个垂直搜索排序优化项目时,就是用第五章的倒排索引代码当成基准(baseline)对比,快速验证了新排序方案的提效空间。
2. 代码库设计与模块规划
整个项目我按照原书的章节结构划分目录,一个章节一个文件夹,每个文件夹都包含可独立运行的Python文件和对应的数据文件。这样的组织方式有几个明显的好处:可以按章节顺序学习,也可以直接跳到感兴趣的算法;每个模块不依赖其他章节的代码,减少环境配置的复杂程度;数据文件跟着章节走,避免找数据的额外成本。
2.1 各章节代码模块的功能划分
以下是代码库的核心目录结构和主要模块:
- chapter2(推荐系统):recommendations.py、data/(评分数据集)
- chapter3(聚类):clusters.py、data/(博客订阅源数据)
- chapter4(搜索与排名):search.py、data/(网页索引数据)
- chapter5(优化):optimization.py、data/(航班数据与偏好数据)
- chapter6(文档过滤):docfilter.py、data/(垃圾邮件数据集)
- chapter7(决策树):treepredict.py、data/(用户行为数据集)
- chapter8(数值预测):numpredict.py、data/(葡萄酒价格数据集)
- chapter9(SVM):svm.py、data/(分类测试数据)
- chapter10(神经网络):neuralnet.py、data/(手写数字和图像数据)
- chapter11(核方法):kernel.py、data/(测试数据)
- chapter12(股票预测):stock.py、data/(历史股价数据)
每个模块我都保留了一段与书籍代码联动的测试代码,通常在文件末尾的main函数中,这样运行单个文件就能看到结果,不必额外编写测试脚本。例如chapter2的recommendations.py里不仅有核心的sim_distance和sim_pearson函数,还包含获取推荐函数getRecommendations,可以直接对内置数据集进行验证。
2.2 代码风格与兼容性设计策略
因为这本书的定位是算法原理解析,代码质量的第一优先级不是性能或者极致工程化,而是可读性和与正文描述的对应关系。我在重写过程中遵循了几条原则,保证这套代码既能跑通,又不失去“教学代码”的初心。
一是保留原有的函数名和变量名,比如recommendations.py里的critics字典、clusters.py里的pearson距离计算函数,确保读者对照原书可以轻松定位代码位置。二是所有Python 2特有的语法糖会做等价替换,比如用列表推导替代局部的filter和map,但算法主体不用过度“Pythonic”的重写,避免引入新bug。
三是统一处理输入输出编码。我在代码库根目录放了一个common.py工具模块,封装了文件读取、数据清洗和结果输出三个常用函数。所有章节的代码在读取数据文件时都统一调用这个模块的方法,好处是只要有数据文件出现编码问题,只需改动一个地方,不用逐个文件打补丁。
四是Python版本限制问题。代码基于Python 3.6,因此可以使用f-string、dataclasses这些新特性,但这套代码的阅读对象有很多初学者,我尽量少用过于“高级”的语法,保持代码的普适性。实际验证发现,除了依赖第三方库(比如numpy和matplotlib)的章节,大部分代码可以直接在Python 3.10以上的高版本跑通,没有明显的兼容性问题。
2.3 依赖管理与虚拟环境配置建议
项目依赖的主要Python库包括numpy、matplotlib、PIL和BeautifulSoup4。numpy用在聚类和数值计算章节,matplotlib用在可视化聚类树和绘制测试结果,PIL是实现神经网络章节图像数据读取的基础,BeautifulSoup4则用于第四章搜索功能中抓取网页的预处理。
我不建议把依赖包直接装进系统全局环境,比较容易出现包版本冲突。推荐用venv创建一个项目独立的虚拟环境,然后安装一个包含所有依赖的requirements.txt。具体的安装命令在第三节会有详细说明,这里先给一个关键的提醒:如果你的网络环境安装第三方库很慢,可以临时切换为国内的镜像源,但生产环境建议还是用官方源以保证包的完整性。
3. 数据集的获取、格式与使用说明
《集体智慧编程》每一章节都配套了相应的数据集,这些数据有些是原书作者从公开数据源整理的,有些是示例用途的模拟数据,但它们的格式都不太一样:有纯文本格式的,有带表头的CSV格式,还有特殊的JSON格式。在重写代码时,我把这些数据全部转成了统一的、容易解析的格式,并重新整理了数据目录,让初学者可以直接把数据集拿来练习。
3.1 关键数据文件与格式解析
各章节数据格式差异比较大,这里先做一个整体说明,避免在运行代码时因为格式不了解而导致报错。
- 第二章的评分数据是Python字典的字面量格式,这是最简单的一种,直接用赋值即可,不需要文件解析。
- 第三章的博客订阅源数据是三个文本文件,每行代表一篇文章的词频统计,格式为“标题:单词”,词与词之间用空格分隔,这部分数据在做聚类之前需要预先解析成向量。
- 第四章的搜索数据是html目录下的多个网页文件,代码会读取网页内容建立索引,所以数据文件本身没有统一的文本格式。
- 第六章的文档过滤数据是多个文本文件,分为正常邮件和垃圾邮件两个目录,每个文件对应一封邮件的正文内容。
- 第十二章的股票数据是从雅虎财经下载的历史价格数据,格式是标准的CSV,列分别为日期、开盘价、最高价、最低价、收盘价和成交量,代码可直接读取。
我在整理数据时做了两件事:一是确保每个数据文件的编码统一为utf-8,避免Windows平台和Mac平台间的乱码问题;二是对缺失的股票数据做了简单的过滤,删除异常行和全部为空的行,确保后续数值计算不会因为空值报错。另外,如果读者想扩充自己的数据集,完全可以替换这些数据文件,只需要保持同样的格式就能跑通算法,这也是我改进过的代码相比原版更方便的方面之一。
建议读者在第一次运行代码时,先通过print(len(data))之类的语句查看一下数据长度,确保数据被正确加载,再进行后续训练,这样可以很快地区分“代码问题”和“数据问题”,提高排查效率。
3.2 数据清洗与预处理的优化细节
对于非结构化的数据,原书大致采用正则表达式和分词方式提取特征。我在实现时在中文场景下做了个小调整:由于原书的数据集是英文文本,如果后续有中文需求,直接套用原书的分词逻辑可能会出问题,比如英文按空格分隔、中文却需要按词语切分。鉴于这本书面向的是算法逻辑本身,我没有额外加入中文分词功能,而是把这个扩展作为读者练习的一部分,如果你真的需要处理中文文本,直接在文件读取阶段换成jieba分词,其他逻辑都可以复用。
对于数值型数据,比如葡萄酒价格数据集和股票数据,原书中已经做了归一化处理。我在整理过程中进一步检查了数据的分布情况,发现个别特征存在异常高的离群值,比如年份字段不小心被读成了当前的年份。这类异常通常会导致预测结果严重偏离,建议在学习到第八章数值预测、第十二章股票预测时,先打印出数据的基本统计信息,比如最大值、最小值和均值,确保数据质量再做后续操作。这也是实际项目中做特征工程的第一步,养成习惯会很有帮助。
3.3 数据集使用的常见误区
有些读者可能会在数据集使用上进入几个误区。第一个误区是直接拿原书的数据集去跑现代的深度学习模型,这完全没有必要,原书的数据规模很小,是为理解算法原理服务的,并不适合直接作为深度学习benchmark。第二个误区是试图在Anaconda的环境里直接import book的数据模块而忽略相对路径问题,这个在第五节会详细说明,这里先提醒一下,运行代码前需要先在终端中进入对应的章节文件夹。
其次,关于原书中的部分数据来自动态网页抓取,比如第四章的搜索索引数据如果找不全,代码可能会报错“找不到文件”。我整理的版本包含了完整的示例网页数据,即使处于无网环境也可以直接跑代码,这一点请放心。如果有读者希望更新或扩充数据,建议保留原始数据的文件名,否则需要同步修改代码中的数据加载路径。
4. Python 3.6环境搭建与实操运行
4.1 虚拟环境创建与依赖安装
我以macOS/Linux环境为例,Windows平台的操作本质一样,只是激活虚拟环境的命令有所不同。
打开终端进入代码库目录,执行以下命令创建并激活虚拟环境:
cd Programming-Collective python3.6 -m venv venv source venv/bin/activate # Windows下为 venv\Scripts\activate pip install --upgrade pip pip install -r requirements.txt如果本机没有安装Python 3.6,建议通过pyenv或conda来安装对应版本。因为你只是运行教学代码,Python版本不必要求非常严格,实测Python 3.7到3.10的大部分代码也能正常运行,只是f-string语法需要Python 3.6以上,所以低于3.6就不建议了。
4.2 各章节目录下的运行示例
依赖装完之后,直接进入某一章节的文件夹运行对应脚本即可。以协同过滤为例:
cd chapter2 python recommendations.py正常情况下你应该会看到针对用户“Toby”的推荐结果输出。我在这里加了一个小的演示函数,运行后除了打印推荐结果,还会打印出与Toby最相似的两个用户及其相似度分数,方便初学者观察协同过滤的中间过程。其他章节的运行方式一样,只需修改文件夹和文件名。
对于会在屏幕输出图片的章节,比如第三章的聚类树状图和第九章的SVM分类结果,请确保运行环境支持图形界面显示。如果你用的是纯命令行的服务器,可以将matplotlib的backend切换为Agg,或者在代码中把图片保存到本地文件,这一点在代码注释中有注明。
4.3 运行过程中遇到常见依赖问题的快修方案
实测中最容易遇到的问题有两个:一是提示缺少PIL模块,这是历史遗留问题,曾经的包名是PIL,现在则统一用Pillow代替。安装方法很简单,直接执行pip install pillow即可。二是matplotlib中文显示乱码,这个问题在本书代码中其实不太会出现,因为原书案例基本都是英文标签,但如果读者在做自己的数据时需要显示中文标题,需要额外配置中文字体,否则会变成方块。
我更想强调的是一个容易被忽略的细节:确保当前的工作目录是在对应的章节文件夹内。不少初学者把代码文件放在Programming-Collective根目录下直接运行,然后报错“找不到数据文件”。这不是代码的问题,而是相对路径的问题。解决方法是先cd到章节目录,再运行脚本,或者代码内部用os.path.dirname(os.path.abspath(file))获取脚本所在目录,实现路径无关化加载,我提供的版本已经统一用后者处理。
5. 常见问题与排查技巧实录
5.1 代码迁移中典型的Python 2到3的坑
我在重写这套代码时,统计了一下最常见的报错类型,其中一大半来自Python 2到3的语法变化。比如print函数报错,Python 2中print "hello"在Python 3中会直接语法错误,需要在字符串外面加括号。这大概是最容易排查也最容易修复的问题。
更深一点的坑在于字典的遍历顺序。Python 3.7开始字典保持了插入顺序,但Python 3.6还属于实现细节,如果在代码中对字典先插入再遍历,逻辑一般是稳定的,但如果要跨字典按键排序,建议明确使用sorted(dict.items()),不要依赖解释器行为。原书代码中有些位置为了解决“每次结果不一样”的问题,把数据转成了set再遍历,这会导致结果顺序不可预测,我在重写时统一改为list排序,保证结果可复现。
5.2 数据文件缺失或损坏时的排查流程
遇到“文件不存在”或“数据为空”的报错,建议按照四个步骤排查:第一步,检查文件路径是否在正确的目录下;第二步,检查文件大小是否合理,如果文件大小为0或者异常小,大概率是下载或者同步出了问题;第三步,用文本编辑器打开文件,查看首行数据内容是否符合预期格式;第四步,检查是否因为文件开头包含BOM(Byte Order Mark),导致首列数据被读入了不可见字符,这个问题在Windows平台用记事本保存CSV时特别常见,直接在代码读取时补充encoding='utf-8-sig'就可以解决。
在数据预处理环节,如果报“list index out of range”的错误,不管是Python列表还是numpy数组,大概率是读取的数据行中有空行或者列数不一致。建议在读取数据的循环中增加if len(row) > expected_cols这样的判断,把不符合规则的行打印出来,这样你能快速定位到具体是哪一行数据异常,然后手动修复。
5.3 实操心得:三个值得反复调试的算法
在我的学习经历里,有三个代码实现是值得反复运行和打断点调试的,即使在今天看来依然收获巨大。
第一个是第三章的层次聚类代码。它用字典构建聚类树,递归生成树状图,代码量虽小但数据结构很精妙,理解了它,你对递归和字典在算法中的应用就上了一层台阶。我在代码中加入了一些打印语句,每次合并两个聚类时都会输出是哪两个聚类、距离是多少,配合matplotlib画出的树状图,靠这个可视化反馈能非常直观理解层次聚类的合并逻辑。
第二个是第七章的决策树代码。原书实现了信息熵、基尼不纯度两种分支标准,又用递归的方式生成树结构,最终展示可读性很好的规则树。这段代码是学习树形模型最好的起点,比sklearn的DecisionTreeClassifier可视化更容易“长”在脑子里,因为它每一步都显式地暴露了规则的选择过程。我在实现时补充了print树叶节点规则的逻辑,每一步都可见可懂。
第三个是第九章的支持向量机代码。这里用的是简化的SMO(序列最小优化)算法,细节很多,初看很容易绕进去,但只要把坐标上升和KKT条件梳理清楚,整个算法就不再神秘。我的代码里包含了每次迭代参数变化的打印信息,可以帮助读者理解SVM训练过程中目标函数是如何一步步下降的。
这三个算法花一个周末吃透,比啃三周机器学习理论更有效,这也是我屡次推荐这本书的一个深层原因。
5.4 扩展建议:从示例代码到实际项目
如果把这套书里的代码学扎实了,下一步可以把它当成自己的“算法工具箱”。我曾经用第二章的协同过滤做电视节目推荐,性能虽比不上深度的推荐模型,但做冷启动阶段的baseline非常合适;用第四章的搜索排序做企业内部文档检索,几百篇文档的规模完全够用;使用第八章的数值预测算法做商品价格的趋势判断,在数据量几千的场景下精度也可接受。学算法不应只停留在看完、跑通,而是尝试替换成自己的数据和场景,让这些代码在职场上真正产生价值。
有一点必须说明:这本书本身的年代决定了它没有涉及深度学习、大规模分布式训练这些现代概念,如果你希望用它来了解目前如火如荼的大型语言模型,那并不是合适的教材。但正因为它的算法足够底层,一旦掌握了这些基础,后续理解更复杂的模型通常会顺手得多。
最后,这套代码和数据集的完整内容,我建议你下载后先用两天时间老老实实把前三个章节跑通,在此基础上再决定是否需要深入后期章节。如果你在运行过程中遇到问题,很有可能也是我踩过的坑,先检查编码、再检查路径、最后检查代码版本,大概率能解决绝大多数问题。
本文还有配套的精品资源,点击获取