犹他大学-CS6140-数据挖掘笔记-全-
犹他大学 CS6140 数据挖掘笔记(全)
001:课程概述

在本节课中,我们将学习犹他大学CS6140数据挖掘课程的整体安排、课程目标、评估方式以及核心主题。课程由Anna Maravic教授主讲,旨在为学生提供处理大规模数据分析所需的理论基础和实践技能。
课程介绍与个人背景
欢迎来到数据挖掘课程。我是Anna Maravic教授,我将担任本课程的讲师。我对这门课程怀有特殊的情感,因为在我决定从事机器学习和自然语言处理研究之前,我的专业是纯数学,没有任何计算机科学背景。当时我选修了一门类似的课程,它为我打开了一个全新的世界,并激励我开始学习更多机器学习课程,最终成为了一名自然语言处理领域的研究者。我希望这门课程至少能激发部分同学的好奇心。
需要说明的是,本课程的大部分材料和幻灯片借鉴自Jeff Phillips教授,他是这门课程的原始设计者。
今天的课程不会涉及正式的教学内容,我们将主要介绍课程的后勤安排,大约需要50分钟。之后我们会稍作休息,然后简要概述本课程将要讨论的主题,让大家对课程内容有一个初步的了解。
课程后勤与资源
课程的后勤安排部分没有配套幻灯片,这与后续的正式讲座不同。这也是唯一一次使用幻灯片的讲座。从下周三开始,我将使用iPad书写,并将内容投影到屏幕上,以模拟使用白板的教学方式。
本课程将被录制并实时直播。你可以在名为“Ufo data science”的YouTube频道上观看直播或回放。然而,如果出现无法在5-10分钟内解决的技术故障,我将继续进行线下授课,届时将没有录制内容。因此,如果完全依赖录制内容来学习,将存在一定风险。你可以选择线下上课或在家观看直播。
我建议你尽量跟上讲座的进度。如果积压了太多视频内容,将很难跟上后续材料,完成作业也会非常困难。请选择最适合你的学习方式,但我推荐你至少与线下授课同步观看。
如果没有问题,我们将继续介绍相关信息。
课程网站与大纲
首先,你需要在Canvas页面找到课程大纲,其中包含了本课程所需的大部分信息。此外,还有一个与课程相关的网站。大纲和网站上的信息是互补的,你需要同时使用这两个资源来学习课程。
在网站上,你可以看到一些基本信息,包括我之前提到的YouTube频道链接、我的邮箱、办公时间等。办公时间安排在每次讲座之后,地点在本教室。由于讲座结束后10分钟有另一门课,我们无法长时间停留,但我和助教们会在另一个房间继续提供帮助。
以下是我们的助教团队:L today Jo、Summer、Behi、Han、Nate和Vinuta。他们几乎可以像我一样为你提供帮助,请在有需要时联系他们。稍后我会详细介绍如何找到我们以及如何与我们沟通。
再次强调,每个人的办公时间都列在网站上。部分办公时间将通过Zoom进行,例如周二下午4点到5点,以及周四中午12点到1点。这对于需要兼顾工作和学习,或主要依赖录制内容的同学可能很有帮助。
在网站上,你还可以找到课程安排表。表格中列出了每个日期的讲座主题、项目组成部分的详细信息,以及作业和考试的截止日期。我建议你主要依赖Canvas来查看确切的截止日期和时间,因为作业发布和提交都在Canvas上进行。但网站上的日程表可以帮助你了解重要日期的大致分布。
你可以看到,作业的布置非常有规律,总共有8次。请提前规划好这些重要日期。除了作业和项目,还需要记住的日期是3月1日的中期考试和5月3日的期末考试。这些考试都是线下进行的,请务必将其加入你的日程表。
让我们回到课程大纲。到目前为止有任何问题吗?
好的,我们继续。
先修知识与背景要求
已经有同学询问学习本课程前需要掌握哪些知识。对于研究生没有正式的课程要求,但对于本科生有正式的先修课要求:需要修读“数据分析基础”和一门“软件开发”类课程。
这是因为本课程假设你已经牢固掌握了线性代数和概率论的基础知识。如果你觉得需要复习这些内容,请自行回顾。我会在课程中指明相关教材的章节,其中涵盖了所有基础知识。如果你觉得有必要,我强烈建议你进行复习,因为我不会在课堂上详细讲解线性代数和概率论的每一个细节,我们将直接在此基础上学习更高级的技术。
CS3500(软件开发课程)作为先修要求的原因是,本课程包含编程作业,我们不会提供极其清晰的实现指令。这样设计的理念是模拟现实世界,在现实中你通常也不会得到非常明确的编程指示。如果你从未上过需要自主编程的课程,完成作业可能会更具挑战性,需要花费更多时间。
此外,本课程的学生背景多样,不仅有计算机科学专业的学生,还有数据科学、数学或其他领域的学生。有些同学可能从未上过严格的编程课程,这意味着对于计算机科学专业的同学可能很快完成的作业,对其他同学来说可能需要更多时间。如果你从未真正编程过,所需时间可能会更长。这是你在考虑作业时需要了解的背景信息。
我之前提到会指明教材中需要复习的章节。这些章节是《数据分析的数学基础》的第1、3章以及第2、5、7章的开头部分。这本书由Jeff Phillips教授编写,有在线免费版本。课程中的引用将指向这个在线版本,而非需要购买的纸质版。
也许我们可以打开看看它的样子。第1、2、3章涵盖了这些基础知识。但下周三,我们将讨论第2章中的部分内容,所以如果你需要复习,最好先关注第1和第3节。
让我返回看看是否遗漏了什么。是的,在本课程以往的版本中,对编程语言没有要求,但我强烈建议你使用Python。因为Python目前已成为数据挖掘、数据科学相关工作的主流编程语言,拥有大量优秀的库,并且可以轻松处理各种数据文件。如果你偏好其他编程语言,我不会强行阻止,但我们推荐在本课程中使用Python。
关于先修知识就介绍到这里。我提到过本课程学生背景多样,因此我们在作业中设置了额外的加分题,这些题目旨在吸引对特定主题感兴趣的同学。你可以在作业中寻找这些题目,看看是否有你感兴趣的内容。
此外,在项目部分,我们也会考虑到这种多样性。你可以在项目中灵活选择主题,展示你来自本专业的专长和知识。
到目前为止有任何问题吗?好的。
教材与参考资料
本课程主要基于三本教材。第一本是之前提到的《数据分析的数学基础》。此外,还有Jeff Phillips教授编写的讲义。我会使用这些讲义来备课,并可能添加一些注释。如果我添加了任何内容,一定会与你们分享。这些讲义可以在课程网站上找到,点击每节课的“笔记”链接即可获取。
这些讲义基本上是那本我们常提到的书(我简称为M4D)的一个不那么精致的版本,并且顺序与书的章节不同,因为讲座的顺序也与书不同。
另外两本教材是《挖掘海量数据集》和《数据科学基础》。前者包含较少的数学形式和证明,而后者则主要关注我们所讨论内容的证明。M4D则介于两者之间。
这些书都不是必须购买的,它们都有在线版本,你可以根据需要免费阅读。特别是如果你对证明更感兴趣,一定要看看《数据科学基础》这本书。本课程中会有一些证明,但不会太多,而这本书里有很多。
好的,我们继续。
沟通渠道与办公时间
我们将使用Canvas发布所有通知,并使用其讨论区功能解答关于作业、项目、课程材料或日程安排的任何问题。关于是在Canvas讨论区发帖还是给我发邮件,有一个简单的判断原则:首先,想想助教是否能回答这个问题,而不仅仅是讲师;其次,这个问题是涉及更多人,还是仅与你个人相关。如果你有个人紧急情况,应该给我发邮件。如果你有一个关于作业的问题,并且认为班上其他同学也可能有同样的问题,最好在讨论区发帖。这样我们只需回答一次,所有人都能看到答案,可以减少重复提问,让我们能处理其他尚未解决的问题。
Canvas讨论区是与我们沟通的首选方式,因为有更多的人可以查看,所以你的问题得到更快回答的几率更高。如果你只给我发邮件,我会尽力回复,但如果邮件太多,难免会有延迟。我们已经安排好每天都有专人检查Canvas讨论区,确保能及时回答你们的所有问题。
我们也将使用Canvas提交作业。作业和项目组成部分都将在Canvas上发布和提交,成绩也会通过Canvas沟通。所以,Canvas是处理大部分课程事务的地方。
重申一下,除非是个人紧急情况,否则请将任何问题发布在Canvas上。但请不要在讨论区发布任何作业答案。如果我们发现此类信息,会立即删除。
其他活动,如查看日程、课堂笔记和视频,将通过这个公开对外的网站进行。
如果你需要私下联系我,可以在课程大纲顶部找到我的邮箱。实际上,如果你在Canvas中点击“收件箱”,效果与发送邮件相同,可以节省你在不同应用间切换的十几秒时间。
除了发送邮件(我认为这是效率最低的联系方式),你还可以参加办公时间。如果你无法参加任何列出的办公时间,请给我们发邮件,我们可以另约时间见面。网站上列出了所有的办公时间,包括线下和Zoom办公时间,希望能满足大家的不同需求。
当然,你也可以在讲座结束后立即提问。如果问题简短,只需要5到10分钟的解答时间,可以在讲座后直接问我。但之后,我们会在MEB 3515房间安排每次讲座后的办公时间。
我们设计办公时间时考虑到作业总是在周三截止,因此在周一、周二和周三安排了更多的办公时间,假设你们在提交作业前需要更多帮助。但如果你开始得较早,周四也有办公时间可以提供帮助。
我个人不在周末或晚上工作,所以除非有重大例外情况,否则你在那些日子不会收到我的回复。助教可能会根据自己的情况回复,我不确定。但我们会在周五晚上和周一早上检查Canvas讨论区。
总之,我们真心希望为你们提供帮助。如果有任何方式我们可以帮助你,请告诉我们。我们愿意提供你成功完成课程所需的任何帮助。请充分利用这些办公时间,与我们交流。
关于这部分有任何问题吗?好的。
课程评估方式
接下来,我们来看看课程评估部分。
你的成绩将由三种方式评估。
首先,作业将占你总成绩的40%。总共有8次作业,大致涵盖课程前半部分和后半部分的主要主题。每次作业通常围绕一个主题,例如统计原理、哈希、LSH等。作业通常包含分析性问题,有时也会要求编程练习,首选语言是Python。
其次,有两次考试,各占10%,分别覆盖课程的前半部分和后半部分。考试是开卷的,你可以带一张纸的笔记,但不允许使用电脑或计算器。考试必须线下进行,除非有医疗紧急情况或与其他考试冲突,否则不能调整考试时间。如果有医疗紧急情况,我们需要医生或辅导员的证明文件。
最后,项目部分占总成绩的40%。这部分内容较多,我会详细说明。
实际上,我会为此打开项目页面,因为内容很多,请耐心听我讲完。首先,项目包含多个组成部分:项目提案、数据收集、中期报告、最终报告和海报展示。每个部分都有不同的分值,并且截止日期不同。请在Canvas上仔细查看每个项目组成部分的具体截止时间。
实际上,第一个截止的项目提案很快就到了,是1月25日。所以请记住,项目工作几乎立即开始。在还没有讨论所有主题的情况下思考项目做什么,可能有点奇怪。但另一种选择是把所有项目工作都放在最后两周,那对你们来说也不好。因此,我建议你先了解一下这些主题,看看哪些可能有趣,或者思考一些听起来模糊有趣的问题,然后来和我们讨论。告诉我们:“我听说过这个问题”、“我在思考这个问题”或者“我看到了这些数据,你觉得用本课程的哪些主题来探索比较好?”等等。欢迎来办公时间找我们讨论,我们很乐意帮助你。如果你想使用课程早期涵盖的技术,这也是可以的。
这里列出了一些贯穿整个学期的日期,但请认真查看这一列,了解本学期你需要完成多少工作。
项目团队规模应为2到3人,理想情况是3人。项目的规模也应与团队人数成比例。在你的提案中,应该能看出有足够三个人做的工作量。因此,在组建团队时,请考虑项目的规模以及每个人将负责什么。在一些报告中,你需要写明这些内容。
如果你希望单独完成项目,我们非常不鼓励这样做。但如果你有非常 compelling 的理由,例如,你已经在某个地方工作,可以访问一些无法共享的数据,并且你真的想用它来做项目,请与我们沟通。这应该是规则的例外情况。
如前所述,项目规模应与人数成比例。另外,你不能在不同课程的项目之间“一稿多投”。例如,你可能同时选修了机器学习课程和数据挖掘课程,想用一个项目应付两门课,这是不允许的。你提交给其他课程的项目应该是独立的。
如果你对此有疑问,请告诉我。
接下来是关于迟交的说明,我稍后在讲解迟交政策时会详细说明。
如果你认为评分有误,可以在收到成绩后的一周内申请重新评分。这适用于项目、作业和考试。我认为,你可以在项目中获得的额外加分仅来自项目展示。我之前提到,作业中有额外加分,项目展示中也有额外加分。这些构成了本课程所有可能的额外加分机会。请记住这一点。一旦最终成绩公布,就没有机会再获得额外加分,你的成绩就是最终成绩。
此外,项目的组成部分与本课程的其他部分一样,都遵循计算机学院的各项政策和指导方针,包括学术不端行为政策,这一点非常严肃。请仔细阅读,并尽量避免任何形式的作弊行为。
好的。
我不想现在读完所有这些内容,那可能会让你们都睡着。但也许针对即将到来的项目提案,这里列出了你们作为一个团队应该撰写的内容:准备一份100到200字的文档,概述你们的计划,说明团队成员、计划使用的数据及其来源、计划从数据中挖掘的结构、为什么这个问题有趣、有什么新意或者讲师能学到什么。试着现在就进入需要撰写这类内容的心态,想象一下回答这些要求中的每一项需要多少时间,然后实际将它们写进文档。
请尽量使用语法正确的句子。现在有很多好工具,比如Grammarly,你可以将其集成到LaTeX中,或者直接将文本放入Google文档,它会给出很多建议。我自己也不是英语母语者,我使用所有这些工具来使我的句子连贯。如果我看到大量的语法错误,我就知道你们甚至没有使用这些免费可用的工具,这会让我感到遗憾。我不会因此扣分,但阅读不连贯的文字并不愉快。
我不会逐一讲解其他内容,但也许我会提到,这里有一些包含潜在数据的链接,你们可以探索。我强烈推荐Kaggle,上面有很多可以查看和尝试的内容。看看这些资源,试着开始头脑风暴,思考可能使用什么数据以及研究什么问题。
最后我想提一下海报展示。我说过项目的组成部分之一是最终展示,这将以海报的形式进行。请举手示意,你们中是否有人以前制作过研究海报?
好的,有一些。那么,请所有见过研究海报的人举手?
好的,更多了。我想给你们看一张我上个月展示的海报。这是一个研究海报的例子,来自我的一篇论文。它看起来像这样:有一个巨大的标题,有一些关于问题动机的说明,试图说服人们为什么这个问题有趣。在这篇特定的论文中,我们收集了一些数据,所以海报有很大一部分用来解释我们如何收集数据以及关于这些数据的一些统计数据。然后,你有一些基线性能,以及一些关于这篇论文主要收获的文字。你可能会包含一个二维码,让人们可以轻松访问你的GitHub代码库和数据。这就是研究海报的一个例子。尽量留出足够的空白,文字尽可能少。图表总是比表格等更好。
这就是你们将要制作的东西。然后我们将举行一个大型的海报展示会,持续至少两个小时。你需要准备一个关于你项目的简短介绍,就像在研究会议上通常做的那样:你站在海报旁边,人们走过来,他们的注意力持续时间可能很短,你需要说服他们你的论文是最好的。所以你需要准备一个大约两到三分钟的简短介绍,这意味着你需要练习,直到你能流利地说出来。对于这门课,你不必练习到做梦都能说的程度,但它应该快速且连贯。目前大约有130名学生注册了这门课,如果你们都组成三人小组,那大约是40多个小组。如果每个人做两分钟的展示,光是听项目展示就需要80多分钟。不幸的是,时间有限,所以你确实需要练习。但这应该很有趣,你也会看到同学们做了什么。我认为这是学习如何将本课程学到的技术应用到有趣问题中的好方法,而且不仅仅是坐在教室里,你会四处走动,更加投入和积极。
好的。我们会处理所有这些事情,我们需要非常仔细的后勤安排,你们需要提交海报的初稿,我们会快速检查是否合理,然后告诉你“这是最终版本”,或者我们会告诉你“你应该修改这里”,然后你发送最终版本。我们会在4月24日之前打印所有这些海报并进行展示。这个时间线必须非常严格,否则所有海报都无法按时打印。
关于项目有任何问题吗?你会帮助我们组建小组,还是我们需要自己发邮件联系?
说实话,我之前没想过这个问题。我原本以为你们会自行安排,但现在你这么一问,我也意识到组建小组可能很困难。是的,让我再考虑一下,并在周三给出更具体的指示。
我可以想象这是可能的,所以我会询问以前的讲师,看看是否能得到这些信息。谢谢。
就我个人而言,对于数据量没有上限要求。通常有下限要求,比如如果你只有10个例子,那就不再是数据挖掘了,因为你可以手动分析数据。所以,关于上限,没有限制;关于下限,可能有。如果你认为你的数据非常有限,请与我沟通,我会告诉你是否足够大。如果你的数据太大,这可能是一个有趣的问题,但也可能难以产生任何结果。但你知道,尝试使用你能处理的最大数据是很容易的,然后发现“哦,我需要一年时间才能完成分析”,然后你可以向下采样,直到找到更合理的数据大小。
我推荐使用这些资源。是的,但现在也有很好的网络爬虫工具。例如,也许你想分析某种类型的音乐歌词,你实际上可以爬取这些歌词并自己收集数据。但我想强调,这些数据将是未标记的。你可能不会费力去标记数据,即请人为每个实例提供类别。原因是那样你无法收集很多实例,更难以使我们将要讨论的任何技术变得有用。
另外,我稍后会提到,在本课程中,我们不会专注于分类,即使用监督技术将事物分类到标签中,因为这太像机器学习课程中教授的内容了。我们不想教相同的东西,那不会是对你们时间或我们时间的最佳利用。
我们可以使用机器学习模型设置来对数据说些什么,然后你可以修复数据的某个子集。
是的,所以我会提到,我们根本不会讨论分类技术。因此,本课程不会提及任何这些监督机器学习技术。
我们不允许使用,比如说,神经网络来预测你的数据,因为这不是我们将在本课程中教授的任何内容。但是,如果你要应用分类器对数据做一些处理,然后根据该分类应用我们使用过的一些技术,那可能是允许的。但在任何你觉得可能没有使用我们在本课程中讨论的任何技术的场景中,请联系我。
我意识到,在我们讲完所有课程材料之前,我们就要开始项目了。我将在今天讲座的最后快速浏览一下,让你们了解这里将教授什么,这可能会让你们了解在项目中可能使用哪些技术。但是,是的,一旦你对将要使用的东西有了一些概念,与我们交谈是最好的主意。
是的。抱歉,我知道这不太具体。好的,我们继续。Maravic教授?是的。
课程政策
好的,这就是你们的评分方式。现在让我们来看看一些课程政策。我将讲解我制定的具体政策,然后还有一些大学政策,现在全部讲完是不合理的。每节课我会讲解其中一两条,这样就不会一次 overwhelming。
如前所述,你们的所有作业都将在Canvas上提交。
你可以在大纲底部找到所有作业的截止日期,并请注意时间。所有作业都将在周三讲座开始前(下午2:45)截止。
但项目组成部分的截止时间在给定日期的不同时间。
请不要假设所有东西都在下午2:45截止,只有作业是。
好的。所有东西都在Canvas上提交,请不要通过电子邮件提交任何东西。
我们建议你们使用LaTeX来撰写作业。请举手示意,让我了解一下你们中有多少人以前使用过LaTeX?
好的,相当一部分人用过,但仍有不少人没用过。基本上,LaTeX是一个工具,可以让你轻松地编写方程式。有一段时间,它是撰写任何与数学相关内容的必备工具。现在LaTeX已经很好地集成到Google文档、幻灯片等工具中,所以你可以在其他地方使用它。但我仍然认为最直接、最简单的方法就是直接使用它。以前人们会在本地编译他们的LaTeX源代码,现在大多数人只是使用Overleaf。这里我提供了一个Overleaf文档的例子,基本上是源代码,然后你得到了编译这个源代码的结果,就是这个PDF。当我们发布作业时,也会提供该作业的LaTeX源代码,这样你就可以把它放到Overleaf中,在那里编写,然后编译,比如这里会重新编译,然后你只需下载PDF,将PDF上传到Canvas。要将项目上传到Overleaf,你只需转到主页,新建项目,然后上传项目,将我们提供的包含文件的zip文件拖放到Overleaf中。
哦,像Jupyter笔记本。但并非所有内容都是编程练习。
是的,我不太清楚它如何适用于任何类型的作业,但你可以写Markdown,这与LaTeX非常相似,我认为对我来说没问题。你提交的是PDF,所以我的意思是,你可以打印Jupyter笔记本,我认为在Overleaf中做更容易。但只要可读,我其实不介意使用任何这些工具。我们想要避免的是手写作业,这很可能会是一场灾难,并导致各种问题。所以绝对不要那样做。但是,如果你使用Git、Overleaf、Stupor Notebooks,或者使用集成了LaTeX的Google文档来写作业,我认为对我们来说应该没问题。
如果我们字写得非常好,可以手写吗?你可以测试我。
我建议不要。我担心如果我同意一个确实字写得非常好的学生,那么其他字写得不好的人也这样做,我们就有麻烦了。
但是,你知道,习惯用LaTeX写这些东西是很好的练习,所以这是一个好机会。
是的,我们会使用GradeScope,但仅此而已。是的。
关于作业大小有什么要求吗?请。
是的,J说得很好。如果你们都使用我们发送的相同文件并填写它们,对我们评分来说也更容易,因为我们确切知道每个内容在哪里。是的,所以我们更倾向于你们按照我刚才展示的方式去做。但如果那确实会占用你们太多时间,我们也能应付一些用不同方式撰写的作业。
好的,你知道,Overleaf也是我想强调的,当你们进行任何类型的研究项目合作时都会用到它。它是主要工具,就像如果你决定做研究,这可能是你除了电子邮件之外,一生中看到最多的网页。
是的,你可以,这就是它如此吸引人的原因,因为多人可以同时在上面工作,这比Overleaf出现之前要好得多。我从未经历过那个时代,或者用Word,我肯定经历过,但我那时没做研究。人们告诉我,他们会有各种奇怪的版本控制问题,比如一个人写,然后另一个人的版本再在上面工作,那是一团糟。所以,是的,这很棒。
好的,你不需要使用Overleaf,你可以在本地编译东西。这意味着如果你使用MacBook,你需要使用像TeX Live这样的东西,然后通常需要下载包等等。而使用Overleaf,所有这些都为你做好了,所以开始使用它要容易得多。
好的,如前所述,作业、项目等所有内容都遵循计算机学院的各项政策和指导方针,包括学术不端行为政策,该政策采用“三振出局”原则。我相信,如果因学术不端行为收到两次警告,你将立即被禁止注册任何额外的计算机学院课程,从各自的学位项目中退学,并且不会被任何未来的计算机学院项目录取。所以这根本不值得。
好的,话虽如此,我能理解什么构成学术不端行为可能会令人困惑。比如,你能和同学讨论吗?你能从彼此那里得到帮助吗?当然可以,我们鼓励你们组成学习小组并讨论作业。但最终,在讨论结束后,你必须用自己的话独立完成作业。很明显,这些是不同的解决方案。我的意思是,解决方案可能非常相似,但执行和书写的方式会不同,这就是我们要找的。所以请与你的同学交流,这会让你的生活更好、更轻松,但当你实际撰写解决方案时,你必须独立完成。
好的,不要向其他学生或互联网索要或复制作业,也不要让其他学生抄袭你的作业。你还应该引用所有参考的来源,特别是在项目组成部分中,因为在那里你遵循他人建议的情况不那么明显。这反映了学术诚信,是你们在研究工作中极其重要的习惯。
好的,我已经提到过不允许“一稿多投”。现在关于迟交作业。
你必须在Canvas上的截止时间前提交作业。如果你迟交了,这种情况时有发生,你最多可以迟交两次作业(仅限作业,不包括项目),每次不超过24小时,且没有惩罚。所以你有两次机会可以迟交作业,不需要通知我们,也不会发生任何事情。然而,在那之后,如果你第三次或之后迟交作业,将受到以下惩罚:前24小时扣10分,24到48小时之间扣20%,48小时后我们不接受任何作业。
另外,如果你迟交了三次,但有些作业做得更好,或者你觉得更好,关于哪次作业会受到惩罚,没有商量的余地。前两次迟交被接受,之后每次迟交都会受到惩罚,就是这样。
好的。我想再次强调,这种无惩罚的迟交仅适用于作业。对于项目,如果你迟交,将立即进入惩罚区域:前24小时扣10%,接下来的24小时扣20%。原因是你将是一个团队,很难判断谁是第二次或第三次迟交。
好的。再次强调,项目并非总是在下午2:45截止,像作业那样。如果你迟交项目组成部分,意味着你团队中的每个人都迟交了,每个人都会受到惩罚或得零分,取决于你们迟交了多久。
好的。我提到过,对于考试,如果你有医疗紧急情况,在提供证明文件后,我们可能会给你另一个时间考试。作业将在截止日期前两周发布,因此不接受在不同时间提交作业的例外情况,特别是考虑到你有两次基本上可以免费迟交作业的机会。
如果有长期生病的情况,当然这不适用,你只需告诉我们。
关于迟交作业有任何问题吗?是的。
关于项目提案,我们是否应该为每个部分提交截止日期?你提到了一些关于时间减少的事情。
是的,我建议你尽快开始思考这个问题。你对将要做什么有一些想法。如果你非常确信你提出的想法是好的,就没有必要与我们交谈。让我回到项目提案,我们有这些组成部分:你的团队成员、计划使用的数据、将从数据中挖掘的结构、为什么你正在处理的问题有趣,以及有什么新意或者讲师能学到什么。如果你不清楚是否满足了这里的任何要求,请来办公时间,我们会给你建议,告诉你是否应该更改任何内容。也就是说,我不希望每个人都来问我们是否足够好。如果你提交了一份合理的文本,可能就足够好了。从那里,我们可以告诉你:“嘿,你通过提交这份文档完成了这个项目组成部分,但我们认为你应该在这个步骤上多下功夫。”所以我觉得在项目提案之后,我们会给你更多的反馈。所以不要过度思考这是否足够好。我们不想变得严格或不合理,只要当我们阅读文本时觉得合理,我们就不会扣分。
好的。如前所述,对于评分错误,你可以在收到分数后的一周内提出。作业和海报展示中有一些额外加分机会。一旦我们公布了最终成绩,就没有机会通过做额外工作来获得额外学分。最终成绩将在5月15日前公布,这是将数字成绩映射到字母成绩的标准方式。
好的,现在关于 accommodations,我们从大学政策开始,我将在每节课讲解其中一条,这样就不会 overwhelming。但我们会涵盖所有内容,以便你们理解这些政策。
关于课程后勤有任何问题吗?没有。
好的。
课程核心主题概述
接下来,我将快速浏览本课程将涵盖的主题。但在那之前,我会给你们两分钟的休息时间。我尽量在每节课都安排两到五分钟的休息,让你们 refresh 一下,希望你们能继续跟上。所以休息两分钟,然后我们还有大约20分钟的讲座内容。
关于评分,我们对所有人的评分标准是一样的。当人们组建项目团队时,无论是本科生还是研究生,我们会考虑项目的规模。所以我认为,本科生做强度稍低一点的项目部分是可以的。此外,还有所有这些你可以获得的额外加分,我觉得你不会有很大的风险失去好成绩。我们将持续检查我们的成绩分布是否与往年相似。如果我们发现由于某种原因,我们的本科生成绩比以前低,我们会考虑提供一些额外作业来获得加分,或者采取其他措施。我们正在考虑这些事情,但我们从所有人按相同标准评分开始,唯一的例外可能是本科生的项目规模稍小一些。这说得通吗?是的,现在本科生这边有很多人。是的,如果你觉得由于某种原因,你可能达不到期望的成绩,或者类似情况,你知道,再次告诉我们。只要我们听到有担忧,我们就会想办法解决。但课程设计得让本科生也能取得好成绩。
好的。让我们完成这第一讲,那么从什么是数据挖掘开始。
好的,我们继续。
什么是数据挖掘?
让我们从什么是数据挖掘开始。这绝对不是一个容易回答的问题。在不同的学术背景下,你可能会听到:在数据中寻找结构,或者是对大规模数据进行机器学习,或者是无监督学习(即从无标签的数据中学习),或者是大规模计算统计学。这些都是合理的答案,如果你在面试中被问到这个问题,你可能会使用其中任何一个。但在本课程中,我们希望你们学到的是如何进行数据分析。你可能会想,数据挖掘或数据分析对我来说是一样的。让我们试着更具体一些。
思考数据分析意味着你精通以下三个组成部分:
-
理解将混乱的原始数据转换为抽象表示的原则。 让我们用一个例子:假设你是一个会议的程序主席,你想查看一篇提交的研究论文是否抄袭,是否与已发表的另一篇研究论文过于相似。你得到了这篇科学文章的原始文本,现在你必须以某种形式表示它,以便能够测量该论文与数据库中所有其他论文的相似度。所以第一步是将这个长字符串转换成我们实际可以用来计算相似度的东西。
-
一旦决定了表示方式,就需要找到相应的算法。 假设你已经设法为整篇科学文章找到了某种向量表示,你想找到某种算法来告诉你,用这个向量表示的论文是否与数据库中存在的其他论文非常相似。所以你需要知道,给定这种表示对象的方式,我可以使用哪些算法。
-
理解算法的可扩展性并进行建模选择。 不会有唯一的方法来解决这个问题,你会在这里和其他地方学到许多算法。然后你需要理解这些算法在大多数情况下的可扩展性。你可能会找到一个非常慢的算法来搜索你的一篇论文与数百万篇已存在论文的相似度,所以你需要考虑:“我需要快速完成这个,程序主席不能等几个月,他们需要立即完成这项工作。”其次,你需要接受这些算法与你以前见过的算法(比如排序)可能完全不同。在这里,你需要熟悉“误差”的概念。你知道你问题的理想解决方案是什么,但你要使用的算法会给出你想要的近似值。你需要考虑存在误差,并且需要知道多少误差是可接受的,或者如何思考什么是可接受的误差。再次考虑论文抄袭问题:如果你使用某种向量相似度来判断某些东西是否过于相似,你需要决定什么是“过于相似”,并且其中会存在误差。最后,我们这里有一个建模的组成部分。对你来说可能不太舒服的是,建模数据的方式不止一种。在本课程中,你将讨论的是,一旦你需要做出某些选择,有哪些最佳策略。我必须告诉你,这是做研究(比如作为博士生)时最难的部分之一。这些选择基本上是你为实现要解决的问题而做的主要事情。你必须做出很多选择,开始思考如何做出最佳选择是你真正需要的技能。当然,不仅仅是你决定成为博士生,如果你在一家公司解决问题,你也必须为该问题提供解决方案,并且经常需要处理这些建模选择。
好的。
思考所有这些的另一种方式是,你有这两个相互交织的目标。你在算法课程中学到的是如何使算法尽可能高效,而在统计学中,你有另一种目标,即想要建模事物。建模有时无法高效完成。思考数据挖掘的一种方式是将其置于两者之间。这不仅适用于数据挖掘,也是思考机器学习及相关领域(如深度学习)的一种方式。
每所大学都有数据挖掘课程,但教学方式不尽相同。本课程的教学方式侧重于处理超大规模数据的技术。我们想涵盖尽可能多的主题,所以当我浏览日历时,你看到了很多主题,其中一些我们进行了分组。你有不同的主题和许多话题,我们将关注近期的发展。
然而,本课程的设计也始终非常正式,并且在某种程度上是数学化的。我们希望你们熟悉这种数学符号来讨论所有这些事情。一些数据挖掘论文的写作方式确实需要你理解那种符号。并非每篇论文都如此,也许如果你将数据挖掘应用到文本等领域,你可能不需要所有这些数学符号,你可以用自己的话表达。但这是协作时一种非常高效的沟通方式。你可能用非常诗意的方式描述你的问题和解决方法,但通常与协作者沟通的最佳方式就是将其放入一些我们都可以以自己的方式思考的抽象对象中。
如前所述,不会有太多证明,会有一些证明。如果你真的想看到更多证明,请参考那本《数据科学基础》的书。
我们还将关注在实践中有用的内容,主要受大公司使用的内容驱动。例如,我们将讨论PageRank,这是谷歌搜索背后的驱动力。
最后,我们不会回避概率算法。我理解这在概念上可能有点难,但我们会立即尝试克服这一点。所以在下一讲中,我们将讨论其中的一些,实际上我们将讲解讨论概率算法和随机性所需的一些基础。第一次作业将全部关于这些内容,以真正让你处于思考这些东西的良好状态。我提到过,Python是首选的编程语言。在数学方面,如前所述,你需要牢固掌握线性代数和概率论。有时你听到这些主题,甚至可能成绩很好,但随着时间的推移你会忘记。我在讲座开始时提到过,我以前是数学专业的,但那已经是很久以前的事了,你会忘记一些东西。你只需要稍微复习一下,回到你上次听说这些东西的状态。所以,即使你觉得对所有这些都很舒服,打开我提到的教科书和你在这里看到的章节,看看你是否对这些主题没问题,这也没有坏处。
但是,是的,当我讲解内容时,我不会深入所有细节。
好的,这种分类至少是以前呈现数据挖掘的方式。所以你可以将数据挖掘视为你的数据以两种不同的形式呈现给你:有标签数据和无标签数据。对于有标签数据,每个实例都有一个标签,通常由标注员手动标记。例如,假设你想将科学论文分类到不同领域,以便在arXiv上自动分类。你可以从有人标记这些论文开始,然后你不仅得到论文,还得到相应的标签。另一种情况是你只得到没有相关标签的论文。如果你有标签,可以考虑两大类算法:回归和分类。回归是给定这些标签数据,你给出某种标量实数值;分类是你自动将示例标记为生物学论文或数学论文等。当我们谈论有标签数据时,我们谈论的是预测。而对于无标签数据,你可能会做类似在数据中寻找结构的事情。对于你想分组到不同领域的科学论文,你想找到对应于每个组的论文集合,你可能会使用降维或聚类等技术。它们的不同之处在于,你是得到连续输出还是得到离散的某种集合。
现在你可能已经暗示了数据挖掘和机器学习的异同。分类是机器学习课程中涵盖得很好的内容,我们在本课程中根本不会讨论分类。唯一的原因是,否则这两门课程之间会有巨大的重叠。我们不想说分类与数据挖掘无关,它是相关的,但我们将专注于本课程中的另一套技术,这样如果你选修数据挖掘和机器学习,你会获得比我们在这里也教分类多得多的知识。
所以它不在这里,但通常很重要。
最后,这是课程大纲。前两项都是关于统计和数学原理的。所以正如我所说,下周三我们将更深入地讲解思考概率算法和随机性所需的基础。我们将稍微讨论一下哈希和集中度量。你可能听说过一种哈希——哈希表,我们将讨论另一种类型——LSH。所以在下一讲中,你可能会为思考所有这些事情打下良好的基础。
然后,之后我们将专注于相似性。我想我已经至少提到了几个相似性相关的例子,比如检查两篇论文是否抄袭,我们用一些向量表示它们,也许我们想检查这两个向量的某种相似性,以判断这两篇论文是否过于相似,因此可疑。了解相似性是我们将要讨论的所有其他内容的基础。在之前的幻灯片中,我说我们将专注于回归、降维和聚类。拥有良好的相似性语言对于理解之后的所有这些主题至关重要。你已经见过一些相似性类型,比如欧几里得距离,但这不会是衡量相似性的唯一方式。回到我所说的关于做出最佳建模选择,衡量相似性的最佳方式也取决于你的问题和数据,你可能会做出不同的建模选择,决定哪种相似性最适合你自己的问题。
所以这可能与你以前见过的相似性类型(即欧几里得距离)略有不同。
除了聚类、回归和降维,我们还将讨论链接分析,这对于分析大型图(如社交网络图)或讨论PageRank时最有用。
最后,我们将稍微讨论一下控制噪声和不确定性。与作业中的数据不同,你的真实世界数据将是混乱的,你应该为此做好准备。你会在数据中发现一些异常值,你的第一步是首先识别这些异常值,然后决定如何处理它们。你可能会删除它们,因为你觉得“哦,这完全是垃圾,不知道是怎么回事。也许有人提交了一篇只有一个词重复了八页的论文,你不需要那个。”这是你可以对异常值做的一件事。另一件事是:也许它看起来像异常值,但可能你处理的数据中,比如,你正在做招聘决策,对于这份工作,主要是女性被录用,现在你看到一个男性,这并不是现实世界的异常,只是你的数据中有这一个异常值,你应该对这个异常值更加谨慎。你也可以利用噪声做一些非常酷的事情,比如确保隐私。可以将噪声添加到数据中,以防止人们从你数据中代表的人那里理解私人信息。所以我们也会稍微讨论一下差分隐私。
是的,我想在这里停下来。我本想更详细地介绍每一个主题,所以如果你打开这些幻灯片,会有更多信息。请随时与我讨论其中任何内容。
好的。关于我之前在服务器上工作过,以及服务器之间的所有信息,并与另一位研究员就这些数据合作过,是的,这非常完美。我们将讨论聚类,我们将讲解层次聚类和其他图聚类。所以,是的,这个项目完全符合你的想法。只是也要记住为你的项目找队友,看起来你已经对这个问题有了一些想法。

总结

在本节课中,我们一起学习了CS6140数据挖掘课程的总体框架。我们了解了课程的后勤安排、沟通渠道、评估方式(包括作业、考试和项目)以及核心主题。课程强调将原始数据转化为抽象表示、选择合适的算法并理解其可扩展性,同时注重数学基础和实际应用。我们还明确了课程不会涵盖监督分类技术,而是专注于相似性度量、聚类、降维、链接分析以及处理噪声和隐私等主题。希望本次概述能帮助你为接下来的学习做好准备。
002:统计原理

在本节课中,我们将回顾一些基础的、高层次的统计原理。我们将通过哈希和随机过程的例子,以及这些过程产生的相关行为来学习。进行这项练习的原因在于,它将帮助你思考那些在其逻辑和过程中包含一定随机性的概率和随机化算法。
概述
我们将从IID假设开始,介绍相关的数学符号,然后探讨哈希表与哈希函数。接着,我们将分析两个具体的随机过程:生日悖论和优惠券收集问题,以理解碰撞和完整集合出现的期望步骤数。这些分析将帮助我们建立对概率算法行为的直观理解。
IID 假设
首先,我们需要了解一个核心原则:IID假设。
IID代表 独立同分布。
- 独立 意味着数据集中的任意两个数据点 ( X_i ) 和 ( X_j ) 彼此独立。
- 同分布 意味着所有数据点 ( X_i ) 都来自同一个概率分布。
在机器学习中,这个假设的一个常见表述是:训练集和测试集是同分布的。这意味着训练误差和测试误差的期望是相似的。
我们关心IID假设主要有两个原因:
- 研究训练误差和测试误差之间的关系。
- 当数据点独立时,我们可以更高效地进行优化。具体来说,给定参数 ( \theta ),数据点 ( X ) 的联合概率可以分解为单个概率的乘积:
[
P(X|\theta) = \prod_{i} P(X_i|\theta)
]
对其取对数后,乘积变为求和,这大大简化了计算:
[
\log P(X|\theta) = \sum_{i} \log P(X_i|\theta)
]
然而,这个假设并不总是成立。例如,在生成文本时,已生成的内容会影响下一个词的选择,因此数据点之间并非独立。
符号与哈希函数
现在,让我们转向本节课将使用的一些特定符号。
我们从一个数据集 ( X_1, X_2, ..., X_n ) 开始,这些数据点是独立同分布的。每个 ( X_i ) 都是一个从1到 ( N ) 的整数。我们用 ( [N] ) 表示整数集合 ( {1, 2, ..., N} ),因此 ( X_i \in [N] )。
这种表示法的例子包括:词典中的所有单词、所有可能的IP地址或所有生日。我们将其表示为整数是为了符号和实现上的简便。
在本节课中,我们假设每个整数被分配到的概率是均匀的。即,对于任意整数 ( j \in [N] ),有:
[
P(X_i = j) = \frac{1}{N}
]
对于不在集合 ( [N] ) 中的整数,概率为0。同样,这个均匀性假设在现实中也不总是成立(例如,生日在夏季更常见),但为了今天的分析,我们将采用它。
接下来,我们回顾一个重要的数据结构:哈希表。其中,哈希函数是我们课程中最感兴趣的组成部分。
哈希函数 ( h ) 从一个函数族 ( \mathcal{H} ) 中随机选取。哈希函数本身是确定性的,它将一个定义域(例如,所有长度为 ( K ) 的字符串集合 ( \Sigma^K ))映射到值域 ( [N] )(即整数1到 ( N ))。
一个好的哈希函数需要具备均匀性。这意味着,对于任意两个不同的字符串 ( s ) 和 ( t ),它们被哈希到同一个值的概率应该相等:
[
P_{h \in \mathcal{H}}(h(s) = h(t)) = \frac{1}{N}
]
这可以防止某些哈希值被分配过多的元素,从而保证效率。
当两个不同的字符串被哈希到相同的整数值时,称为碰撞。我们希望碰撞尽可能少。
以下是几种常见的哈希函数示例:
- Python内置函数:例如 SHA-1 的变种,通过连接一个随机种子字符串 ( a ) 来实现随机性。
- 乘法哈希:形式为 ( h_a(x) = \lfloor N \cdot \text{frac}(x \cdot a) \rfloor ),其中 ( a ) 是一个大的奇数。
- 模哈希:( h(x) = x \mod M )。虽然常见,但由于其结构性较强(例如,相差 ( M ) 的数总会碰撞),通常不是最佳选择。
生日悖论
在介绍了基础概念后,我们来看一个具体的随机过程分析:生日悖论。这个问题探讨的是,平均需要看到多少个不同的项目(例如人)才会发生第一次碰撞(例如生日相同)。
生日悖论指出,在一个房间里只需要大约23个人,其中两人生日相同的概率就超过50%。这之所以被称为“悖论”,是因为23远小于一年的总天数365。
让我们更正式地推导一下。假设有 ( k ) 个人,我们想知道没有碰撞(即所有人生日都不同)的概率。更精确的计算如下(不假设独立性):
[
P(\text{无碰撞}) = 1 \cdot \frac{N-1}{N} \cdot \frac{N-2}{N} \cdot ... \cdot \frac{N-(k-1)}{N}
]
其中 ( N=365 )。当 ( k=23 ) 时,计算可得无碰撞概率约为0.467,因此至少有一对碰撞的概率约为 ( 1 - 0.467 = 0.533 ),即略高于50%。
一个实用的经验法则是,要达到概率 ( p ) 的碰撞,所需的步骤数 ( k ) 大约为:
[
k \approx \sqrt{2N \cdot p}
]
对于 ( p=0.5, N=365 ),计算得 ( k \approx 27 ),与23接近。这个分析告诉我们,在随机过程中,碰撞出现得比直觉预期要早。
优惠券收集问题
与寻找第一个碰撞相反,另一个问题是:需要多少次尝试才能收集到所有不同的项目? 例如,需要买多少份开心乐园餐才能集齐所有可能的玩具?这被称为优惠券收集问题。
设 ( T ) 是收集齐所有 ( N ) 种玩具所需购买套餐总数的期望值。我们可以将过程分解:设 ( T_i ) 为收集到第 ( i ) 个新玩具所需的期望步数,( d_i = T_i - T_{i-1} ) 为在已拥有 ( i-1 ) 种玩具后,获得下一个新玩具所需的期望步数。
在已有 ( i-1 ) 种玩具时,下一次购买获得新玩具的概率是:
[
p_i = \frac{N - (i-1)}{N}
]
获得下一个新玩具的步数 ( d_i ) 服从成功概率为 ( p_i ) 的几何分布,其期望为:
[
E[d_i] = \frac{1}{p_i} = \frac{N}{N - (i-1)}
]
那么,收集齐所有玩具的总期望步数为:
[
E[T] = \sum_{i=1}^{N} E[d_i] = N \cdot \sum_{i=1}^{N} \frac{1}{i}
]
右边的和式是第 ( N ) 个调和数 ( H_N )。它没有闭式解,但可以近似为:
[
H_N \approx \gamma + \ln N
]
其中 ( \gamma \approx 0.577 ) 是欧拉-马歇罗尼常数。因此:
[
E[T] \approx N (\gamma + \ln N) \approx N \ln N
]
这个结果告诉我们,要集齐所有不同的项目,平均需要的尝试次数大约是 ( N \ln N ),这比项目总数 ( N ) 要多。
总结

本节课我们一起回顾了数据挖掘中重要的统计原理。
我们首先学习了 IID(独立同分布) 假设及其在机器学习中的重要性,同时也认识到它在现实中并非总是成立。
接着,我们介绍了哈希函数的概念,并讨论了均匀性和碰撞。
然后,我们通过生日悖论分析了看到第一次碰撞所需的期望步骤数,发现它大约需要 ( \sqrt{N} ) 量级的步骤。
最后,我们通过优惠券收集问题分析了收集齐所有不同项目所需的期望步骤数,得到其数量级约为 ( N \ln N )。
理解这些随机过程的行为,对于设计和分析包含随机性的算法至关重要。
003:k-grams 与 Jaccard 相似性 📚

在本节课中,我们将学习数据挖掘中的一个基础问题:如何高效地查找或比较数据中的相似项。我们将从如何将文本文档表示为集合开始,然后学习如何使用 Jaccard 相似性来度量这些集合之间的相似度。
课程政策更新 📝
首先,我们回顾一下课程政策。今天涉及的是退课或撤销政策。学生可以在学期开始的前两周内退课,而不会受到任何处罚。在退课截止日期之后、课程中期之前,学生可以正式从一门或所有课程中撤销。成绩单上会记录“W”等级,并收取相应的学费。“W”等级不用于计算学生的GPA。关于完整学期、第一期和第二期课程的撤销截止日期,请参阅学术日历。
我想提一下与此相关的另一件事。在前两周无惩罚退课的政策下,我决定要求一些作业实际编写 Python 代码,特别是使用一些 Python 库。这应该不会太困难或超级复杂,但我认为在完成数据挖掘课程时了解这些库很重要。你们将学习它们的基本用法。这可能让你们有所顾虑。如果你们觉得这太难,可以考虑退课选项,但我真的相信这不会太复杂,你们需要自己决定。
这是我对课程大纲的一个修改。另一个修改是关于沟通方式的。发布第一次作业后,很明显有很多问题直接发送到我的收件箱,你们希望听到我的意见,而不是助教的意见。这对我来说很困难,因为我需要做研究,需要为大学服务,需要为研究社区服务等等。你们的消息与所有其他消息混在一起,我无法优先处理你们的消息或其他消息。因此,我们将改用 Piazza。Piazza 有一个有用的功能,我可以“认可”消息。如果你们看到我认可了助教的消息,就可以得出结论:我也会告诉你们同样的事情,无需直接联系我。当然,总会有需要直接联系我的个人情况。Piazza 提供了所有选项,让你们可以直接或间接联系教师,使事情变得私密或隐藏。我认为这对我来说会更容易一些,因此对你们也更好,因为你们会及时得到我的回复。
这两项更改尚未实施,一旦实施,我们将在 Canvas 上宣布。
回顾上节课内容 🔄
上一节课的讲义中,至少有几处内容不够清晰。首先是不清楚如何将多重哈希用于字符串。基本上,需要将字符串转换为整数,有方法可以做到这一点,但今天我们不会深入讨论,这将是你们要做的。
其次,我提到了一个关于哈希步骤数的经验法则,它来自一个等式。当时有同学问这个法则从哪里来,我没有给出答案。所以我在笔记中添加了如何从这个等式推导出这个经验法则概率的说明。这个推导基于独立性假设。
具体来说,从这个等式出发,你们需要使用二项式定理,并意识到当 N 很大时,1/N 很小,其二次方及更高次方项将非常小,因此可以进行近似。然后,利用当 k 很大时,k 选 2 可以近似为 k²/2 的事实。将这些结合起来,就得到了那个公式。
另外,关于调和数,我上次搞混了,没有正确设置 i 的范围。现在笔记中已经修正了。
还有一个问题是:给定 k 次购买,能否给出看到所有玩具的概率?上次我不知道如何推导。实际上,这是一个经过充分研究的问题。从我们见过的公式推导并不简单,需要一些努力。如果你们知道斯特林数,可以使用它来得到那个概率。我会在 Canvas 或 Piazza 上分享相关资料。
以上是关于上一讲的全部内容。包含这些修正的笔记已在网站上提供。
项目提案与作业提醒 📅
在开始新内容之前,我想提醒大家,项目提案的截止日期即将到来。要提交项目提案,你们需要组建团队。我们已经设定了组建团队的截止日期,我想是明天周四下午6点。如果到那时你们还没有组队,我们将随机分配。正如第一讲所说,必须有非常令人信服的理由才能单人成组,理想情况是三人一组。
我还带来了一些海报,让你们了解这门课程期望的项目类型。一般来说,我恳请你们不要在教室外等候,而是到我们为办公时间预订的房间来找我们。我知道你们可能只想快速问个问题然后回家,但这让我们很难回答所有问题。而且还有助教可以帮助回答问题。如果你们挤在人群里,就看不到他们了。所以,除非你们真的非常赶时间,否则请到那个房间去。我这么说是因为我把海报带到了那个房间,你们可以在那里更从容地查看。
最后,新的作业已经发布。这次作业你们有两周时间完成。我们将尽量保持提前两周发布作业的节奏,但根据我的日程安排,有时可能会有小的延迟,例如我出差时。所以这并不是一成不变的。
今日主题:寻找相似项 🔍
现在,我们终于可以开始新的课程内容了。今天你们将听到完成第一次作业第一个问题所需的一切知识。我相信在这次讲座之后,你们就可以开始处理第一个问题了。
今天以及接下来两讲的内容,将围绕数据挖掘的一个基本问题展开:在数据中查找或检查相似项。
基本问题是:寻找相似项。
例子包括:
- 检测抄袭:例如,作为会议组委会成员,我们会收到大量论文,需要检查这些论文是否与科学界已存在的某些论文过于相似。论文数量巨大,因此这是一个大池子里的相似性查找问题。
- 网页镜像识别:网络上不同的页面可能有镜像来分担负载,我们可能希望识别这些相似的页面。
- 新闻文章溯源:一家新闻媒体写了第一篇报道,然后其他媒体引用、改写片段,尤其是在翻译成另一种语言时。你们可能也想知道哪些文章来自同一来源。
这些只是一些例子,我相信你们能想到更多。这是一个非常普遍的问题。你们可能会想:我知道怎么做,我直接比较每一对就行了。如果两篇论文过于相似,我就说这篇论文抄袭了之前的那篇。这可能是你们完全合理的想法。
但当处理大数据时,问题就出现了。如果我们有 N = 1,000,000 个项目,那么就有 N 选 2 对,即 N * (N-1) / 2 对。对于一百万个项目,这已经是 5 × 10¹¹ 对。基本上,如果你们每秒能比较一百万对,比较这么多对也需要五天。如果有一千万个项目,这将需要一年。显然,在处理大数据时,这种显而易见的方法是不可行的。我们不能这样做,因为我们有这个问题。
这三讲的重点就是看看我们如何能更有效地做到这一点,如何实际比较项目对,而不浪费这么多时间,并且有实际有用的应用。
我们将要学习的实际解决方案叫做 局部敏感哈希。我们将实际应用上一讲学到的哈希函数。当我们把学过的东西应用到一个非常现实的世界问题时,感觉非常好。
局部敏感哈希的思想是:假设你们有 N 个文档。你们将使用一堆哈希函数来哈希它们。然后你们会说,我的两个文档 D1 和 D2 是相似的,如果对于我使用的这些哈希函数中的某些,它们具有相同的哈希值。如果不存在这样的哈希函数,那么你们可以断定它们不相似。这将快得多。基本上,你们是随机地将它们放入桶中,如果它们没有落在同一个地方,你们就可以说它们不相似。正如你们在作业和上一讲中意识到的,为了实现碰撞,你们需要的试验次数比实际项目数要少。
这就是我们要学习的局部敏感哈希。但在实际能够做到这一点之前,我们需要一些技术。
课程路线图 🗺️
我们的路线图将如下所示:
-
今天:我们将学习如何用集合表示文本文档。这里有两个文档,每个文档都将用某个集合表示。然后,我们将使用集合相似性来比较它们,具体来说是 Jaccard 相似性。然后我们可以说它们是相似还是不相似。这就是我们今天要讨论的内容:如何从文本到集合,以及如何使用 Jaccard 相似性来比较这些代表文本的集合。
-
下周一:我们将讨论一个问题,即这里的集合实际上可能非常大,然后你们又会遇到问题。因此,我们将使用一种称为 最小哈希 的技术,用更小的集合来表示它,并近似 Jaccard 相似性。这就是我们下次要做的。
-
下周三:我们将把 LSH 的思想与从最小哈希得到的结果结合起来。
这就是我们实现局部敏感哈希的方法。请将你们的思维设定为:我们分三步走,每讲一步。
从文档到集合 📄➡️📦
正如所说,今天我们将从文档到集合。由于我需要文本示例,我将使用一些幻灯片来讲解这部分。
我们将以这四个句子作为运行示例:
- I am Sam.
- Sam I am.
- I do not like green eggs and ham.
- I do not like them Sam I am.
首先,你们可以做一个非常常见的处理:定义词汇表。基本上,使用这四个句子中存在的所有单词,并且不重复。如果一个单词出现两次,你们只在这里放一次。然后每个单词用一个整数表示。通常我们按字母顺序排列并编号。这里没有任何哈希或复杂操作,这只是制作一个单词列表并给它们分配整数。
然后,你们可以生成一个向量,每个位置放入对应词汇在句子中出现的次数。这称为 词袋 表示。例如,单词 “am” 在第一个句子中出现一次,你们就在这里放数字1。然后 “and”, “do”, “green”, “ham” 没有出现在第一个句子中,所以你们全放零。接着到单词 “I”,它出现一次,放数字1,依此类推。这里唯一出现次数超过一次的是 “I”。这些就是词袋,一种超级简单的单词表示方法。
但这种方法有一个问题,有人能指出这里有什么问题或可以改进的地方吗?没错,我们这里有两个句子 “I am Sam” 和它的有趣版本 “Sam I am”。用这种词袋表示法,我们无法捕捉到这一点,它们完全相同。基本上,我们完全丢弃了关于句子的句法信息。例如,如果你们使用这些向量来判断文本是否正式,就不会有很好的表示,因为尽管第二个句子非常不正式,但用这个向量无法捕捉到。所以我们想做更聪明一点的事情,我们使用所谓的 k-grams,特别是这里我们将关注基于单词的 k-grams。
什么是 k-grams?🔤
k-grams 是指从每个句子中取出连续的 k 个单词序列。
- 如果 k=1,意味着取这个句子集合中的单个单词。我们有 “I”, “am”, “Sam” 等等。
- 然而,我们可以要求 2-grams,这意味着取两个单词的序列。我们会有 “I am”, “am Sam”, “Sam Sam”, “Sam I”, “I am”, “I do”, “do not” 等等。
- 在自然语言处理中,通常当有 1-grams 时,我们称之为 unigrams;2-grams 是 bigrams;3-grams 是 trigrams;从4开始,我们就只说 4-grams、5-grams 等等。如果你们遇到这些词,它们是非常标准的,我鼓励你们实际使用这些术语,这听起来更专业。
我们有了这些 k-grams。这里可能发生的情况是,我们犯了一些小的拼写错误,这在处理数据挖掘中的互联网文本数据时非常常见。例如,我们可能说 “This movie is awesome”,然后有人可能稍微拼错为 “This movie is awesomw”(因为键盘上 W 紧挨着 E)。如果你们使用基于单词的 k-grams,主要单词 “awesome” 将不会被捕捉到,基本上 “awesomw” 将与词汇表中的词非常不同。
另一个可以利用的想法是 基于字符的 k-grams,即寻找连续的 K 个字符序列。例如,如果 K=3,那么 “I am Sam.” 就会有 “I a”, “am”, “m S”, “Sa”, “am.” 等三元组。它们对于检查这类拼写错误非常有用,对于形态丰富的语言也很有用。
关于 k-grams 的顺序问题:如果你们混合单词并使用 unigrams,顺序无关紧要;但如果你们查看 bigrams 并且混合了单词,因为你们查看的是序列,那么顺序就有关系了,而这正是重点——捕捉事物出现方式的差异。
这些就是 k-grams,这是我们今天表示文本的方式,也就是我之前提到的集合表示。然后我们将对这个集合表示做一些处理。
在继续之前,我还想强调,你们可能知道一些分布式的或密集的向量单词表示,你们可能会想:你们是在糊弄我们吗?我知道我们现在用的是更简单的东西。你们是对的,如今在自然语言处理中,我们用具有连续值的向量表示单词,而不是我们这里用的整数计数的词袋向量。在我们完成 LSH 之后,我计划介绍这些向量表示。然而,我想强调的是,这种 k-grams 或 n-grams 集合至今仍然非常有用,因为文本有很多预处理任务。例如,我们想知道文本是用哪种语言写的,使用这种轻量级的 k-grams 方法比训练神经网络来预测语言要好得多。或者你们可能知道大语言模型,为了训练它们,我们抓取文本时也会使用 k-grams。所以,尽管现在有更高级的版本,但这些集合仍然非常重要。
建模选择 🤔
在构建这些东西时,我们做了几个建模选择。例如,我们从词汇表中排除了标点符号和句号。我们应该这样做吗?这取决于任务。例如,标点的使用对新闻文章非常重要,你们可能想要建模它;如果处理推文,它就不那么重要,你们可能直接丢弃。我未提及的一点是,这里什么进入了词汇表?我包含了除标点和句号之外的所有内容。但通常,我们会收集所有单词及其频率,然后根据某些计数来裁剪词汇表。例如,我们会说一个单词必须出现三次才能被包含在词汇表中,因为其他单词太奇怪了,我们不想从中得到任何信息。
另一个决定是是否将文本小写。如果有很多专有名词,你们可能不应该小写,因为大写首字母提供了信息,表明很多名字都是这样写的。所以,在处理计算文本时,总是需要做出很多建模决策。
集合相似性与 Jaccard 相似性 ⚖️
现在我们已经用集合表示了文档。今天课程的目标是定义集合之间的相似性,以便我们可以说这两个文本文档是相似或不相似的。
我们将使用的一个具体相似性度量称为 Jaccard 相似性。让我们看一个不涉及单词但涉及一些整数的玩具示例。
设 A = {0, 1, 2, 5, 6}
设 B = {0, 2, 3, 5, 7}
Jaccard 相似性公式如下(不仅限于此特定示例):
Jaccard(A, B) = |A ∩ B| / |A ∪ B|
它等于两个集合交集的基数除以它们并集的基数。基本上,你们根据它们共享的项目数量相对于集合一和集合二中所有项目数量的多少来衡量它们的相似程度。
对于我们的具体 A 和 B 值:
- 交集 A ∩ B = {0, 2, 5},基数为 3。
- 并集 A ∪ B = {0, 1, 2, 3, 5, 6, 7},基数为 7。
- 因此,Jaccard 相似性 = 3 / 7 ≈ 0.4286。
如果我们想象一下,这些 A 和 B 是两个文档的表示,那么我们会这样使用 Jaccard 相似性,并说它们有 0.4286 的相似度。可能不明显的是,这里可以达到的最大值是 1,即交集中的所有内容实际上都在并集中。
广义集合相似性族 🧮
Jaccard 相似性不是我们可以使用的唯一度量,实际上有一整套相似性度量。存在一个广义的集合相似性公式。
公式如下:我们有参数 x, y, z, z‘,它们都大于或等于零。当我们取 A 和 B 的相似性时,它等于:
S_{x,y,z,z'}(A, B) = (x * |A ∩ B| + y * |(A ∪ B)^c|) / (x * |A ∩ B| + y * |(A ∪ B)^c| + z * |A Δ B| + z' * |(A ∪ B)^c|)
解释一下集合操作:
A ∩ B是交集。(A ∪ B)^c是并集的补集,即全集中不在并集内的所有元素。A Δ B是对称差,即所有在 A 中但不在 B 中,以及在 B 中但不在 A 中的元素。基本上,从并集中丢弃交集部分。
分母看起来非常相似,但对称差前面是 z‘。唯一的区别就是这个 z’。
通过代入具体的参数值,我们可以得到五个具体的相似性公式示例:
- Jaccard 相似性:
S_{1,0,0,1}(A, B) = |A ∩ B| / |A ∪ B| - Hamming 相似性:
S_{1,1,0,1}(A, B) = (|A ∩ B| + |(A ∪ B)^c|) / N,其中 N 是全集大小。 - Sørensen-Dice 系数:
S_{1,0,0,2}(A, B) = (2 * |A ∩ B|) / (|A| + |B|) - S_{1,1,0,2} 相似性:
S_{1,1,0,2}(A, B) = (|A ∩ B| + |(A ∪ B)^c|) / (N + |A ∩ B| - |A Δ B|) - 另一个相似性:
S_{2,0,0,1}(A, B) = (2 * |A ∩ B|) / (2 * |A ∩ B| + |A Δ B|)
如何在这些相似性度量中选择?这又是一个建模决策。根据具体问题,如果前人发现某个度量对你们的问题更好,你们就沿用那个。或者,特别是在机器学习中,我们通常有数据的训练集、开发集和测试集划分。你们可以在开发集上尝试所有这些度量,假设第五个在开发集上最好,那么你们就在测试集上报告使用第五个相似性度量的结果。
应用 Jaccard 相似性到文本示例 📝
回到我们 “I am Sam” 的例子,让我们尝试将 Jaccard 相似性应用到具体的文本示例中。
我们将选择基于单词的 bigrams(k=2)。每个文档用这些 bigrams 集合表示。
- 句子 “I am Sam”: 集合为
- 句子 “Sam I am”: 集合为
Jaccard 相似性公式为:|交集| / |并集|
- 对于第一句和第二句:交集为 {“I am”},基数为1。并集为 {“I am”, “am Sam”, “Sam I”},基数为3。相似性 = 1/3 ≈ 0.333。
这个相似度是合理的。如果我们回到词袋表示,并使用欧几里得距离作为相似性度量,我们会得到距离为0,因此相似性为1(完美相似)。这意味着这两者完全相似。因此,选择欧几里得距离或欧几里得相似性在这里并不是最佳选择,因为它无法体现它们并非完全相似的事实。而 Jaccard 相似性在使用 bigrams 时给出了这个信息,并且使用 bigrams 而不是 unigrams 来获取这些信息很重要。
对于 D1 和 D3,我们得到它们非常不相似,因为相似性为0。D1 和 D4 是 1/8,小于 0.333。这里我们得到的最高相似度是 0.333,这是直观的,因为我们可以看出 “I am Sam” 和 “Sam I am” 是这里最相似的文档对。至少对我来说,相对于其他相似性来看 Jaccard 相似性更容易解释。如果看绝对数字,最大值是1,当然如果得到0.9,可能就很接近了,但这再次取决于应用。我建议相对地看待这些值。
课堂练习 📱
我们将进行一个小练习。请计算在特定参数下的 Jaccard 相似性。我们将使用在线投票来提交答案。
问题:计算文档 D1 (“I am Sam.”) 和 D2 (“Sam I am.”) 之间的 Jaccard 相似性。使用基于字符的 trigrams(k=3),并包含句点。
步骤:
- 为每个文档构建字符 trigrams 集合(包含空格和句点)。
- 计算两个集合的交集和并集。
- 应用公式:Jaccard = |交集| / |并集|。
(注:由于转录文本中的具体 trigrams 列表可能有误,且练习涉及实时互动,此处不提供具体计算过程和答案,但方法是明确的。)
总结与展望 🎯
本节课中,我们一起学习了数据挖掘中寻找相似项问题的第一步。
我们首先了解了如何将文本文档通过 k-grams(n-grams)转化为集合表示,这是一个关键的预处理步骤。接着,我们深入探讨了如何度量集合之间的相似性,重点介绍了 Jaccard 相似性 及其计算公式 |A ∩ B| / |A ∪ B|。我们还简要了解了其他广义的集合相似性度量。
现在,我们已经完成了实现高效相似性查找(局部敏感哈希)所需三步中的第一步:将文本表示为集合,并度量集合相似性。

在下节课中,我们将面对当这些集合过大时带来的新挑战,并学习 最小哈希 技术,它能帮助我们压缩集合表示并近似计算 Jaccard 相似性,为最终应用局部敏感哈希算法奠定基础。
004:最小哈希与局部敏感哈希

在本节课中,我们将继续学习最小哈希技术,并深入探讨如何确定所需哈希函数的数量以获得可靠的杰卡德相似度估计。随后,我们将引入“局部敏感哈希”这一核心概念。
课程政策与公告
首先,我们来回顾今天的课程政策。该政策涉及课程材料的版权问题,规定课程内容仅供个人、非商业、教育和学术用途,禁止用于任何盈利目的。更多细节可查阅《学生权利与责任守则》中关于课堂内容使用和分发的章节。
此外,今天发布了一项公告:我们正在寻找一个两人小组,愿意接纳另一名同学加入其项目。如果您所在的小组符合条件,请在课后立即联系我或助教。我们非常感谢您的慷慨,这能帮助我们避免出现单人小组的情况。
今天还发布了第三份作业,截止日期为两周后。请合理安排时间,如果尚未开始第二份作业(一周后截止),建议现在开始,以免任务堆积。
确定哈希函数数量
上一讲我们提到,可以通过计算签名并比较两个集合签名的相同维度数量来估计杰卡德相似度。其中涉及一个关键参数 k,即我们使用的哈希函数数量。一个自然的问题是:为了获得良好的杰卡德相似度估计,我们应该使用多少个哈希函数?
为了回答这个问题,我们将引入一个更通用的框架,它不仅适用于当前场景,也适用于数据挖掘中通过聚合更多数据以获得更好估计的一般情况。这个框架被称为“概率近似正确”。
概率近似正确框架
PAC框架涉及几个关键变量:
- X̂:一个随机变量,代表我们的估计值(例如,杰卡德相似度的估计)。
- E[X̂]:该随机变量的期望值(例如,真实的杰卡德相似度)。
- δ:失败概率,取值范围为0到1。例如,δ=0.1表示我们接受10%的失败情况。
- ε:误差容忍度,一个大于0的数,用于衡量估计的“好坏”程度。
PAC框架的核心是建立如下形式的边界:
P(|X̂ - E[X̂]| > ε) ≤ δ
这意味着,估计值与真实值之差大于ε(即估计不佳)的概率应小于δ。等价地,也可以写作:
P(|X̂ - E[X̂]| ≤ ε) ≥ 1 - δ
这表示,在至少 (1-δ) 的情况下,我们的估计是“好”的(误差在ε以内)。
切比雪夫不等式与中心极限定理
通常,我们会结合切比雪夫不等式来应用PAC框架。其推导依赖于中心极限定理。该定理指出,如果我们有n个独立同分布的随机变量(均值为μ,方差为σ²),那么当n很大时,这些变量的样本均值将近似服从正态分布。形式化表示为:
(1/n) * Σ_{i=1}^{n} X_i → N(μ, σ²/n) (当 n → ∞)
结合PAC框架和中心极限定理,我们可以得到切比雪夫界的一种形式。假设我们有独立同分布的随机变量X_i,且每个X_i都被限制在区间[A_i, B_i]内。定义Δ_i = B_i - A_i,并令M = Σ_{i=1}^{n} X_i(注意,这里不是样本均值,而是总和)。那么对于任意λ > 0,有:
P(|M - E[M]| > λ) ≤ 2 * exp( -2λ² / Σ_{i=1}^{n} Δ_i² )
应用于最小哈希
现在,我们将这个边界应用于最小哈希问题。我们的目标是估计两个集合S_i和S_j的杰卡德相似度J(S_i, S_j)。
首先,回顾我们如何定义随机变量。在上一讲中,我们定义了指示变量:
X_l = I( minhash(S_i) = minhash(S_j) )
这个变量在最小哈希值相等时取值为1,否则为0。显然,X_l的取值范围是[0, 1]。
我们使用k个不同的哈希函数,得到k个这样的随机变量X_1, X_2, ..., X_k。它们的和M = Σ_{l=1}^{k} X_l。我们知道,每个X_l的期望值E[X_l]就是杰卡德相似度J(S_i, S_j)。因此,E[M] = k * J(S_i, S_j)。
我们的估计量是Ĵ = M / k。我们希望|Ĵ - J|很小。
接下来,我们应用边界。设Δ_l = 1 - 0 = 1(因为每个X_l的边界是0和1)。那么Σ Δ_l² = k。
我们希望控制误差|Ĵ - J| > ε的概率。这等价于|M - k*J| > kε。在边界公式中,令λ = kε。
代入边界公式:
P(|M - E[M]| > kε) ≤ 2 * exp( -2(kε)² / k ) = 2 * exp( -2kε² )
这个不等式告诉我们,估计误差大于ε的概率随着哈希函数数量k的增加而呈指数级下降。因此,通过选择足够大的k,我们可以使这个概率(即失败概率δ)变得任意小。例如,如果我们希望以至少95%的置信度(δ=0.05)保证误差在ε=0.05以内,我们可以解方程:
2 * exp(-2k*(0.05)²) ≤ 0.05
来求解所需的k值。
总结
本节课中,我们一起学习了以下内容:
- 我们回顾了课程政策,特别是关于版权的规定。
- 我们提出了一个关键问题:在最小哈希中,需要多少个哈希函数(k)才能获得可靠的杰卡德相似度估计。
- 我们引入了概率近似正确框架,它为我们提供了一种量化估计可靠性的通用方法。
- 通过结合中心极限定理和切比雪夫不等式,我们推导出了一个概率边界。
- 我们将这个边界应用于最小哈希的具体场景,证明了估计误差超过给定阈值ε的概率随哈希函数数量k的增加而指数下降,即
P(|Ĵ - J| > ε) ≤ 2 * exp(-2kε²)。这为我们根据所需的精度(ε)和置信度(δ)来选择k提供了理论依据。

下一节,我们将基于最小哈希构建高效的相似项查找方法——局部敏感哈希。
005:完成最小哈希 🧮

在本节课中,我们将继续学习“寻找相似项”系列的第二部分。我们将重点解决当文档集合(表示为k-gram集合)过大时,如何高效地计算文档间相似度的问题。具体来说,我们将学习如何将大型集合转换为紧凑的“签名”向量,并利用这些签名来近似计算杰卡德相似度。
课程公告与项目提案提醒 📢
首先,提醒大家我们已经启用了Piazza平台进行课程交流,并因此禁用了Canvas中的讨论区,以避免信息交叉发布。如有任何问题,请通过Piazza联系我们。
接下来,重申关于抄袭和作弊的学术诚信政策,这与犹他大学计算学院的规定一致。如有疑问,请参考学生权利与责任守则。
关于即将于1月25日(两天后)截止的项目提案,大家提出了许多问题。以下是关键点:
- 内容要求:提案需说明小组成员、计划使用的数据及其来源、希望从数据中挖掘的结构、项目的意义以及导师能从中学习到什么新内容。
- 技术选择:即使课程尚未深入讲解所有算法,你们也需要根据所选数据和问题类型,自行研究课程日历和讲义,判断哪些技术可能适用。可以分工查阅资料。
- 反馈目的:提交提案的目的是让我们审核项目的可行性。即使你们选择的技术路径不完全合适,只要按要求提交了提案,就不会丢分,我们会提供反馈指导调整。
- 与机器学习项目的关系:原则上,希望数据挖掘项目使用不同的数据和问题。如果确实想研究同一问题,必须确保所使用的技术(如分类 vs. 聚类)、数据表示和预处理方法有显著不同,并需在提案中充分论证。如有疑虑,请直接联系我确认。
- 格式与长度:提案应简洁,控制在100-200词左右。
如有其他问题,欢迎在课后答疑时间咨询。


回顾:寻找相似项的问题 🎯
上一节我们介绍了如何将文档转换为k-gram集合,并通过计算集合的杰卡德相似度来衡量文档相似性。杰卡德相似度公式为:
Jaccard(S1, S2) = |S1 ∩ S2| / |S1 ∪ S2|
然而,当文档很长时,对应的k-gram集合会非常庞大,直接计算效率低下。
因此,本节我们将学习如何将这些大型集合转换为短小的“签名”向量,并确保能够从这些签名中准确地估计出原始的杰卡德相似度。
从概念到签名:最小哈希方法 🧠
我们的目标是:将大型集合转换为小向量(签名),并且能够基于签名估计杰卡德相似度。
特征矩阵
首先,我们引入一个概念工具——特征矩阵。该矩阵的行为全域集合中的所有元素(例如所有可能的k-gram),列为各个文档的集合。
- 如果元素
i出现在集合j中,则矩阵第i行第j列的值M[i][j] = 1。 - 否则,
M[i][j] = 0。
这是一个概念上的表示,在实际中因为矩阵过于稀疏,我们不会真正这样存储数据。
示例:
假设有集合:
S1 = {a, d}
S2 = {c}
S3 = {b, d, e}
S4 = {a, c, d}
全域元素为 {a, b, c, d, e},映射为行号 0 到 4。
其特征矩阵如下(列代表S1到S4):
| 行(元素) | S1 | S2 | S3 | S4 |
|---|---|---|---|---|
| 0 (a) | 1 | 0 | 0 | 1 |
| 1 (b) | 0 | 0 | 1 | 0 |
| 2 (c) | 0 | 1 | 0 | 1 |
| 3 (d) | 1 | 0 | 1 | 1 |
| 4 (e) | 0 | 0 | 1 | 0 |
最小哈希值
接下来,我们定义最小哈希值。这同样是一个概念性定义:
- 随机打乱特征矩阵的行序(即进行一个排列)。
- 对于每个集合(矩阵的列),其最小哈希值
h(S)定义为:在打乱行序后,从上往下扫描,第一个出现“1”的行号。
最小哈希的关键性质:对于任意两个集合 S1 和 S2,它们的最小哈希值相等的概率,恰好等于它们的杰卡德相似度!
Pr[h(S1) = h(S2)] = Jaccard(S1, S2)
证明思路:
考虑特征矩阵中对应S1和S2的两列。将所有行分为三类:
- X类:两列的值都为1(即元素在交集中)。
- Y类:一列为1,另一列为0(即元素在对称差中)。
- Z类:两列都为0。
在随机排列的行序中,从上往下扫描,首先遇到的是X类行的概率是 |X| / (|X| + |Y|),这正好是 |S1 ∩ S2| / |S1 ∪ S2|,即杰卡德相似度。而如果首先遇到的是Y类行,则两个集合的最小哈希值必然不同。
签名矩阵
单一的最小哈希值估计方差较大。为了获得更稳健的估计,我们使用 k 个不同的随机排列,从而得到 k 个不同的最小哈希函数 h1, h2, ..., hk。
对于一个包含 n 个文档的集合,我们构建一个签名矩阵:
- 矩阵有
k行(对应k个哈希函数)和n列(对应n个文档)。 - 第
i行第j列的值是hi(Sj),即第i个哈希函数对第j个文档集合计算得到的最小哈希值。
此时,两个文档签名向量的相似度(即对应列中值相同的行数比例),就是它们杰卡德相似度的无偏估计。
实践中的高效最小哈希算法 ⚡
上一节介绍的方法需要实际构造并打乱庞大的特征矩阵,这在实践中效率极低。本节我们来看看如何高效地计算签名矩阵。
核心思想是:用哈希函数来模拟行排列的效果。我们选择 k 个将元素映射到大整数范围的哈希函数(例如 h(x) = (ax + b) mod prime)。
快速最小哈希算法:
对于每个文档集合 S:
- 初始化一个长度为
k的签名向量sig,所有值设为无穷大(或一个非常大的数)。 - 遍历集合
S中的每一个元素x。 - 对于每一个哈希函数
hj(j 从 1 到 k):- 计算
hv = hj(x)。 - 如果
hv < sig[j],则更新sig[j] = hv。
- 计算
- 遍历完成后,向量
sig即为该文档的签名。
算法理解:
可以将哈希函数值 hj(x) 想象为元素 x 在某个虚拟的“行排列”中所处的位置。算法始终保留遇到的最小哈希值,这模拟了在排列后扫描时记录“第一个1”的行号的过程。
示例:
假设集合 S1 = {a, d},对应整数 {0, 3}。
选用两个哈希函数(仅为演示):
h1(x) = (x + 1) mod 5
h2(x) = (3x + 1) mod 5
初始化签名 sig = [∞, ∞]。
- 处理元素
0:h1(0)=1,小于sig[0]=∞,更新sig[0]=1。h2(0)=1,小于sig[1]=∞,更新sig[1]=1。
- 处理元素
3:h1(3)=4,不小于sig[0]=1,不更新。h2(3)= (9+1) mod 5 = 0,小于sig[1]=1,更新sig[1]=0。
最终得到 S1 的签名 sig = [1, 0]。
估计相似度:
要估计两个文档的杰卡德相似度,只需计算它们签名向量中对应位置值相同的比例。例如,若 S1 签名为 [1, 0],S3 签名为 [0, 0],则相似度估计为 1/2 = 0.5(实际杰卡德相似度需另行计算以验证估计质量)。
总结 📝
本节课我们一起学习了最小哈希技术的核心内容:
- 目标:将大型集合压缩成短签名,以高效估计杰卡德相似度。
- 概念基础:通过特征矩阵和行排列定义最小哈希值,并证明了
Pr[h(S1)=h(S2)] = Jaccard(S1, S2)。 - 签名构造:使用多个最小哈希函数构建签名矩阵,以降低估计误差。
- 高效算法:掌握了实践中使用的快速最小哈希算法,该算法通过哈希函数模拟行排列,无需构造庞大矩阵,只需线性扫描集合元素即可生成签名。

在下一讲中,我们将利用这些签名,通过“局部敏感哈希”技术,最终实现在海量文档集合中快速寻找相似项的目标。
006:距离 📏

在本节课中,我们将学习数据挖掘中常用的各种距离度量。理解这些距离对于后续的聚类分析以及构建高效的相似性搜索算法(如局部敏感哈希)至关重要。我们将从距离的数学定义开始,然后逐一介绍几种核心的距离度量,并探讨其中一些如何与特定的哈希函数族结合,用于近似最近邻搜索。
距离的定义与性质
上一节我们介绍了基于Jaccard相似度的局部敏感哈希技术。本节中,我们来看看距离的正式定义。与相似度不同,距离度量通常需要满足一些数学性质。
一个距离函数 d: X × X → [0, ∞) 将集合 X 中的点对映射到非负实数。如果它满足以下所有性质,则被称为度量:
- 非负性:
d(x, y) ≥ 0 - 同一性:
d(x, y) = 0当且仅当x = y - 对称性:
d(x, y) = d(y, x) - 三角不等式:
d(x, z) ≤ d(x, y) + d(y, z)
如果函数不满足同一性,则称为伪度量;如果不满足对称性,则称为拟度量。在实际应用中,有时人们会宽松地使用“距离”一词,即使某些性质不成立。
从相似度到距离
我们之前讨论过Jaccard相似度。自然地,可以定义对应的Jaccard距离。
Jaccard距离 定义为 1 减去 Jaccard 相似度:
d_J(A, B) = 1 - J(A, B) = 1 - (|A ∩ B| / |A ∪ B|)
可以证明,Jaccard距离满足所有度量性质,因此它是一个真正的度量。
常见的向量空间距离
当数据点表示为向量时,有一系列常用的距离度量。以下是其中几种核心的距离。
欧几里得距离 (L2距离)
这是最直观的距离,即两点间的“直线”距离。
d_E(a, b) = sqrt( Σ (a_i - b_i)^2 ) = ||a - b||_2
曼哈顿距离 (L1距离)
模拟在网格状道路(如曼哈顿街区)上行走的距离。
d_M(a, b) = Σ |a_i - b_i| = ||a - b||_1
闵可夫斯基距离 (Lp距离)
这是欧氏距离和曼哈顿距离的推广。
d_p(a, b) = ( Σ |a_i - b_i|^p )^(1/p) = ||a - b||_p
当 p=1 时为曼哈顿距离,p=2 时为欧氏距离。
切比雪夫距离 (L∞距离)
取所有维度上差值绝对值的最大值。
d_∞(a, b) = max_i |a_i - b_i| = ||a - b||_∞
为了帮助理解这些距离的计算,我们来看一个简单的例子。
计算示例:
假设有两个二维向量 a = (3, 4) 和 b = (7, 1)。
- L1 (曼哈顿) 距离:
|3-7| + |4-1| = 4 + 3 = 7 - L2 (欧几里得) 距离:
sqrt((3-7)^2 + (4-1)^2) = sqrt(16 + 9) = sqrt(25) = 5 - L∞ (切比雪夫) 距离:
max(|3-7|, |4-1|) = max(4, 3) = 4


马氏距离
当数据各维度的尺度(单位)不同或存在相关性时,直接使用Lp距离可能不恰当。马氏距离通过引入协方差矩阵(或其逆)来标准化距离。
d_M(a, b) = sqrt( (a - b)^T * Σ^{-1} * (a - b) )
其中 Σ 是数据的协方差矩阵。当 Σ 为单位矩阵时,马氏距离退化为欧氏距离。
余弦距离与角度距离
在文本挖掘等领域,向量的方向往往比大小更重要。这时会用到基于角度的距离。
余弦相似度与余弦距离
首先定义余弦相似度,即向量夹角的余弦值:
cos_sim(a, b) = (a · b) / (||a|| * ||b||)
其中 a · b 是点积。夹角越小,余弦值越接近1,表示越相似。
余弦距离通常定义为:
d_cos(a, b) = 1 - cos_sim(a, b)
需要注意的是,余弦距离不是一个度量。例如,向量 a 和 2a 方向相同,夹角为0,余弦距离为0,但它们并非同一个向量,违反了度量的同一性。
角度距离
角度距离直接使用向量间的夹角(通常以弧度为单位):
d_angle(a, b) = arccos( cos_sim(a, b) )
角度距离是一个度量,满足所有度量性质。有时在文献中,“余弦距离”指的就是角度距离,阅读时需注意区分。
为角度距离构建LSH族
回顾局部敏感哈希(LSH)的核心思想:为特定的距离或相似度度量,找到一个哈希函数族,使得相似的点以高概率哈希到同一个桶中。我们曾为Jaccard相似度找到了MinHash族。现在,我们也可以为角度距离构建这样的哈希函数族。
哈希函数族定义:
- 随机选取一个单位向量
u(即||u||=1)。 - 对于任意向量
a,定义哈希函数h_u(a) = sign(u · a)。这里sign是符号函数,若点积为正则输出+1,为负则输出-1。
关键性质:
可以证明,对于两个向量 a 和 b,在随机选择单位向量 u 的情况下,它们被哈希到相同值(即 h_u(a) = h_u(b))的概率为:
P[h_u(a) = h_u(b)] = 1 - (d_angle(a, b) / π)
这个性质与MinHash对于Jaccard相似度的性质(P = Jaccard相似度)类似。因此,这个基于随机超平面的哈希函数族,与角度距离一起,构成了另一个可用的LSH方案,满足 (d1, d2, p1, p2)-敏感性的要求。
总结
本节课中我们一起学习了数据挖掘中多种重要的距离度量。
- 我们首先明确了距离和度量的数学定义。
- 接着,回顾了从Jaccard相似度导出的Jaccard距离。
- 然后,系统学习了向量空间中常见的距离家族:欧氏距离(L2)、曼哈顿距离(L1)、闵可夫斯基距离(Lp)和切比雪夫距离(L∞),并了解了处理不同尺度数据的马氏距离。
- 之后,我们探讨了在文本等领域常用的余弦相似度、余弦距离以及更符合度量定义的角度距离。
- 最后,我们展示了如何为角度距离设计一个随机超平面哈希函数族,从而扩展了局部敏感哈希(LSH)技术的应用范围。

理解这些距离的适用场景和数学性质,是选择合适的数据挖掘算法(尤其是接下来的聚类算法)的基础。
007:嵌入与表示 📚

在本节课中,我们将学习如何将文本和图像等非结构化数据转换为计算机可以理解和处理的数值形式,即“表示”。我们将重点介绍几种核心的表示方法,包括TF-IDF、词嵌入和上下文化表示,并简要探讨图像表示。理解这些方法对于后续进行相似性计算、聚类等数据挖掘任务至关重要。


文本表示:从词袋到词嵌入
上一节我们讨论了基于集合(如k-gram)的相似性度量。本节中,我们来看看如何将文本表示为数值向量,以便进行更复杂的计算。
词袋模型与TF-IDF
词袋模型将文档表示为一个向量,其中每个维度对应一个词,其值为该词在文档中出现的次数。然而,这种方法忽略了词的重要性和文档间的差异。
以下是TF-IDF(词频-逆文档频率)方法,它通过结合局部和全局信息来改进词袋模型。
- 词频:衡量一个词在单个文档中的重要性。公式为:
TF(t, d) = (词t在文档d中的出现次数) / (文档d的总词数)。有时也直接使用原始计数。 - 逆文档频率:衡量一个词在整个文档集合中的普遍重要性。公式为:
IDF(t) = log(文档总数 / 包含词t的文档数)。IDF值高意味着该词在少数文档中出现,具有较好的区分度。 - TF-IDF权重:最终的词权重是TF和IDF的乘积:
TF-IDF(t, d) = TF(t, d) * IDF(t)。
通过计算每个文档中所有词的TF-IDF值,我们可以构建一个词-文档矩阵。每个文档可以表示为该矩阵的一列(文档向量),然后使用余弦相似度等度量来计算文档间的相似性。
词嵌入:密集向量表示
TF-IDF向量通常是稀疏的(包含大量零值)。词嵌入提供了一种密集的、低维的向量表示。
其核心思想基于分布假说:出现在相似上下文中的词往往具有相似的含义。因此,词嵌入的目标是学习一个向量空间,使得语义相近的词在空间中的位置也接近。
一个著名的词嵌入模型是Word2Vec,它包含两种算法:Skip-gram with Negative Sampling (SGNS) 和 Continuous Bag of Words (CBOW)。其训练过程简述如下:
- 给定一个目标词(如“apricot”)及其上下文窗口(如左右各两个词)。
- 模型的目标是:最大化目标词向量与其上下文词向量之间的相似度(点积)。
- 同时,模型会采样一些不在上下文中的“负例”词,并最小化目标词向量与这些负例词向量的相似度。
- 通过反复迭代上述过程,更新所有词的向量表示,最终得到训练好的词嵌入。
训练完成后,我们可以丢弃模型,只保留这些词向量。对于一个句子,常见的表示方法是将其所有词的词向量取平均值,得到一个句子的密集向量表示。

使用词嵌入时需要注意:
- 静态性:每个词只有一个固定的向量,无法处理一词多义。
- 偏见:词嵌入会反映并放大训练数据中存在的社会偏见(如性别、职业偏见),可能导致资源分配不公或代表性伤害。

上下文化表示
为了解决一词多义问题,出现了基于Transformer架构的上下文化表示模型(如BERT)。这类模型的核心是自注意力机制,它能够根据句子中其他词的信息来动态调整每个词的表示。
训练时,模型通过预测被掩盖的词语来学习上下文信息。使用时,将整个句子输入模型,对输出的每个词的表示进行平均(或使用特殊的[CLS]标记),即可得到整个句子的表示。这类表示能更好地捕捉语义。
图像表示 🖼️
与文本类似,图像也需要转换为数值表示。最基本的方法是将图像视为像素矩阵(灰度图)或三通道张量(RGB彩色图)。
深度特征表示
当前,最常用的图像表示方法是利用预训练的深度神经网络提取特征。
- 卷积神经网络特征:例如,Faster R-CNN等模型在图像分类任务上预训练后,可以提取图像中不同区域或整个图像的特征向量。这些向量编码了高级视觉信息。
- 多模态模型特征:如CLIP模型,同时在图像和文本数据上训练。其图像编码器部分输出的特征向量,与语义信息关联更强,是目前性能优异的图像表示方法。
选择图像表示方法时需考虑:
- 计算资源:大型模型(如CLIP)需要较强的硬件支持。
- 领域适应性:预训练数据的领域应与目标应用相近(例如,用自然图像训练的模型处理医学X光片效果可能不佳)。
- 社会偏见:图像表示模型同样可能继承和放大训练数据中的偏见,需谨慎评估。
总结

本节课我们一起学习了数据挖掘中至关重要的数据表示技术。
- 对于文本,我们介绍了从稀疏的TF-IDF表示,到基于分布假说的静态词嵌入(如Word2Vec),再到能处理一词多义的上下文化表示(如BERT)的演进。
- 对于图像,我们了解了从原始像素到利用预训练深度神经网络(如CNN、CLIP)提取高级特征向量的方法。
- 无论哪种表示,其目标都是将数据转换为稠密、低维且蕴含语义/视觉信息的向量,以便后续进行相似性计算、聚类、分类等任务。在选择具体方法时,需要综合考虑任务需求、数据特性、计算成本以及模型可能带来的偏见等问题。
008:分层聚类 📊

在本节课中,我们将要学习一种重要的数据挖掘技术——分层聚类。我们将了解其基本思想、算法步骤、如何衡量簇之间的距离、何时停止合并簇,以及该方法的优缺点。
概述
分层聚类是一种“自底向上”的聚类方法。其核心思想是:开始时,将每个数据点视为一个独立的簇;然后,反复合并两个“最接近”的簇,直到满足停止条件。最终,我们会得到一个簇的层次结构,可以直观地表示为树状图。
算法步骤
分层聚类算法的流程非常直观。
- 初始化:将数据集中的每个数据点
Xi都视为一个单独的簇。 - 循环合并:当不满足停止条件时,重复以下步骤:
- 寻找最近簇:在所有簇对中,找到距离最近的两个簇
Ci和Cj。 - 合并簇:将
Ci和Cj合并为一个新的簇。
- 寻找最近簇:在所有簇对中,找到距离最近的两个簇
如何衡量簇间距离
算法的关键在于如何定义两个簇之间的“距离”或“接近度”。以下是几种常见的方法:
- 质心距离:计算每个簇的质心(即簇内所有点的平均向量),然后计算两个质心之间的距离。公式为:
d(C1, C2) = distance(centroid(C1), centroid(C2))。这种方法适用于欧几里得空间。 - 单链距离:取两个簇中任意两点间距离的最小值。公式为:
d(C1, C2) = min{distance(x, y) for x in C1, y in C2}。它对噪声和离群点敏感,容易形成“链式”簇。 - 全链距离:取两个簇中任意两点间距离的最大值。公式为:
d(C1, C2) = max{distance(x, y) for x in C1, y in C2}。它倾向于产生紧凑的球形簇。 - 平均链距离:计算两个簇中所有点对之间距离的平均值。公式为:
d(C1, C2) = average{distance(x, y) for x in C1, y in C2}。这是单链和全链之间的一个折中。 - 基于半径/直径的距离:合并两个簇后,计算新簇的半径(质心到最远点的距离)或直径(簇内最远两点间的距离)。选择合并后能使半径或直径最小的簇对。这有助于保持簇的紧密度。
何时停止合并
上一节我们介绍了如何合并簇,本节中我们来看看算法何时应该停止。这通常取决于具体的应用场景和目标。
- 达到预定簇数量:当合并到只剩下
K个簇时停止。这需要事先对数据有较好的了解。 - 距离阈值:当最近的两个簇之间的距离超过某个预设阈值时停止。
- 簇的紧密度:当合并会产生一个“质量不佳”的簇时停止。例如,新簇的半径或直径过大,或者簇内点的平均距离超过限制。
- 肘部法则:绘制随着簇数量减少,某个指标(如误差平方和)的变化曲线。当曲线出现明显的拐点(像肘部)时,对应的簇数量可能是最佳选择。
- 构建完整树:不设置停止条件,一直合并到只剩下一个包含所有数据点的簇。最终结果是一个完整的层次树(树状图),用户可以根据需要从树的任何层级“切割”出特定数量的簇。
算法效率分析
分层聚类算法概念简单,但计算复杂度较高。
- 朴素实现:在每一步都需要计算和比较所有簇对的距离。总时间复杂度约为 O(n³),其中
n是数据点的数量。这对于大规模数据集来说非常慢。 - 优化实现(使用优先队列):可以维护一个优先队列来高效地查找最近簇对。优化后的时间复杂度约为 O(n² log n)。虽然比立方级好,但对于海量数据仍然不够高效。
因此,分层聚类更适合中小规模数据集,或者当数据本身具有清晰的层次结构时使用。
聚类结果验证
在得到聚类结果后,我们需要评估其质量。以下是几种验证方法:
- 人工抽样检查:从每个簇中随机抽取一些样本,人工检查它们是否属于合理的类别。
- 降维可视化:使用降维技术(如PCA、t-SNE)将高维数据投影到2D或3D空间,然后可视化观察簇的分布是否清晰可辨。
- 肘部法则:如前所述,通过绘制误差平方和与簇数量的关系图,寻找拐点来评估最佳的簇数量。
总结

本节课中我们一起学习了分层聚类算法。我们了解了其自底向上的合并过程,探讨了多种衡量簇间距离的方法(如质心、单链、全链等),讨论了决定何时停止合并的策略,并分析了算法的时间复杂度。最后,我们简要介绍了如何验证聚类结果的有效性。分层聚类是一种直观且能揭示数据层次结构的强大工具,尤其适用于簇数量未知或数据具有内在层次关系的场景。
009:K均值聚类

在本节课中,我们将学习一种非常流行的聚类算法——K均值。我们将从问题定义开始,逐步推导出具体的算法步骤,并讨论其性质、初始化技巧、变体以及如何评估聚类结果。
概述
上一讲我们介绍了层次聚类算法。本节我们将探讨另一种核心的聚类方法:K均值。K均值通常指代一个具体的算法(劳埃德算法),也可以指代一类基于最小化“簇内平方误差”的聚类问题。我们将学习其工作原理、优缺点,并了解如何选择初始中心点以及如何验证聚类结果的质量。
K均值问题定义与算法推导
K均值的目标是将N个数据点划分到K个互不重叠的“硬”簇中。其核心思想是迭代地优化簇的中心点(质心)和点的分配。
核心概念与目标函数
我们首先定义一个需要最小化的准则函数(或称成本函数、误差函数)J:
J = Σ (k=1 to K) Σ (x in C_k) ||x - c_k||²
其中:
- C_k 表示第k个簇。
- c_k 表示第k个簇的质心(中心点)。
- ||x - c_k|| 是数据点x与其所属簇质心c_k之间的欧几里得距离。
这个函数J衡量了所有数据点与其所属簇质心之间的总距离平方和。我们的目标就是找到簇分配和质心位置,使得J最小。
迭代优化过程
直接最小化J没有闭式解。因此,我们采用一种迭代的、两步交替的优化方法:
- 分配步骤:固定质心
{c_k},将每个数据点x_i分配给距离它最近的质心所属的簇。这通过定义变量b_ik来实现,当k是使||x_i - c_k||最小的簇索引时,b_ik = 1,否则为0。 - 更新步骤:固定点的分配
{b_ik},更新每个簇的质心c_k。通过对J关于c_k求导并令导数为零,可以推导出最优的c_k就是该簇内所有点的平均值:c_k = (1/|C_k|) Σ (x in C_k) x
K均值(劳埃德)算法
基于上述推导,我们可以形式化地写出K均值算法(又称劳埃德算法):
- 输入:数据点
{x_1, ..., x_n},簇数量K。 - 随机初始化
K个质心{c_1, ..., c_K}。 - 重复以下步骤直到收敛(质心不再变化):
- 分配:对于每个数据点
x_i,计算其到所有质心的距离,并将其分配给最近的质心对应的簇。 - 更新:对于每个簇
C_k,将其质心c_k更新为该簇内所有点的平均值。
- 分配:对于每个数据点
- 输出:最终的簇划分
{C_1, ..., C_K}和质心{c_1, ..., c_K}。
K均值的性质与讨论
了解了算法流程后,我们来分析其重要性质。
以下是K均值算法的一些关键特性:
- 硬聚类:每个点只属于一个簇。
- 效率:算法复杂度约为 O(T * n * K * d),其中T是迭代次数,n是点数,K是簇数,d是数据维度。这比层次聚类的O(n²)更高效。
- 收敛性:由于J在每次迭代后都不增加(通常减少),且可能的划分组合有限,算法保证收敛。
- 局部最优:算法容易陷入局部最优解,最终结果严重依赖于初始质心的选择。
- 距离假设:标准K均值使用欧几里得距离,并隐含假设数据点可以计算平均值(即处于欧氏空间)。
质心初始化方法
由于初始质心选择至关重要,我们介绍几种改进随机初始化的方法。
以下是几种常见的质心初始化策略:
- 随机点:从数据点集合中随机选择K个点作为初始质心。这避免了选择远离数据分布的质心,但对异常值敏感。
- 全局中心扰动:计算所有数据点的全局中心,然后加上K个小的随机向量,得到K个初始质心。这对异常值有一定鲁棒性。
- K-means++:首先随机选择一个数据点作为第一个质心。然后,对于每个后续质心,以正比于其与已有最近质心距离的概率选择一个数据点。这倾向于选择彼此远离的点,同时降低了选中孤立异常点的概率。
- Gonzalez算法:随机选择一个点作为第一个质心,后续每次选择距离当前所有质心最远的数据点作为新质心。这是K-means++的一种确定性变体。
K中心点算法:处理任意距离
当数据不处于欧氏空间或无法计算平均值时,我们需要K均值的一个变体——K中心点算法。
K中心点算法使用“中心点”代替“质心”。中心点是簇中一个实际存在的数据点,作为簇的代表。对应的算法称为PAM(围绕中心点的划分)。
以下是PAM算法的步骤:
- 随机选择K个数据点作为初始中心点
{m_1, ..., m_K}。 - 重复直到收敛:
- 分配:将每个非中心点数据点分配到距离它最近的中心点所属的簇。
- 更新:对于每个簇,尝试用簇内其他点替换当前中心点,选择能使簇内所有点到新中心点的总距离最小的点作为新中心点。
该算法的复杂度更高,约为 O(T * K * (n-K)²),但可以处理任意定义的距离函数。
聚类验证与簇数选择
最后,我们回到如何评估聚类结果和选择合适簇数K的问题。这与上一讲末尾的内容相衔接。
轮廓系数分析
轮廓系数是一种结合了簇内凝聚度和簇间分离度的评估指标,适用于单个样本点。
对于数据点 x_i:
- a(i):
x_i与同簇内所有其他点之间的平均距离(凝聚度)。 - b(i):
x_i到其他每个簇中所有点平均距离的最小值(分离度)。 - 轮廓系数 s(i):s(i) = (b(i) - a(i)) / max{a(i), b(i)}
s(i) 取值范围为[-1, 1]:
s(i)接近1:点i聚类恰当,远离其他簇。s(i)接近0:点i位于两个簇的边界。s(i)接近-1:点i可能被误分到其他簇。
通过绘制所有点的轮廓系数并按簇排序,可以直观评估每个簇的紧致度以及整体聚类质量。通常,我们希望每个簇的轮廓系数都高于平均值,且没有大量负系数的点。
其他验证方法
除了轮廓分析,还有多种方法可以帮助我们选择K或验证聚类。
以下是一些常用的簇数选择和验证方法:
- 肘部法则:绘制不同K值对应的总簇内平方误差(SSE,即目标函数J)。SSE随K增大而下降。选择曲线拐点(形如肘部)对应的K值,此时增加K带来的收益锐减。
- 正则化准则:在最小化SSE的同时,加入对模型复杂度的惩罚。例如,贝叶斯信息准则(BIC)给出公式:BIC = J + 2 * d * K,选择使BIC最小的K。
- 利用部分标注数据:如果能够获取少量数据的真实簇标签(参考簇),则可以使用外部指标评估聚类结果与参考簇的一致性。常用指标是调整兰德指数,它计算了“点对”在两种划分下一致性的校正值,其值越接近1表示一致性越好。
总结

本节课我们一起学习了K均值聚类。我们从最小化簇内平方误差的目标函数出发,推导出了迭代的K均值(劳埃德)算法。我们讨论了该算法的效率、收敛性以及对初始值敏感的缺点,并介绍了几种改进的质心初始化方法。为了处理非欧氏空间的数据,我们了解了其变体K中心点算法。最后,我们系统回顾了聚类验证的方法,包括视觉评估、肘部法则、轮廓系数分析以及利用部分标注数据的调整兰德指数,这些工具能帮助我们选择合理的簇数并评估聚类结果的有效性。
010:谱聚类

在本节课中,我们将学习一种特殊的聚类算法——谱聚类。谱聚类基于图论思想,将数据点视为图中的节点,通过寻找图中连接紧密但组间连接稀疏的分区来实现聚类。我们将从图的基本定义开始,逐步引入谱聚类所需的核心概念和矩阵,最后构建完整的算法流程。
图的基本定义
上一节我们概述了谱聚类的核心思想。本节中,我们来看看实现谱聚类所需的一些基本图论概念。
图是一种抽象的数据结构,由一组顶点和连接顶点的边构成。
- 顶点集:记作 V = {v₁, v₂, ..., vₙ},包含 n 个顶点。
- 边集:记作 E = {e₁, e₂, ..., eₘ},每条边连接两个顶点,例如连接 vₗ 和 vₖ。
- 无向图:我们主要处理无向图,即边没有方向。如果顶点 A 与 B 相连,则 B 也与 A 相连。
- 邻接矩阵:这是图的常用数学表示。对于一个有 n 个顶点的图,其邻接矩阵 W 是一个 n×n 的矩阵。如果顶点 i 和 j 之间有边相连,则 Wᵢⱼ = 1,否则为 0。对于无向图,该矩阵是对称的,即 Wᵢⱼ = Wⱼᵢ。
- 加权图:边可以带有权重,表示连接强度。此时,邻接矩阵 W 中的元素 Wᵢⱼ 表示顶点 i 和 j 之间边的权重。权重为非负值,Wᵢⱼ = 0 表示两顶点间无边。
- 顶点的度:顶点 vᵢ 的度 dᵢ 是其所有连接边的权重之和。公式为:dᵢ = Σⱼ Wᵢⱼ。
- 度矩阵:这是一个对角矩阵 D,其对角线上的第 i 个元素就是顶点 vᵢ 的度 dᵢ,非对角线元素为 0。
- 子集间的权重:对于顶点集的子集 A 和 B,它们之间的权重 W(A, B) 定义为所有连接 A 中顶点和 B 中顶点的边的权重之和。公式为:W(A, B) = Σ_{i∈A, j∈B} Wᵢⱼ。
- 子集的大小:有两种常用定义。
- 基数:子集 A 中顶点的数量,记作 |A|。
- 体积:子集 A 中所有顶点的度之和,记作 vol(A) = Σ_{i∈A} dᵢ。
- 图的分割:将顶点集 V 划分为 k 个子集 A₁, A₂, ..., Aₖ,满足每个子集非空,且所有子集互不相交,它们的并集等于 V。
图分割问题与谱聚类的联系
了解了图的基本概念后,本节我们来看看谱聚类试图解决的核心问题——图分割,以及两者之间的联系。
谱聚类本质上是图分割问题的一种近似解法。图分割的目标是将图划分为 k 个部分,使得各部分内部的连接尽可能紧密,而不同部分之间的连接尽可能稀疏。
最朴素的分割方法是解决最小割问题,即寻找分割 {A₁, ..., Aₖ},以最小化割值 cut(A₁, ..., Aₖ)。割值定义为连接不同子集的边的权重之和。对于 k=2 的情况,公式为:cut(A₁, A₂) = W(A₁, A₂)。对于 k>2,公式推广为:cut(A₁, ..., Aₖ) = (1/2) Σ_{i=1}^{k} W(Aᵢ, V\Aᵢ),其中 V\Aᵢ 是 Aᵢ 的补集。
然而,最小割问题存在一个平凡解:将单个顶点作为一个子集,其余所有顶点作为另一个子集。这通常不是有意义的聚类结果。因此,我们需要引入平衡约束,确保每个子集都“足够大”。这催生了两种改进的割准则:
- 比率割:最小化 RatioCut(A₁, ..., Aₖ) = (1/2) Σ_{i=1}^{k} [W(Aᵢ, V\Aᵢ) / |Aᵢ|]。这里使用子集的基数 |Aᵢ| 作为平衡项。
- 规范割:最小化 NCut(A₁, ..., Aₖ) = (1/2) Σ_{i=1}^{k} [W(Aᵢ, V\Aᵢ) / vol(Aᵢ)]。这里使用子集的体积 vol(Aᵢ) 作为平衡项。
谱聚类算法正是通过求解上述比率割或规范割问题的松弛版本而得到的。
- 求解松弛的比率割问题,对应非规范化谱聚类。
- 求解松弛的规范割问题,对应规范化谱聚类。
图拉普拉斯矩阵
上一节我们引入了图分割的优化目标。本节中,我们来看看实现谱聚类的关键数学工具——图拉普拉斯矩阵。
图拉普拉斯矩阵有多种形式,它们在图分析和谱聚类中扮演核心角色。
- 非规范化图拉普拉斯矩阵:定义为度矩阵与邻接矩阵之差。公式为:L = D - W。这是一个对称矩阵,具有 n 个非负的实特征值。
- 规范化图拉普拉斯矩阵:有两种常见形式。
- 对称归一化形式:L_sym = D^{-1/2} L D^{-1/2} = I - D^{-1/2} W D^{-1/2}。
- 随机游走归一化形式:L_rw = D^{-1} L = I - D^{-1} W。
这些矩阵的特征值和特征向量对于谱聚类至关重要。特别是,非规范化拉普拉斯矩阵 L 有一个平凡特征值 0,对应的特征向量是所有元素为 1 的向量。谱聚类通常关注的是第二小特征值对应的特征向量。
从相似性数据到相似图
在应用谱聚类之前,我们需要将原始数据点转化为图结构。本节介绍如何根据数据点之间的相似性构建相似图。
给定数据点 x₁, x₂, ..., xₙ,以及点对之间的相似性度量 sᵢⱼ(或距离),我们可以构建一个加权图。顶点对应数据点,边的权重通常由相似性决定。构建相似图有几种常见策略:
- ε-邻近图:仅当两点间的距离小于某个阈值 ε 时,才连接它们。
- k-最近邻图:连接每个点与其 k 个最相似的点。由于相似性可能不对称,这会产生有向边。通常进行对称化处理:
- 简单k近邻图:只要点 i 在点 j 的 k 近邻中,或点 j 在点 i 的 k 近邻中,就连接 i 和 j。
- 互k近邻图:仅当点 i 和点 j 互为对方的 k 近邻时,才连接它们。
- 全连接图:连接所有点,边的权重即为相似度 sᵢⱼ。常用高斯核函数计算相似度:sᵢⱼ = exp(-||xᵢ - xⱼ||² / (2σ²))。
选择哪种构图方法取决于具体问题和数据特性,没有绝对最优的通用准则。
谱聚类算法
掌握了所有预备知识后,本节我们正式介绍谱聚类算法的具体步骤。这里以非规范化谱聚类为例。
输入:
- n 个数据点 x₁, ..., xₙ
- 相似性矩阵 S(或相似性计算函数)
- 聚类数目 k
算法步骤:
- 构建相似图:根据选定的策略(如全连接、k-NN等),由相似性矩阵 S 构建加权邻接矩阵 W。
- 计算图拉普拉斯矩阵:计算非规范化图拉普拉斯矩阵 L = D - W,其中 D 是度矩阵。
- 特征分解:计算矩阵 L 的前 k 个最小特征值对应的特征向量 u₁, u₂, ..., uₖ(每个是 n 维向量)。
- 构建特征向量矩阵:将这 k 个特征向量作为列向量,形成一个 n × k 的矩阵 U = [u₁ u₂ ... uₖ]。
- 构建新特征空间:令 yᵢ ∈ Rᵏ 为矩阵 U 的第 i 行(i=1,...,n)。这样,每个原始数据点 xᵢ 被映射到一个 k 维空间中的点 yᵢ。
- 聚类新数据点:使用 k-means 算法将新数据点 {y₁, ..., yₙ} 聚类成 k 个簇 C₁, ..., Cₖ。
- 输出原始聚类结果:最终,将原始顶点 vᵢ 分配到簇 C̃ⱼ 中,当且仅当其对应的新表示 yᵢ 属于 k-means 产生的簇 Cⱼ。
对于规范化谱聚类,算法流程类似,主要区别在于第 2 步和第 3 步:使用规范化图拉普拉斯矩阵(如 L_sym 或 L_rw)并进行其特征分解。
总结

本节课中,我们一起学习了谱聚类算法。我们从图的基本定义出发,引入了邻接矩阵、度矩阵、图拉普拉斯矩阵等核心概念。我们了解到谱聚类旨在近似解决图的分割问题(如比率割或规范割),并通过松弛技术将其转化为求解图拉普拉斯矩阵特征向量的问题。最后,我们详细介绍了谱聚类的完整算法步骤:构建相似图、计算拉普拉斯矩阵、进行特征分解、在新特征空间中使用 k-means 进行聚类。谱聚类特别适用于发现复杂形状的簇,是数据挖掘中一个强大而灵活的工具。

浙公网安备 33010602011771号