更新:相關代碼放gitee了,sql與測試類在如下位置https://gitee.com/hwp_ing/mahout.git
參考文章
1.spring boot項目基于mahout推薦算法實現(xiàn)商品推薦
2.相關內容在章節(jié)5-9
前言
這邊只是跑了個文章推薦的demo,不過什么電影,商品啥的都一樣,沒啥區(qū)別就是把表當中的文章id改成商品id,操作類型自己修改一下
mahout基礎知識掃盲,大概看一下就行,簡單的推薦算法直接套下面核心代碼的模板,改改參數(shù)就行。
推薦系統(tǒng) Mahout入門之簡單使用
推薦系統(tǒng)之推薦算法實戰(zhàn):mahout推薦算法框架
溫馨提醒
這個mahout包有毒。。。。很多依賴沖突。。。。
這是我的pom文件,僅僅供參考。。
<dependencies>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>3.5.3</version>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.21</version>
</dependency>
<!--引入推薦引擎mahout,注意要先全部引入,再使用exclusion標簽-->
<dependency>
<groupId>org.apache.mahout</groupId>
<artifactId>mahout-mr</artifactId>
<version>0.12.2</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jcl</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-core</artifactId>
</exclusion>
<exclusion>
<groupId>org.apache.lucene</groupId>
<artifactId>lucene-analyzers-common</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<artifactId>jersey-client</artifactId>
<groupId>com.sun.jersey</groupId>
</exclusion>
<exclusion>
<artifactId>jersey-core</artifactId>
<groupId>com.sun.jersey</groupId>
</exclusion>
<exclusion>
<artifactId>jersey-apache-client4</artifactId>
<groupId>com.sun.jersey.contribs</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
1.建表并且生成一些數(shù)據(jù)
首先,建立一個用戶文章操作表(user_article_operation)
然后生成一些數(shù)據(jù),這里使用navicat生成了50條記錄(因為只是測試一下算法的準確性因此只生成了3個用戶,10篇文章)
使用case when語句簡單統(tǒng)計數(shù)據(jù)
使用case when 簡單統(tǒng)計一下數(shù)據(jù),推測一下用戶相關度
不同操作對應不同分數(shù)0點贊(3分)1收藏(3分)2評論(5)分,分組求和
SELECT
user_id,
article_id,
SUM(
CASE operation_type
WHEN 0 THEN 3
WHEN 1 THEN 3
WHEN 2 THEN 5
else 0 END
) AS "value"
FROM
user_article_operation
GROUP BY user_id,article_id
ORDER BY user_id
執(zhí)行語句如下
可以看出
1號用戶最喜歡6,9號文章,
2號用戶最喜歡4,5,6號文章
3號用戶最喜歡4,5,6號文章
發(fā)現(xiàn)1,2,3號用戶都喜歡6號文章,3個用戶具有一定相似性。
(別問為啥這么規(guī)律,問就是我為了好測試修改了下數(shù)據(jù),如果你感覺哪里不對勁的話,那你說的都對)(反正應付一下老師夠了,這里只是提供一個小demo,讀者需注意哈????????)
因此如果要給1號用戶推薦文章的話,應該先推薦5號,再推薦4號文章。
2. 代碼與測試
只需要根據(jù)表生成相應實體類(注意要加一個value屬性來存儲分數(shù))
主要代碼如下,其實就兩個方法
userArticleOperationMapper.getAllUserPreference()方法收集數(shù)據(jù)mapper文件如下
測試算法
輸入推薦5個,但是這里只推薦了四個,應該是樣本數(shù)據(jù)量太小的原因,對比了一下之前運行case then語句時做的的簡單預測,5號最推薦,然后是4號,控制臺打印的結果還是比較符合的。
(反正應付一下老師夠了,這里只是提供一個小demo,讀者需注意哈????????)文章來源:http://www.zghlxwxcb.cn/news/detail-427027.html
3.核心代碼(基于用戶分析)
讀者自己建個表,然后簡單寫個對應實體類,然后添加下面的核心代碼就行。如下面的UserArticleOperation就是我建立的實體類,基本改幾個參數(shù)就行,套模板的。文章來源地址http://www.zghlxwxcb.cn/news/detail-427027.html
public List<Long> recommend( Integer userId) throws TasteException {
List<UserArticleOperation> userList = userArticleOperationMapper.getAllUserPreference();
//創(chuàng)建數(shù)據(jù)模型
DataModel dataModel = this.createDataModel(userList);
//獲取用戶相似程度
UserSimilarity similarity = new UncenteredCosineSimilarity(dataModel);
//獲取用戶鄰居
UserNeighborhood userNeighborhood = new NearestNUserNeighborhood(2, similarity, dataModel);
//構建推薦器
Recommender recommender = new GenericUserBasedRecommender(dataModel, userNeighborhood, similarity);
//推薦2個
List<RecommendedItem> recommendedItems = recommender.recommend(userId, 5);
List<Long> itemIds = recommendedItems.stream().map(RecommendedItem::getItemID).collect(Collectors.toList());
return itemIds;
}
private DataModel createDataModel(List<UserArticleOperation> userArticleOperations) {
FastByIDMap<PreferenceArray> fastByIdMap = new FastByIDMap<>();
Map<Integer, List<UserArticleOperation>> map = userArticleOperations.stream().collect(Collectors.groupingBy(UserArticleOperation::getUserId));
Collection<List<UserArticleOperation>> list = map.values();
for(List<UserArticleOperation> userPreferences : list){
GenericPreference[] array = new GenericPreference[userPreferences.size()];
for(int i = 0; i < userPreferences.size(); i++){
UserArticleOperation userPreference = userPreferences.get(i);
GenericPreference item = new GenericPreference(userPreference.getUserId(), userPreference.getArticleId(), userPreference.getValue());
array[i] = item;
}
fastByIdMap.put(array[0].getUserID(), new GenericUserPreferenceArray(Arrays.asList(array)));
}
return new GenericDataModel(fastByIdMap);
}
<select id="getAllUserPreference" resultType="UserArticleOperation">
SELECT
user_id,
article_id,
SUM(
CASE operation_type
WHEN 0 THEN 2
WHEN 1 THEN 3
WHEN 2 THEN 5
else 0 END
) AS "value"
FROM
user_article_operation
GROUP BY user_id,article_id
</select>
到了這里,關于springboot集成mahout實現(xiàn)簡單基于協(xié)同過濾算法的文章推薦算法的文章就介紹完了。如果您還想了解更多內容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!