博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Mahout搭建推荐系统之入门篇1-搭建REST风格简单推荐系统
阅读量:6568 次
发布时间:2019-06-24

本文共 6519 字,大约阅读时间需要 21 分钟。

hot3.png

     用意: 网络上有很多关于使用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文件. 内容如下

import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.Produces;import javax.ws.rs.core.MediaType;//设置路径为http://域名:端口/ConTextRootURL/url-pattern + /hello//以我的机子为例:http://localhost:8080/rs/rest/hello@Path("/recommend")public class HelloRS {  // 这个方法将返回普通文本  @GET  @Produces(MediaType.TEXT_PLAIN)  public String sayPlainTextHello() {    return "Hello REST";  }  // 这个方法将返回XML文件  @GET  @Produces(MediaType.TEXT_XML)  public String sayXMLHello() {    return "
" + "
Hello REST" + "
"; } // 这个方法将返回HTML文件 @GET @Produces(MediaType.TEXT_HTML) public String sayHtmlHello() { return " " + "" + "Hello REST" + "" + "

" + "Hello REST" + "

" + " "; }}

3. 选择Project,使用Run as->MyEclipse Server Application即可.
使用
 既可以看到返回Hello REST了.
修改文件后Tomcat将会自动检测并布置.
注:有任何问题,看console中的日志输出,找到Exception或者error, Google一下.
二. 利用mahout搭建简单的推荐系统,数据使用代码生成
1. 在Java Build Path引入mahout相关库文件, 下载地址:
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文件,代码如下:

import org.apache.mahout.cf.taste.impl.model.file.*;import org.apache.mahout.cf.taste.impl.neighborhood.*;import org.apache.mahout.cf.taste.impl.recommender.*;import org.apache.mahout.cf.taste.impl.similarity.*;import org.apache.mahout.cf.taste.model.*;import org.apache.mahout.cf.taste.neighborhood.*;import org.apache.mahout.cf.taste.recommender.*;import org.apache.mahout.cf.taste.similarity.*;import java.io.*;import java.util.*;class RecommenderIntro {     private FileDataModel model;     private PearsonCorrelationSimilarity similarity;     private NearestNUserNeighborhood neighborhood;     private GenericUserBasedRecommender recommender;    // 从filename中读取数据(用户id, 物品id, 评分rate), 生成数据类model, 相似类similarity以及最相近的邻居类(2个)     public RecommenderIntro(String filename) throws Exception {          model = new FileDataModel(new File(filename));          similarity = new PearsonCorrelationSimilarity(model);          neighborhood =               new NearestNUserNeighborhood(2, similarity, model);          recommender = new GenericUserBasedRecommender(                    model, neighborhood, similarity);}// 对用户userid推荐前num个物品.public List
SimpleRecommend(int userid, int num) throws Exception { List
recommendations = recommender.recommend(1, 1); return recommendations;}}

代码介绍: 

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

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

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

import java.util.List;import javax.ws.rs.DefaultValue;import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.Produces;import javax.ws.rs.QueryParam;import javax.ws.rs.core.MediaType;import org.apache.mahout.cf.taste.recommender.RecommendedItem;//Sets the path to base URL + /hello@Path("/recommend")public class HelloRS {	private RecommenderIntro recommender = null;	private String filename = null;	// This method is called if TEXT_PLAIN is request	@GET	@Produces(MediaType.TEXT_PLAIN)	public String sayPlainTextHello(			@DefaultValue("1") @QueryParam("id") String id,			@DefaultValue("1") @QueryParam("num") String num) throws Exception {		int userId = Integer.valueOf(id);		int rankNum = Integer.valueOf(num);		String resultStr = getRecommender(userId, rankNum);		return resultStr;	}	// This method is called if XML is request	@GET	@Produces(MediaType.TEXT_XML)	public String sayXMLHello(@DefaultValue("1") @QueryParam("id") String id,			@DefaultValue("1") @QueryParam("num") String num) throws Exception {		int userId = Integer.valueOf(id);		int rankNum = Integer.valueOf(num);		String resultStr = getRecommender(userId, rankNum);		return "
" + "
" + resultStr + "
"; } // This method is called if HTML is request @GET @Produces(MediaType.TEXT_HTML) public String sayHtmlHello(@DefaultValue("1") @QueryParam("id") String id, @DefaultValue("1") @QueryParam("num") String num) throws Exception { System.out.println(id + " " + num); int userId = Integer.valueOf(id); int rankNum = Integer.valueOf(num); String resultStr = getRecommender(userId, rankNum); return " " + "" + "Hello REST" + "" + "

" + resultStr + "

" + " "; } private String getRecommender(int userId, int num) throws Exception { if (filename == null) { String classPath = this.getClass().getClassLoader() .getResource("/").getPath(); classPath = classPath.replace("%20", "\\ "); filename = classPath + "intro.csv"; System.out.println(filename); } if (recommender == null) recommender = new RecommenderIntro(filename); List
recommendedList = recommender.SimpleRecommend( userId, num); String resultStr = "Result=" + recommendedList.get(0).getItemID() + " " + recommendedList.get(0).getValue(); return resultStr; }}

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

如果浏览器 输入  

参数表@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作为成员函数,保证每一个函数都引用同一份数据,保证一致性.

获取路径的方法如下:

String classPath = this.getClass().getClassLoader()					.getResource("/").getPath();

4. 运行代码,即可使用 即可在浏览器中访问.

返回:

Result=104 4.257081

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

[2] Lars Vogel  REST with Java (JAX-RS) using Jersey - Tutorial [3] REST 参考豆瓣API 

转载于:https://my.oschina.net/Cfreedom/blog/173539

你可能感兴趣的文章
Viewport
查看>>
〖Android〗(how-to) fix k860/k860i buletooth.
查看>>
static与线程安全 -摘自网络
查看>>
jsf标签,jsp标签与jstl标签
查看>>
使用PHP CURL的POST数据
查看>>
struts2:表单标签
查看>>
ASP.NET MVC3 通过Url传多个参数方法
查看>>
遭遇sql server 2005 启动包未能正确加载需要重新安装错误,重装.NET FRAMEWORK经历分析...
查看>>
简明 MongoDB 入门教程
查看>>
.NET Core 3.0中的数据库驱动框架System.Data
查看>>
北大AI公开课2019 | 雷鸣:人工智能革命与机遇
查看>>
英特尔开源计算机视觉数据标签工具CVAT,加速数据注释
查看>>
consule服务注册和发现 安装 部署
查看>>
多个帐户都用root 来登录 怎么看另一个用户使用的那些命令
查看>>
Map集合案例
查看>>
《FPGA全程进阶---实战演练》第十一章 VGA五彩缤纷
查看>>
第七次课程作业
查看>>
C++ 文本查询2.0(逻辑查询)
查看>>
Objective-C学习总结-13协议1
查看>>
web学习方向
查看>>