mahout下的Hadoop平台上的Kmeans算法实现

Mahout主要有协同过滤、聚类和分类三种算法的实现。现在我们就用Mahout来实现经典的Kmeans聚类算法。

首先,下载HadoopMahout。因为Mahout有很多实现是运行在Hadoop上的,所以要先安装Hadoop

具体怎么安装?简单地说一下:

1. 先安装SSH

ufw disable 关闭防火墙

 

cd .ssh/   进入ssh文件夹,没有的话,下面生产密钥的时候自动生成

ssh-keygen -t rsa 生成ssh密钥

cp id_rsa.pub authorized_keys 复制多一份

ssh localhost 测试是否联通

sudo apt-get install openssh-server 安装ssh服务

net start sshd 启动ssh服务

 

2. 解压Hadoop

 

tar -zxvf hadoop-1.1.2.tar.gz 解压tar.gz

 

3. 添加环境变量

export JAVA_HOME=/usr/local/jdk7 增加环境变量

export PATH=.:$JAVA_HOME/bin:$PATH 增加环境变量

4. 单机运行的话至少修改四个配置文件

5. 其他命令

 

hadoop namenode -format 格式化hadoopnamenode,datanode不需要格式化

start-all.sh 启动所有的hadoop服务

stop-all.sh 关闭所有的hadoop服务

start-dfs.sh 单独启动hdfs

stop-dfs.sh

start-mapred.sh 启动MapReduce的两个服务

hadoop-daemon.sh start[进程名称] 单独启动进程

 

jps 查看正在运行的各种进程

 

ps -e | grep ssh  查看防火墙服务是否开启

ifconfig -a |grep inet 查看网络连接地址

6. Mahout的安装也类似

 

先解压,再配置环境变量,最后输入mahout命令,有各种算法列出来就是安装成功了!

http://kdd.ics.uci.edu/databases/reuters21578/reuters21578.tar.gz

下载 Reuters21578 文本语料。也可以自己准备数据集。我用我自己的数据集来做实现。

我收集了1000首歌曲的信息,如下:


把这些信息存入mongodb数据库中,以后还要使用,当然不存也可以。然后用java代码取出来,每首歌曲生成一个txt文件。并且做了处理,标签值赋予不同的权重,歌词进行了分词处理。

Map<String,Object> outmap = new HashMap<String, Object>();
        outmap.put("flag",false);
        List<Song> list = songRepository.findAll();
        int size = list.size() ;
        String[] strs = new String[size];
        if (list != null){
            //循环每一首歌曲
            for (int i = 0; i < size; i++) {
                Song song = list.get(i);
                //有权值的标签
                StringBuilder sb = new StringBuilder();
                for (int j = 0; j < 8; j++) {
                    sb.append(song.getArtist()).append(" ");
                }
                for (int j = 0; j < 2; j++) {
                    sb.append(song.getAlbum()).append(" ");
                }
                for (int j = 0; j < 5; j++) {
                    sb.append(song.getType()).append(" ");
                }
                for (int j = 0; j < 3; j++) {
                    sb.append(song.getDistrict()).append(" ");
                }
                for (int j = 0; j < 6; j++) {
                    sb.append(song.getYears()).append(" ");
                }
                for (int j = 0; j < 3; j++) {
                    sb.append(song.getRhythm()).append(" ");
                }
                for (int j = 0; j < 4; j++) {
                    sb.append(song.getMood()).append(" ");
                }
                //无权值的歌词
                String strLrc = song.getLrc() ;
                //对歌词进行分词
                strLrc = SplitWord.splitWordBySpace(strLrc);
                sb.append(strLrc);
                strs[i] = sb.toString() ;
            }
            //写出文件
            WriteLines.writeStrBecomeTxts("C:\\Users\\xin\\Desktop\\大论文\\Scala","utf-8",strs);
            outmap.put("flag",true);
            return outmap ;
        } else {
            return outmap ;
        }

生成的文件如下:


把这些文件压缩成一个文件,也就是Hadoop可以解析的SequenceFile格式的文件

Mahout seqdirectory -i file:/usr/song-input -o file:/usr/song-output -c UTF-8 -chunk 64 -xm sequential

file:前缀是指在本地文件系统上寻找,而不是HDFS-xm sequential 就是本地执行的意思。

-chunk 64 压缩成64M一个文件,HDFS文件系统的单位就是64M

 

接着就是把SequenceFile格式的文件转换为向量Vector。把上一步生成的文件放到HDFS文件系统上。运行命令:

hadoop fs -mkdir input
hadoop fs -put /usr/song-output/chunk-0 input
Mahout seq2sparse -i input -o output -ow --weight tfidf --maxDFPercent  95 --nameVector -a org.apache.lucene.analysis.WhitespaceAnalyzer

-i 输入目录

-o 输出目录

--weight 权重公式

--maxDFPercent 过滤高词频 >95%

-a 指定分词器 因为我们前面已经用IK分过词了,这里直接按空格分词就可以了

各个参数如下图:

生成目录:

root@xin:~# hadoop fs -ls output
Warning: $HADOOP_HOME is deprecated.

Found 7 items
drwxr-xr-x   - root supergroup          0 2015-03-30 14:11 /user/root/output/df-count
-rw-r--r--   1 root supergroup      48768 2015-03-30 14:10 /user/root/output/dictionary.file-0
-rw-r--r--   1 root supergroup      51433 2015-03-30 14:11 /user/root/output/frequency.file-0
drwxr-xr-x   - root supergroup          0 2015-03-30 14:11 /user/root/output/tf-vectors
drwxr-xr-x   - root supergroup          0 2015-03-30 14:12 /user/root/output/tfidf-vectors
drwxr-xr-x   - root supergroup          0 2015-03-30 14:09 /user/root/output/tokenized-documents
drwxr-xr-x   - root supergroup          0 2015-03-30 14:10 /user/root/output/wordcount

· dictionary.file-0:词文本 -> id(int)的映射。词转化为id,这是常见做法。

· frequency.file:词id -> 文档集词频(cf)

· wordcount(目录): 词文本 -> 文档集词频(cf),这个应该是各种过滤处理之前的信息。

· df-count(目录): 词id -> 文档频率(df)

· tf-vectorstfidf-vectors (均为目录):词向量,每篇文档一行,格式为{ id:特征值},其中特征值为tftfidf。有用采用了内置类型VectorWritable,需要 用命令”mahout vectordump -i <path>”查看。

· tokenized-documents:分词后的文档。

现在来运行Kmeans算法了!

Mahout kmeans -i output/tfidf-vectors -c output/kmeans-clusters -o output/kmeas -k 10
-x 200 -ow --clustering

参数说明如下:

 

    -i:输入为上面产出的tfidf向量。

    -o:每一轮迭代的结果将输出在这里。

    -k:几个簇。

    -c:这是一个神奇的变量。若不设定k,则用这个目录里面的点,作为聚类中心点。否则,随机选择k个点,作为中心点。

    -dm:距离公式,文本类型推荐用cosine距离。

    -x :最大迭代次数。

    –clustering:在mapreduce模式运行。

    –convergenceDelta:迭代收敛阈值,默认0.5,对于Cosine来说略大。

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

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值