Mahout主要有协同过滤、聚类和分类三种算法的实现。现在我们就用Mahout来实现经典的Kmeans聚类算法。
首先,下载Hadoop和Mahout。因为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 格式化hadoop的namenode,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-vectors、tfidf-vectors (均为目录):词向量,每篇文档一行,格式为{ 词id:特征值},其中特征值为tf或tfidf。有用采用了内置类型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个中心点的信息。
而