当前位置: 首页 > 工具软件 > LensKit > 使用案例 >

LensKit<开源推荐系统框架Java>学习笔记

司徒茂实
2023-12-01

这段时间需要为网站添加推荐功能,一开始学习了一下推荐系统的一些经典算法,基于物品得,基于用户的等等,学习不是很深刻。利用学习LensKit的机会,把之前学习片段拾起来,记录一下。


1、下载开发包:http://lenskit.org/  如果无法下载点击:http://pan.baidu.com/s/1hr02PuO百度网盘

然后配置路径就可以开始我们的学习了,建议看一下推荐系统这个书

2、先来个例子

</pre>/*** * <p>Description: </p>* <p>Company: 燕山大学</p> * @author   于海强* @date       2015-12-8*/package lenskit.test1208;import it.unimi.dsi.fastutil.longs.LongSet;//import java.io.File;import java.sql.Connection;//import java.util.List;import org.grouplens.lenskit.data.sql.JDBCRatingDAO;import org.grouplens.lenskit.transform.normalize.BaselineSubtractingUserVectorNormalizer;//import org.grouplens.lenskit.transform.normalize.BaselineSubtractingUserVectorNormalizer;import org.grouplens.lenskit.transform.normalize.UserVectorNormalizer;import org.lenskit.LenskitConfiguration;import org.lenskit.LenskitRecommender;import org.lenskit.api.ItemScorer;import org.lenskit.api.RatingPredictor;import org.lenskit.api.Result;import org.lenskit.baseline.BaselineScorer;import org.lenskit.baseline.ItemMeanRatingItemScorer;import org.lenskit.knn.item.ItemItemScorer;import YHQ.SQL.DBAccess;/** * @author  作者 E-mail:  * @date 创建时间:2015-12-8 上午10:08:44  * @version 1.0  * @parameter   * @since   * @return   *//** *  * <p>Description: </p> * <p>Company: 燕山大学</p>  * @author   于海强 * @date       2015-12-8 */public class LensKitTest {<span style="white-space:pre">	</span>/**<span style="white-space:pre">	</span> *@description:<span style="white-space:pre">	</span> *@author: 于海强<span style="white-space:pre">	</span> *@date: 日期:2015-12-8 时间:上午10:08:44<span style="white-space:pre">	</span> *@param args<span style="white-space:pre">	</span> *@version 1.0<span style="white-space:pre">	</span> *@return <span style="white-space:pre">	</span> */<span style="white-space:pre">	</span>public static void main(String[] args) {<span style="white-space:pre">		</span>// TODO 自动生成的方法存根<span style="white-space:pre">		</span>LenskitConfiguration  config = new LenskitConfiguration();<span style="white-space:pre">		</span><span style="white-space:pre">		</span>config.bind(ItemScorer.class)<span style="white-space:pre">				</span>.to(ItemItemScorer.class);<span style="white-space:pre">		</span><span style="white-space:pre">		</span>/**<span style="white-space:pre">		</span> * 基于用户的推荐<span style="white-space:pre">		</span> */<span style="white-space:pre">		</span>{<span style="white-space:pre">		</span>/*config.bind(BaselineScorer.class,ItemScorer.class).to(UserMeanItemScorer.class);<span style="white-space:pre">		</span><span style="white-space:pre">		</span><span style="white-space:pre">		</span>config.bind(UserMeanBaseline.class,ItemScorer.class)<span style="white-space:pre">		</span>.to(ItemMeanRatingItemScorer.class);<span style="white-space:pre">		</span><span style="white-space:pre">			</span>config.bind(UserVectorNormalizer.class)<span style="white-space:pre">		</span>.to(BaselineSubtractingUserVectorNormalizer.class);<span style="white-space:pre">		</span><span style="white-space:pre">		</span>*/<span style="white-space:pre">		</span>}<span style="white-space:pre">		</span><span style="white-space:pre">		</span>/**<span style="white-space:pre">		</span> * 基于物品的<span style="white-space:pre">		</span> */<span style="white-space:pre">		</span>{<span style="white-space:pre">			</span>config.bind(BaselineScorer.class,ItemScorer.class).to(ItemMeanRatingItemScorer.class);<span style="white-space:pre">		</span><span style="white-space:pre">			</span>config.bind(UserVectorNormalizer.class).to(BaselineSubtractingUserVectorNormalizer.class);<span style="white-space:pre">		</span><span style="white-space:pre">		</span>}<span style="white-space:pre">		</span>//config.bind(NeighborhoodSize.class).to<span style="white-space:pre">	</span><span style="white-space:pre">		</span><span style="white-space:pre">		</span>/**<span style="white-space:pre">		</span> * 创建数据库连接,获取连接,数据库中一定要有ratings这个表<span style="white-space:pre">		</span> * ,表结构和数据上传到百度云了http://pan.baidu.com/s/1bogupor<span style="white-space:pre">		</span> */<span style="white-space:pre">		</span>DBAccess dbAccess = new DBAccess();<span style="white-space:pre">		</span>dbAccess.createConn();<span style="white-space:pre">		</span>Connection connection = dbAccess.getConn();<span style="white-space:pre">		</span><span style="white-space:pre">		</span>JDBCRatingDAO  dao = JDBCRatingDAO.newBuilder().build(connection);<span style="white-space:pre">		</span><span style="white-space:pre">		</span>LongSet lSet = dao.getItemIds();<span style="white-space:pre">		</span>//System.out.println(lSet.toString());<span style="white-space:pre">		</span>config.addComponent(dao);<span style="white-space:pre">		</span>    /* additional configuration */<span style="white-space:pre">		</span>    LenskitRecommender rec = LenskitRecommender.build(config);<span style="white-space:pre">		</span>    /* do things with the recommender */<span style="white-space:pre">		</span><span style="white-space:pre">		</span>//EventFormat ef= DelimitedColumnEventFormat.create(",".toString());<span style="white-space:pre">		</span><span style="white-space:pre">		</span>//config.bind(EventDAO.class).to(new TextEventDAO(new File("ratings.csv"), null));<span style="white-space:pre">		</span>//config.bind(EventDAO.class).to()<span style="white-space:pre">			</span><span style="white-space:pre">	</span><span style="white-space:pre">		</span>/**<span style="white-space:pre">		</span> * 输出结果<span style="white-space:pre">		</span> */<span style="white-space:pre">		</span>RatingPredictor pred = rec.getRatingPredictor();<span style="white-space:pre">		</span>for(int i=1;i<=4;i++)<span style="white-space:pre">		</span>{<span style="white-space:pre">			</span>for(int j=1;j<=5;j++)<span style="white-space:pre">			</span>{<span style="white-space:pre">				</span>Result result = pred.predict(i, j);<span style="white-space:pre">				</span>System.out.println(result.getScore()+"      ");<span style="white-space:pre">			</span>}<span style="white-space:pre">			</span>System.out.println();<span style="white-space:pre">		</span>}<span style="white-space:pre">		</span><span style="white-space:pre">	</span>}<span style="white-space:pre">	</span>/**<span style="white-space:pre">	</span> * <span style="white-space:pre">	</span> * <p>Description: </p><span style="white-space:pre">	</span> * <p>Company: 燕山大学</p> <span style="white-space:pre">	</span> * @author   于海强<span style="white-space:pre">	</span> * @date       2015-12-8<span style="white-space:pre">	</span> */}</div><div><span style="font-size:32px;">3.分析</span><span style="white-space:pre">		</span>这部分内容我主要是copy文档,简单翻译加上我的理解</div><div><span style="white-space:pre">	</span><span style="font-size:24px;">1.</span>首先初始化lenskit算法,通过bind.to 方法,可以看到这个方法中仅仅是指定了类,并没有实例化,原因在于lenskit采用了依赖注入,所有绑定(bind)的类都是实现了某一个接口,更改实现类即可更改算法</div><div><span style="white-space:pre">		</span>ItemSorer,<span style="background-color: rgb(240, 240, 240);">BaselineScorer,</span><span style="background-color: rgb(240, 240, 240);">UserVectorNormalizer这些类我也没搞清楚到底咋回事,可以去看看文档,先理解为配置相应的算法(感觉这段客户端代码还是很不错的,配置了相应的类即可配置算法,比自己写强多了!!!)</span></div><div><span style="white-space:pre"></span><pre name="code" class="html">LenskitConfiguration config = new LenskitConfiguration()
// Use item-item CF to score items
config.bind(ItemScorer.class)
      .to(ItemItemScorer.class);
// let's use personalized mean rating as the baseline/fallback predictor
// 2-step process:
// First, use the user mean rating as the baseline scorer
config.bind(BaselineScorer.class, ItemScorer.class)
      .to(UserMeanItemScorer.class);
// Second, use the item mean rating as the base for user means
config.bind(UserMeanBaseline.class, ItemScorer.class)
      .to(ItemMeanRatingItemScorer.class);
// and normalize ratings by baseline prior to computing similarities
config.bind(UserVectorNormalizer.class)
      .to(BaselineSubtractingUserVectorNormalizer.class);
2.配置数据源。文档中给的例子是连接csv文件,我写的时候没有找到 SimpleFileRatingDAO 这个类。也没有找到csv文件,我连接的是数据库,代码如下
DBAccess dbAccess = new DBAccess();
		dbAccess.createConn();
		Connection connection = dbAccess.getConn();
		
		JDBCRatingDAO  dao = JDBCRatingDAO.newBuilder().build(connection);
可以看到此刻并没有指定表名称,通过查看控制台输出看到默认到ratings中去找。

user,Item分别为用户和物品的ID,rating为分数。
http://pan.baidu.com/s/1bogupor表结构和测试数据都在这,我用的是navicat for mysql.其他数据库可能

4.创建推荐
LenskitRecommender rec = LenskitRecommender.create(config);

5.生成推荐结果
ItemRecommender irec = rec.getItemRecommender();
List<ScoredId> recommendations = irec.recommend(42, 10);

如果没有配置ItemRecommender它默认采用返回某个用户例如42,的前n(10)个物品。
也可以使用
RatingPredictor pred = rec.getRatingPredictor();
double score = pred.predict(42, 17);

6.总结
  使用这个框架还是很方便的,至于推荐效果我不太清楚,也没有过测试经验,现在需要深入一下推荐算法了,后续会与极其基础推荐算法的一些学习笔记
 类似资料: