使用Mahout搭建推荐系统之入门篇1-搭建REST风格简单推荐系统

转载 2013年12月04日 15:32:41

用意: 网络上有很多关于使用mahout搭建推荐系统的文章,但是还没有一个从建立推荐系统原型至部署到简单服务器的完整教程. 虽然部分朋友对推荐系统很感兴趣, 但是因hadoop的复杂而却步.  同时对于那些没有任何Web开发经验的朋友来说, 一个完整的小型推荐系统可以很大的激发学习的兴趣和动手的冲动. 我觉得动手的冲动比看书的冲动要重要的多.

     原型分为两个系列 : JAVA原型和Python原型.

这篇博客主要是介绍JAVA推荐系统原型: 主要参考[1]

使用MyEclipse和Mahout开发一个REST风格[3]的简单推荐系统

一. 搭建一个Hello world的REST服务器
1. 选择建立MyEclise Web Service Project
    填写Project Name, 填写完毕后,注意Context root URL的内容.两者是一致的.当然你也可以让两者不一样,自己选择一个名字.如Project Name为testHello.而URL为/rs.(URL十分重要,是最终WEB访问路径的一部分)

     Library见下图 core server client json.


2. 打开/WEB-INF下的web-xml可以看到

<servlet-mapping>
<servlet-name>JAX-RS REST Servlet</servlet-name>
<url-pattern>/test/*</url-pattern>
</servlet-mapping>

其中的url-pattern将是WEB路径的一部分,具体见下文.

2. 在/src目录下加入HelloRS文件. 内容如下


[java] view plaincopy
  1. import javax.ws.rs.GET;  
  2. import javax.ws.rs.Path;  
  3. import javax.ws.rs.Produces;  
  4. import javax.ws.rs.core.MediaType;  
  5.   
  6.   
  7. //设置路径为http://域名:端口/ConTextRootURL/url-pattern + /hello  
  8. //以我的机子为例:http://localhost:8080/rs/rest/hello  
  9.   
  10. @Path("/recommend")  
  11. public class HelloRS {  
  12.   
  13.   // 这个方法将返回普通文本  
  14.   @GET  
  15.   @Produces(MediaType.TEXT_PLAIN)  
  16.   public String sayPlainTextHello() {  
  17.     return "Hello REST";  
  18.   }  
  19.   
  20.   // 这个方法将返回XML文件  
  21.   @GET  
  22.   @Produces(MediaType.TEXT_XML)  
  23.   public String sayXMLHello() {  
  24.     return "<?xml version=\"1.0\"?>" + "<hello> Hello REST" + "</hello>";  
  25.   }  
  26.   
  27.   // 这个方法将返回HTML文件  
  28.   @GET  
  29.   @Produces(MediaType.TEXT_HTML)  
  30.   public String sayHtmlHello() {  
  31.     return "<html> " + "<title>" + "Hello REST" + "</title>"  
  32.         + "<body><h1>" + "Hello REST" + "</body></h1>" + "</html> ";  
  33.   }  
  34.   
  35. }  


3. 选择Project,使用Run as->MyEclipse Server Application即可.
使用 http://localhost:8080/rs/rest/hello 既可以看到返回Hello REST了.

修改文件后Tomcat将会自动检测并布置.
注:有任何问题,看console中的日志输出,找到Exception或者error, Google一下.

二. 利用mahout搭建简单的推荐系统,数据使用代码生成

1. 在Java Build Path引入mahout相关库文件, 下载地址: http://pan.baidu.com/s/1Ea8pI
mahout核心类: 提供推荐Model等核心类
    mahout-core-0.5.jar
    mahout-math-0.5.jar
辅助类: 提供Log和部分数学公式类.
    uncommons-maths-1.2.jar
    google-collections-1.0-rc2.jar
    guava-r0.3.jar
    slf4j-api-1.6.0.jar

2. 在src下新建一个RecommenderIntro.java文件,代码如下:

[java] view plaincopy
  1. <strong>import org.apache.mahout.cf.taste.impl.model.file.*;  
  2. import org.apache.mahout.cf.taste.impl.neighborhood.*;  
  3. import org.apache.mahout.cf.taste.impl.recommender.*;  
  4. import org.apache.mahout.cf.taste.impl.similarity.*;  
  5. import org.apache.mahout.cf.taste.model.*;  
  6. import org.apache.mahout.cf.taste.neighborhood.*;  
  7. import org.apache.mahout.cf.taste.recommender.*;  
  8. import org.apache.mahout.cf.taste.similarity.*;  
  9. import java.io.*;  
  10. import java.util.*;  
  11.   
  12. class RecommenderIntro {  
  13.   
  14.      private FileDataModel model;  
  15.      private PearsonCorrelationSimilarity similarity;  
  16.      private NearestNUserNeighborhood neighborhood;  
  17.      private GenericUserBasedRecommender recommender;  
  18.   
  19.   
  20.   
  21.     // 从filename中读取数据(用户id, 物品id, 评分rate), 生成数据类model, 相似类similarity以及最相近的邻居类(2个)  
  22.   
  23.      public RecommenderIntro(String filename) throws Exception {  
  24.           model = new FileDataModel(new File(filename));  
  25.   
  26.           similarity = new PearsonCorrelationSimilarity(model);  
  27.           neighborhood =  
  28.                new NearestNUserNeighborhood(2, similarity, model);  
  29.   
  30.           recommender = new GenericUserBasedRecommender(  
  31.                     model, neighborhood, similarity);  
  32. }  
  33.   
  34.   
  35.   
  36. // 对用户userid推荐前num个物品.  
  37.   
  38. public List<RecommendedItem> SimpleRecommend(int userid, int num) throws Exception {  
  39.   
  40.      List<RecommendedItem> recommendations =  
  41.      recommender.recommend(11);  
  42.   
  43.      return recommendations;  
  44.   
  45. }  
  46.   
  47. }</strong>  

代码介绍: 

    本算法是最简单的基于用户的协同过滤. 现实解释:你想别人给你推荐一个电影,你会从一堆人中找到与你最熟悉的几个人推荐电影给你,然后找到被推荐次数最多的电影. Model类用来存储数据, mahout为了节约内存, 数据结构设计的很好,下次找个机会聊聊. Similarity计算两个人之间的相似性, 而Neighborhood则是为每个人保存最相似的2个人.最后recommener结合model\neighborhood和similarity来为某个user推荐N个好友. 

3. 修改helloRS文件修改如下所示:

    将intro.csv文件放到src/目录下

[java] view plaincopy
  1. <strong>import java.util.List;  
  2.   
  3. import javax.ws.rs.DefaultValue;  
  4. import javax.ws.rs.GET;  
  5. import javax.ws.rs.Path;  
  6. import javax.ws.rs.Produces;  
  7. import javax.ws.rs.QueryParam;  
  8. import javax.ws.rs.core.MediaType;  
  9.   
  10. import org.apache.mahout.cf.taste.recommender.RecommendedItem;  
  11.   
  12. //Sets the path to base URL + /hello  
  13. @Path("/recommend")  
  14. public class HelloRS {  
  15.   
  16.     private RecommenderIntro recommender = null;  
  17.     private String filename = null;  
  18.   
  19.     // This method is called if TEXT_PLAIN is request  
  20.     @GET  
  21.     @Produces(MediaType.TEXT_PLAIN)  
  22.     public String sayPlainTextHello(  
  23.             @DefaultValue("1"@QueryParam("id") String id,  
  24.             @DefaultValue("1"@QueryParam("num") String num) throws Exception {  
  25.   
  26.         int userId = Integer.valueOf(id);  
  27.         int rankNum = Integer.valueOf(num);  
  28.         String resultStr = getRecommender(userId, rankNum);  
  29.   
  30.         return resultStr;  
  31.     }  
  32.   
  33.     // This method is called if XML is request  
  34.     @GET  
  35.     @Produces(MediaType.TEXT_XML)  
  36.     public String sayXMLHello(@DefaultValue("1"@QueryParam("id") String id,  
  37.             @DefaultValue("1"@QueryParam("num") String num) throws Exception {  
  38.         int userId = Integer.valueOf(id);  
  39.         int rankNum = Integer.valueOf(num);  
  40.         String resultStr = getRecommender(userId, rankNum);  
  41.   
  42.         return "<?xml version=\"1.0\"?>" + "<hello> " + resultStr + "</hello>";  
  43.     }  
  44.   
  45.     // This method is called if HTML is request  
  46.     @GET  
  47.     @Produces(MediaType.TEXT_HTML)  
  48.     public String sayHtmlHello(@DefaultValue("1"@QueryParam("id") String id,  
  49.             @DefaultValue("1"@QueryParam("num") String num) throws Exception {  
  50.   
  51.         System.out.println(id + " " + num);  
  52.         int userId = Integer.valueOf(id);  
  53.         int rankNum = Integer.valueOf(num);  
  54.         String resultStr = getRecommender(userId, rankNum);  
  55.   
  56.         return "<html> " + "<title>" + "Hello REST" + "</title>" + "<body><h1>"  
  57.                 + resultStr + "</body></h1>" + "</html> ";  
  58.     }  
  59.   
  60.     private String getRecommender(int userId, int num) throws Exception {  
  61.   
  62.         if (filename == null) {  
  63.             String classPath = this.getClass().getClassLoader()  
  64.                     .getResource("/").getPath();  
  65.               
  66.             classPath = classPath.replace("%20""\\ ");  
  67.             filename = classPath + "intro.csv";  
  68.             System.out.println(filename);  
  69.         }  
  70.   
  71.         if (recommender == null)  
  72.             recommender = new RecommenderIntro(filename);  
  73.   
  74.         List<RecommendedItem> recommendedList = recommender.SimpleRecommend(  
  75.                 userId, num);  
  76.         String resultStr = "Result=" + recommendedList.get(0).getItemID() + " "  
  77.                 + recommendedList.get(0).getValue();  
  78.   
  79.         return resultStr;  
  80.     }  
  81.   
  82. }</strong>  

代码介绍: 代码提供了XML\HTML和普通文本三个格式, 以浏览器默认的HTML格式为例. 

如果浏览器 输入 http://localhost:8080/rs/rest/recommend?id=1&num=1 

参数表@DefaultValue("1") @QueryParam("id") String id, @DefaultValue("1") @QueryParam("num") String num表示获得参数

id = "1", num = "1". 之后通过getRecommender来初始化Recommender并获得数据. QueryParam表示GET方法的数据.

注: 由于intro.csv数据集比较少,所有部分id和num值无法返回合适的结果.

注: 由与intro.csv最终会部署在tomcat上,所以需要获得tomcat中class的路径.

注: recommender作为成员函数,保证每一个函数都引用同一份数据,保证一致性.

获取路径的方法如下:

[java] view plaincopy
  1. <strong>String classPath = this.getClass().getClassLoader()  
  2.                     .getResource("/").getPath();<span style="line-height:1.428571em; font-family:'sans serif',tahoma,verdana,helvetica; font-size:10pt; font-weight:normal"></span></strong>  

4. 运行代码,即可使用http://localhost:8080/rs/rest/recommend?id=1&num=1 即可在浏览器中访问.

返回:

Result=104 4.257081


一些问题: 
注意: 碰到tomcat端口设置问题: 8080 被占用.原因是已启动了tomcat了.使用/etc/init.d/tomcat6 stop让程序停止即可.
注意: Myeclipse安装路径中不要出现空格,否则会出现问题.

参考资料: 
[1] Sean Owen "Mahout in Action"  http://book.douban.com/subject/4893547/

[2] Lars Vogel  REST with Java (JAX-RS) using Jersey - Tutorial http://www.vogella.com/articles/REST/article.html[3] REST 参考豆瓣API http://developers.douban.com/wiki/?title=movie_v2#reviews


转自:http://blog.csdn.net/qingfengmanbu/article/details/14101443#comments

相关文章推荐

Slope one—个性化推荐中最简洁的协同过滤算法

Slope One 是一系列应用于 协同过滤的算法的统称。由 Daniel Lemire和Anna Maclachlan于2005年发表的论文中提出。 [1]有争议的是,该算法堪称基于项目评价的non...

推荐算法之 slope one 算法

1.示例引入多个吃货在某美团的某家饭馆点餐,如下两道菜:可乐鸡翅: 红烧肉: 顾客吃过后,会有相关的星级评分。假设评分如下: 评分 可乐鸡翅 红烧肉 小明 4 ...

使用Mahout搭建推荐系统之入门篇1-搭建REST风格简单推荐系统

原始链接:http://my.oschina.net/Cfreedom/blog?catalog=408809      用意: 网络上有很多关于使用mahout搭建推荐系统的文章,...

使用Mahout搭建推荐系统之入门篇2-玩转你的数据1

用意: 搞推荐系统或者数据挖掘的, 对数据要绝对的敏感和熟悉, 并且热爱你的数据. 分析数据既要用统计分析那一套,又要熟悉业务发掘有趣的特征(feature). 后者有意思的多,但是因为我业务做的不多...

使用Mahout搭建推荐系统之入门篇-Mahout源码初探

用意: 希望了解Mahout中数据的存储方式, 它如何避免java object带来的冗余开销。学完知识,要进行些实战 去分析数据。 花了些时间看了看Mahout的源码和官方资料,记录下自己的...

使用Mahout搭建推荐系统之入门篇4-Mahout实战

原始地址:http://my.oschina.net/Cfreedom/blog/201828 目录[-] 一、基本内容 二、运行环境 三、程序运行 3.1 调整...

使用Mahout搭建推荐系统之入门篇3-Mahout源码初探

用意: 希望了解Mahout中数据的存储方式, 它如何避免java object带来的冗余开销。学完知识,要进行些实战 去分析数据。 花了些时间看了看Mahout的源码和官方资料,记录下自己的一些...

使用Mahout搭建推荐系统之入门篇4-Mahout实战

用意: 结合上篇博客,写写代码熟悉一下Mahout。很多地方想法都比较粗糙,亟待指正。 代码放在了:https://github.com/xiaoqiangkx/qingRS 一、基本内容    ...

第一篇:win7下mahout搭建简单推荐系统

之前查了很多

mahout入门之推荐系统

Apache Mahout 是 Apache Software Foundation (ASF) 开发的一个全新的开源项目,其主要目标是创建一些可伸缩的机器学习算法,供开发人员在 Apache 在许可...
  • RFC2008
  • RFC2008
  • 2012年04月01日 15:22
  • 1580
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:使用Mahout搭建推荐系统之入门篇1-搭建REST风格简单推荐系统
举报原因:
原因补充:

(最多只允许输入30个字)