mahout LDA

article/2025/10/9 22:08:22

什么是Mahout?

” Apache Mahout™ project’s goal is to build a scalable machine learning library ”

我来拓展一下:
(1) Mahout 是Apache旗下的开源项目,集成了大量的机器学习算法。
(2) 大部分算法,可以运行在Hadoop上,具有很好的拓展性,使得大数据上的机器学习成为可能。

本篇主要探讨 Mahout 0.9 中的聚类(Clustering)工具的用法。

一、数据准备

Mahout聚类算法的输入为List<Vector>,即需要将每个待聚类的文档,表示为向量形式。

在本文中,我们选择经典的 Reuters21578 文本语料。尝试对新闻内容进行文本聚类。

1、下载数据

2、解压缩数据

解压缩之后,reuters-sgm下,包含了若干*.sgm文件,每个文件中又包含了若干下属结构化文档:

在下文中,我们主要使用<TITLE>和<BODY>中的文本。即标题+正文。

3、抽取

Mahout中内置了对上述Reuters预料的抽取程序,我们可以直接使用。

如上所述,抽取好的结果在./reuters-out文件夹下面,每篇<REUTERS>文档,变成了一个独立的文件。

一共有21578个txt,即数据集中含有21578篇文档:-)

说下命名规则吧,例如:文件名:./reuters-out/reut2-006.sgm-246.txt,表示来自于./reuters-sgm/reut2-006.sgm中的第246篇文档,下标从0开始。

4、转换成SequenceFile

对于传统的文本聚类算法而言,下一步应该是:将文本转化为词的向量空间表示。

然而,不要太着急哦。

由于Mahout运行在Hadoop上,HDFS是为大文件设计的。如果我们把上述21578个txt都拷贝上去,这样是非常不合适的

设想下:假设对1000万篇新闻进行聚类,难道要拷贝1000w个文件么?这会把name node搞挂的。

因此,Mahout采用SequenceFile作为其基本的数据交换格式。

内置的seqdirectory命令(这个命令设计的不合理,应该叫directoryseq才对),可以完成 文本目录->SequenceFile的转换过程。

上述命令蕴含了2个大坑,在其他文档中均没有仔细说明:
(1) -xm sequential,表示在本地执行,而不是用MapReduce执行。如果是后者,我们势必要将这些小文件上传到HDFS上,那样的话,还要SequenceFile做甚……
(2) 然而seqdirectory在执行的时候,并不因为十本地模式,就在本地文件系统上寻找。而是根据-i -o的文件系统前缀来判断文件位置。也就是说,默认情况,依然十在HDFS上查找的……所以,这个file://的前缀是非常有必要的。

其他2个参数:

  • -c UTF8:编码。
  • -chunk 64:64MB一个Chunk,应该和HDFS的BLOCK保持一致或者倍数关系。

5、转换为向量表示

为了适应多种数据,聚类算法多使用向量空间作为输入数据。

首先在HDFS  上创建目录user/coder4

hadoop  fs  -mkdir  user/coder4

由于我们先前已经得到了处理好的SequenceFile,从这一步开始,就可以在Hadoop上进行啦。

开始text->Vector的转换:

输入和输出不解释了。在Mahout中的向量类型可以称为sparse。

参数说明如下:

  • -ow( 或 –overwrite):即使输出目录存在,依然覆盖。
  • –weight(或 -wt) tfidf:权重公式,大家都懂的。其他可选的有tf (当LDA时建议使用)。
  • –maxDFPercent(或 -x) 85:过滤高频词,当DF大于85%时,将不在作为词特征输出到向量中。
  • –namedVector (或-nv):向量会输出附加信息。

其他可能有用的选项:

  • –analyzerName(或-a):指定其他分词器。
  • –minDF:最小DF阈值。
  • –minSupport:最小的支持度阈值,默认为2。
  • –maxNGramSize(或-ng):是否创建ngram,默认为1。建议一般设定到2就够了。
  • –minLLR(或 -ml):The minimum Log Likelihood Ratio。默认为1.0。当设定了-ng > 1后,建议设置为较大的值,只过滤有意义的N-Gram。
  • –logNormalize(或 -lnorm):是否对输出向量做Log变换。
  • –norm(或 -n):是否对输出向量做p-norm变换,默认不变换。

看一下产出:

说明各个文件的用途:

  • dictionary.file-0:词文本 -> 词id(int)的映射。词转化为id,这是常见做法。
  • frequency.file:词id -> 文档集词频(cf)。
  • wordcount(目录): 词文本 -> 文档集词频(cf),这个应该是各种过滤处理之前的信息。
  • df-count(目录): 词id -> 文档频率(df)。
  • tf-vectors、tfidf-vectors (均为目录):词向量,每篇文档一行,格式为{词id:特征值},其中特征值为tf或tfidf。有用采用了内置类型VectorWritable,需要用命令”mahout vectordump -i <path>”查看。
  • tokenized-documents:分词后的文档。

二、KMeans

1、运行K-Means

参数说明如下:

  • -i:输入为上面产出的tfidf向量。
  • -o:每一轮迭代的结果将输出在这里。
  • -k:几个簇。
  • -c:这是一个神奇的变量。若不设定k,则用这个目录里面的点,作为聚类中心点。否则,随机选择k个点,作为中心点。
  • -dm:距离公式,文本类型推荐用cosine距离。
  • -x :最大迭代次数。
  • –clustering:在mapreduce模式运行。
  • –convergenceDelta:迭代收敛阈值,默认0.5,对于Cosine来说略大。

输出1,初始随机选择的中心点:

输出2,聚类过程、结果:

其中,clusters-k(-final)为每次迭代后,簇的20个中心点的信息。

而clusterdPoints,存储了 簇id -> 文档id 的映射。

2、查看簇结果

首先,用clusterdump,来查看k(20)个簇的信息。

要说明的是,clusterdump似乎只能在本地执行……所以先把数据下载到本地吧。

参数说明:

  • -i :我们只看最终迭代生成的簇结果。
  • -d :使用 词 -> 词id 映射,使得我们输出结果中,可以直接显示每个簇,权重最高的词文本,而不是词id。
  • -dt:上面映射类型,由于我们是seqdictionary生成的,so。。
  • -o:最终产出目录
  • -n:每个簇,只输出20个权重最高的词。

看看dump结果吧:

一共有20行,表示20个簇。每行形如:

其中前面的12722是簇的ID,n=1305即簇中有这么多个文档。c向量是簇中心点向量,格式为 词文本:权重(点坐标),r是簇的半径向量,格式为 词文本:半径。

下面的Top Terms是簇中选取出来的特征词。

3、查看聚类结果

其实,聚类结果中,更重要的是,文档被聚到了哪个类。

遗憾的是,在很多资料中,都没有说明这一点。前文我们已经提到了,簇id -> 文档id的结果,保存在了clusteredPoints下面。这也是mahout内置类型存储的。我们可以用seqdumper命令查看。

其中,-d和-dt的原因同clusterdump。

如果不指定-o,默认输出到屏幕,输出结果为形如:

其实,这个输出是一个SequenceFile,大家自己写程序也可以读出来的。

Key是ClusterID,上面clusterdump的时候,已经说了。

Value是文档的聚类结果:wt是文档属于簇的概率,对于kmeans总是1.0,/reut2-000.sgm-0.txt就是文档标志啦,前面seqdirectionary的-nv起作用了,再后面的就是这个点的各个词id和权重了。

三、Fuzzy-KMeans

KMeans是一种简单有效的聚类方法,但存在一些缺点。

例如:一个点只能属于一个簇,这种叫做硬聚类。而很多情况下,软聚类才是科学的。例如:《哈利波》属于小说,也属于电影。Fuzzy-Kmeans 通过引入“隶属度”的方式,实现了软聚类。

1、算法简介

详细的介绍转载自:http://home.deib.polimi.it/matteucc/Clustering/tutorial_html/cmeans.html

Clustering - Fuzzy C-means

2、工具用法

执行Fuzzy-KMeans

新增算法的柔软参数m,若m接近于1则接近于KMeans;随着m增加,会有越来越多的聚簇重叠(越多的点同时属于多个聚簇)。

3、查看隶属度

如上文所述,在Fuzzy-KMeans中,点以一定的 “概率” 隶属于聚簇。

我们可以用seqdumper查看隶属度:

其中的 w: xxx.xxx表示了 隶属度,应当是 0~1之间的数。

四、Canopy

KMeans算法还有一个缺陷: k需要预先给定,在很多场景下,聚类形状都是预先无法知道的,k更无从谈起。因此,往往先用别的算法进行粗略聚类,同时确定初始值,然后再用KMeans算法。

1、算法简介

Canopy Clustering 算法提出于2000年。优点是计算速度快,缺点是结果准确性较低。

尽管如此,其结果依然可以大致描述 聚类中心的位置。因此,常用来与KMeans算法配合使用。

(1) 将数据集向量化得到一个list后放入内存,选择两个距离阈值:T1和T2,其中T1 > T2,对应上图,实线圈为T1,虚线圈为T2,T1和T2的值可以用交叉校验来确定;
(2) 从list中任取一点P,用低计算成本方法快速计算点P与所有Canopy之间的距离(如果当前不存在Canopy,则把点P作为一个Canopy),如果点P与某个Canopy距离在T1以内,则将点P加入到这个Canopy;
(3) 如果点P曾经与某个Canopy的距离在T2以内,则需要把点P从list中删除,这一步是认为点P此时与这个Canopy已经够近了,因此它不可以再做其它Canopy的中心了;
(4) 重复步骤2、3,直到list为空结束。

我再来简单概括一下:阈值T1 > T2。到簇中心点的距离 < T2的点,必须属于本聚簇(硬)。T2 < 到簇中心点距离 < T1的点,可以属于多个聚簇(软)。在后续计算可以被合并。

2、聚类用法

执行Canopy聚类

如上所述,在距离的计算方面,我们选择了欧式距离。阈值T1=150, t2=75。

输出结果,也可以用ClusterDump查看。

这是一个粗略、大致的结果。在实际应用中,经常被用来作为K-Means的初始聚簇中心,来代替随机选择的K个中心点。这一做法有2个优点:
(1) 无需决定K,因为我们的预设往往是不准的。
(2) 使用Canopy的聚类结果,是一个大致准确的中心点。而随机选择很可能陷入局部最优。

在执行k-means时,若我们不指定k,则会使用-c的路径作为初始聚簇中心点,并跳过随机选择的过程。

3、参数选择

最后,我们讨论以下Canopy的参数T1和T2。

  • T1 > T2,具体值是文档及距离计算公式而定。
  • 若T1过大,会使得许多点属于多个Canopy,造成各个簇的中心点距离比较近,使得簇之间的区分不明显。
  • 若T2过大,强标记数据点的数量会增加,从而减少簇个数。
  • 若T2过小,会增加簇的个数,以及计算时间。

网上有人给出了这个做法,仅供参考:

  1. 对数据进行采样。
  2. 计算所有文档之间的平均距离(使用要在Canopy中用的距离公式)。
  3. T1 = 平均距离 * 2;T2 = 平均距离。

上述做法有一定道理,但我认为,以下更加合理:

  1. 对数据进行采样。
  2. 选择一个T2,T1 = 2 * T1。
  3. 进行聚类,并评测聚类效果,可使用k-fold交叉验证。
  4. 迭代选择下一个T2。
  5. 直到找到最优的T1 T2。

五、Spectral

1、谱聚类算法简介

谱聚类算法,参考了文章《Mahout Spectral聚类》。

谱聚类算法是一种较为现代的图聚类算法。与K-Means等传统聚类相比,它具有以下特点:

  1. 可以对非欧式距离空间的点进行聚类。传统K-Means将点视为向量,并计算距离。而谱聚类算法要求直接给出两样本间相似度的矩阵。使得一些不便于在欧式空间计算的多特征聚类问题,有了更好的解法。(例如,性别,年龄2个特征,在欧式空间中就没有显著意义)。
  2. 上面的这一更宽泛的约束条件,使得谱聚类对样本空间的形状无限制,并能收敛于全局最优解(无需使用)。

一种典型的谱聚类算法的大致流程是:

  1. 构建样本集的相似度矩阵W。
  2. 对相似度矩阵W进行稀疏化,形成新的相似度矩阵A。
  3. 构建相似度矩阵A的拉普拉斯矩阵L。
  4. 计算拉普拉斯矩阵L的前k个特征值与特征向量,构建特征向量空间。
  5. 将前k个特征向量(列向量)组合成N*k的矩阵,每一行看成k维空间的一个向量,利用K-means或其它经典聚类算法对该矩阵进行聚类。

其中,转化为拉普拉斯矩阵实际是一个降维的过程。正是这一特点,使得谱聚类能够处理超大规模的数据。

2、Mahout中的谱聚类

上文已经提到:

  • 传统K-Means等聚类中,需要将每个样本转化为一个向量。
  • 谱聚类中,则需要直接给一个矩阵,其中存储了任意两个样本之间的相似度。

例如:

2013081119022654

在实际应用中,相似矩阵(affinity matrix)是相当稀疏的。所以,Mahout采用了邻接矩阵的输入格式,即(i, j, affinity)表示第i个样本与第j个样本的相似度是affinity。

同时,还需要输入矩阵的维度。原因应该是很好理解的。

如上图中的数据,转化完毕后,就是:

Mahout中,将谱聚类与KMeans进行了整合,执行命令:

参数说明:

  • -i :输入的相似度矩阵,邻接矩阵。
  • -k:目标聚成2个簇。
  • -o:聚簇中间结果。
  • -d:相似度矩阵维度为6,也即样本共6个。
  • -x:100,最多迭代100次。
  • -cd:收敛阈值,默认0.5

其他可选参数:

  • -ssvd:使用svd矩阵分解降维。
  • -q:svd相关。

输出的目录结构,与K-Means等相似:

说明一下:

  • sc-spectral/clusters-0:初始聚簇。
  • sc-spectral/kmeans_out/clusteredPoints:最终结果,样本->聚簇映射。
  • sc-spectral/kmeans_out/clusters-1-final:最终聚簇的信息。

先看一下聚簇映射:

如上所示,这个顺序,是按照输入样本顺序来的。Key 1表示属于第2个簇,0表示第1个簇。distance是点与簇的相似距离。

然后来看一下簇中心:

输出结果:

于 K-Means一样,VL-XX是簇名称,n代表簇中含有几个元素。c是簇中心,r是簇半径。

然而奇怪的是,我们可以发现,上面的n都是错的,而下面簇中点的打印是对的不知道是什么Bug…

六、LDA

LDA是一种主题模型,它是一种考虑了词贡献的,较为高级的“聚类”算法,主要功能为:

  1. 给定主题数k,输出文档属于每个主题的概率(越大表示越贴近该主题)。
  2. 输出每个主题中,权重最大的几个词。相当于传统聚类之后的Tag。

关于算法、原理方面,本文就不做过多的介绍了,感兴趣的可以查看相关论文。

考虑到LDA的特性,提取特征的时候,我们需要使用tf而非tfidf:

Mahout实现的LDA有个大坑:tf的vector,词必须是Ingeter类型,即要我们把word转换成wordid。

生成的有2个子目录,我们只用下面这个matrix:

LDA训练:

上述参数,说明一下:

  • -k 主题数20
  • -dt:输出的?
  • -o:输出的?
  • -x:迭代100次,其实对于LDA,1000~2000次是比较合理的。
  • -nt:词的数量,即dictionary.file-0的大小。

PS:Mahout这个LDA,执行效率真心不高,也可能是我的数据太小,机器太少。

文档->主题的概率

输出共21578行,代表了文档集合中的所有文档。

  • Key是文档id,与文件的对应关系可以在/user/coder4/reuters-cvb-vectoers/docIndex中查看。
  • Value是文档属于Topic 0~19的概率。按照值Sort一下,就能知道文档属于哪个主题的概率最大。

主题->词的概率

  • 一共有20行有效输出,Key 0~19,代表了20个主题。
  • 每个Value中有41806个词的权重。表示了词属于当前主题的权重。

本来有个LDAPrintTopics,可以直接打印Topic对应的词的,但是年久失修,已经不能用在新版的cvb的LDA上了。大家可以写程序对上免每个Topic中词的权重进行排序,从而获得每个主题的代表词。


http://chatgpt.dhexx.cn/article/pggyMmU8.shtml

相关文章

Mahout

1、Mahout是什么 Mahout是一个算法库,集成了很多算法。Apache Mahout 是 Apache Software Foundation&#xff08;ASF&#xff09;旗下的一个开源项目&#xff0c;提供一些可扩展的机器学习领域经典算法的实现&#xff0c;旨在帮助开发人员更加方便快捷地创建智能应用程序。Ma…

mahout 详解

前言 用Mahout来构建推荐系统&#xff0c;是一件既简单又困难的事情。简单是因为Mahout完整地封装了“协同过滤”算法&#xff0c;并实现了并行化&#xff0c;提供非常简单的API接口&#xff1b;困难是因为我们不了解算法细节&#xff0c;很难去根据业务的场景进行算法配置和调…

基于Mahout实现协同过滤推荐算法的电影推荐系统

1 Mahout介绍 Apache Mahout 是 Apache Software Foundation&#xff08;ASF&#xff09; 旗下的一个开源项目&#xff0c;提供一些可扩展的机器学习领域经典算法的实现&#xff0c;旨在帮助开发人员更加方便快捷地创建智能应用程序。经典算法包括聚类、分类、协同过滤、进化编…

Mahout简介

Mahout简介 一、mahout是什么 Apache Mahout是ApacheSoftware Foundation &#xff08;ASF&#xff09;旗下的一个开源项目&#xff0c;提供了一些经典的机器学习的算法&#xff0c;皆在帮助开发人员更加方便快捷地创建智能应用程序。目前已经有了三个公共发型版本&#xff0…

推荐系统 Mahout入门之简单使用

Mahout&#xff1a; Apache Mahout 是 Apache Software Foundation&#xff08;ASF&#xff09;旗下的一个开源项目&#xff0c;提供一些可扩展的机器学习领域经典算法的实现&#xff0c;旨在帮助开发人员更加方便快捷地创建智能应用程序。Mahout项目目前已经有了多个公共发行…

Mahout介绍和简单应用

Mahout学习&#xff08;主要学习内容是Mahout中推荐部分的ItemCF、UserCF、Hadoop集群部署运行&#xff09; 1.Mahout是什么&#xff1f; Mahout是一个算法库,集成了很多算法。 Apache Mahout 是 Apache Software Foundation&#xff08;ASF&#xff09;旗下的一个开源项目&…

脚手架开发流程

先把原理讲通&#xff0c;方便后续的开发。 后续都拿vue-cli举例 脚手架实现原理 为什么全局安装vue/cli后会添加的命令为vue&#xff1f;全局安装vue/cli时发生了什么&#xff1f;执行vue命令时发生了什么&#xff1f;为什么vue指向一个js文件&#xff0c;我们却可以直接通过…

ns2模拟仿真实验

内容&#xff1a; 编写TCL脚本&#xff0c;搭建如下图所示的一个网络&#xff0c;共6个节点&#xff0c;其中2、3节点用做ftp服务器和客户端&#xff0c;4、5节点用做cbr流量的源和目的&#xff0c;而0、1节点用做转发设备。各节点间的链路属性见图。 模拟时间设为13秒钟&#…

NS2网络仿真环境的搭建和使用

一实验概述: 1学会安装和使用NS2&#xff1b;熟悉NS2的文档结构&#xff1b;掌握NS2的仿真环境、使用界面和操作方法。 2学会安装NS2仿真环境和配置。 3了解NS2的工作原理和程序组成。 4熟悉NS2中的脚本语言Tcl和Otcl 5学习分裂对象模型和TclCL 6NS的时间调度机制学习。 …

NS2的NODE类——node

本文转自&#xff1a;http://hi.baidu.com/wirelesscat/blog/item/67c6db4633f71e016b63e59b.html 同时推荐一个很好的博客&#xff0c;这里有连载的 ns2 仿真问题&#xff0c;感谢大牛&#xff5e;&#xff5e;&#xff5e; 博客地址&#xff1a;http://hi.baidu.com/wirele…

NS2问题解决

问题一&#xff1a; When configured, ns found the right version of tclsh in /usr/bin/tclsh8.6 but it doesnt seem to be there anymore, so ns will fall back on running the first tclsh in your path. The wrong version of tclsh may break the test suites. Reconfi…

NS2简单介绍

NS是一种针对网络技术的源代码公开的、免费的软件模拟平台&#xff0c;研究人员使用它可以很容易的进行网络技术的开发&#xff0c;而且发展到今天&#xff0c;它所包含的模块已经非常丰富&#xff0c;几乎涉及到了网络技术的所有方面。所以&#xff0c;NS成了目前学术界广泛使…

NS2网络仿真

NS2安装与配置TCP/UDP比较仿真静态/动态路由仿真 1.安装与配置 1.1更新系统 sudo apt-get update #更新源列表 sudo apt-get upgrade #更新已经安装的包 sudo apt-get dist-upgrade #更新软件&#xff0c;升级系统 1.2安装ns2需要的几个包 sudo apt-get install build-ess…

ns2安装详细过程与网络仿真

ns2安装详细过程与网络仿真 博客分类&#xff1a; Networks TclLinuxUnixGCCVC 简单的说&#xff0c;NS&#xff0d;2是一个网络模拟器&#xff0c;所以经常被用到网络课的教学中。 NS-2是OpenSource的&#xff0c;最早的版本是在linux/unix下运行的&#xff0c;后来有了wi…

NS2教程

柯老师的NS2新网址 Due to some reasons, my NS2 website is sometimes donw and unavailable for many users. Therefore, I provide another backup website. 1. NS2 http://csie.nqu.edu.tw/smallko/ns2/ns2.htm 2. old_NS2 (backup of NS2 Learning Guide) http://csie.n…

ns2安装和若干问题的解决方法

文章目录 1. 安装与配置2. 安装nam3. 配置环境变量4. 检查是否能够成功运行参考资料 在安装ns2的过程中遇到了很多问题&#xff0c;为了记录这些问题和为同样遇到这些问题的朋友提供思路&#xff0c;写下这篇博文。 安装ns2和nam主要分为如下几个步骤&#xff1a; 安装与配置…

Linux下安装ns2

最近为了项目需要用到NS2软件用于网络仿真实验&#xff0c;从Windows到Linux折腾了我将近一周的时间。在Windows装了卸、卸了装十几遍还是不成功&#xff0c;最后放弃了&#xff0c;回到了Linux系统&#xff0c;又折腾了两天终于安装测试成功&#xff01;&#xff08;安装其实蛮…

企业微信第三方扫码登录

为什么写这个文章 公司后台突然需要扫码登录&#xff0c;网上的企业微信扫码都是基于自建应用的扫码登录&#xff0c;对第三方的扫码并没有多加介绍 概述 企业微信的管理员和成员&#xff0c;可通过单点登录机制&#xff0c;登录到第三方网站。第三方可通过接口&#xff0c;…

微信第三方登录有两种登录方式, 1. 微信开放平台登录 2. 微信公众平台授权登录?

https://www.v2ex.com/amp/t/390333 微信开放平台登录与微信公众平台授权登录区别在哪? 2017-09-13 12:05:41 08:00 xoxo419 微信第三方登录有两种登录方式, 1. 微信开放平台登录 2. 微信公众平台授权登录? 问: 两者区别在哪? 壹号店 http://m.yhd.com 微信第三方登录属…

Android APP微信第三方登录踩坑 - 微信开放平台修改应用包名后微信第三方登录失败

在微信开放平台注册移动应用&#xff0c;才能在APP里实现「微信登录」和「微信支付」。 近期因为业务需要&#xff0c;需要修改应用的包名&#xff0c;因此在微信开发平台重新提交了应用「基本信息」修改申请&#xff0c;顺便吐槽下&#xff0c;现在微信开发平台对应用审核真是…