因为工作需要,mahout直接连接mysql做智能推荐。首先你得自己去计算(User_id,Item_id,preference),然后把这些数据导入到数据库中,JDBCDataModel对Mysql格式做了限制。推荐使用如下语句建立自己的表

CREATE TABLE taste_preferences (

user_id BIGINT NOT NULL,

item_id BIGINT NOT NULL,

preference FLOAT NOT NULL,

PRIMARY KEY (user_id, item_id),

INDEX (user_id),

INDEX (item_id)

)

自己的数据准备好了,就可以用啦。

package demo;

import java.util.ArrayList;

import java.util.HashMap;

import java.util.Map;

import org.apache.mahout.cf.taste.common.TasteException;

import org.apache.mahout.cf.taste.impl.model.jdbc.MySQLJDBCDataModel;

import org.apache.mahout.cf.taste.impl.model.jdbc.ReloadFromJDBCDataModel;

import org.apache.mahout.cf.taste.impl.recommender.svd.ALSWRFactorizer;

import org.apache.mahout.cf.taste.impl.recommender.svd.SVDRecommender;

import org.apache.mahout.cf.taste.model.DataModel;

import org.apache.mahout.cf.taste.model.JDBCDataModel;

import org.apache.mahout.cf.taste.recommender.Recommender;

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

public class Test {

static Map hashMap = new HashMap();

//返回一个的hashMap,意义是为User推荐对应的item。

public HashMap SVDlist(DataModel model,

ArrayList userIDs, ArrayList brandIDs)

throws TasteException {

System.out.println("-------------------------------------------------------- ");

//这里有另外一种协同过滤算法,基于Item的,我测试结果不是很好,就没用了。

// ItemSimilarity similarity = new PearsonCorrelationSimilarity(

// model);

// Recommender recommender = new GenericItemBasedRecommender(model,

// similarity);

Recommender recommender = new SVDRecommender(model,

new ALSWRFactorizer(model, 10, 0.75, 20));

for (int i = 0; i < userIDs.size(); i++) {

float score = 0, scoretemp = 0;

Long bestBrand = 0L;

for (int j = 0; j < brandIDs.size(); j++) {

scoretemp = recommender.estimatePreference(userIDs.get(i),

brandIDs.get(j));

if (scoretemp > score) {

score = scoretemp;

bestBrand = brandIDs.get(j);

}

hashMap.put(userIDs.get(i), bestBrand);

}

System.out.println("The best brand for " + userIDs.get(i) + " is "

+ bestBrand);

}

return (HashMap) hashMap;

}

public static void main(String[] args) throws Exception {

String driver = "com.mysql.jdbc.Driver";

String host = "192.168.1.102";

String user = "test";

String password = "123456";

String databasename = "test_orders";

Class.forName(driver);

MysqlDataSource dataSource = new MysqlDataSource();

dataSource.setServerName(host);

dataSource.setUser(user);

dataSource.setPassword(password);

dataSource.setDatabaseName(databasename);

JDBCDataModel jdbcDataModel = new MySQLJDBCDataModel(dataSource,

"taste_preferences", "user_id", "item_id", "preference", null);

//利用ReloadFromJDBCDataModel包裹jdbcDataModel,可以把输入加入内存计算,加快计算速度。

ReloadFromJDBCDataModel model = new ReloadFromJDBCDataModel(

jdbcDataModel);

//这里的refresh是刷新model,一般情况下我觉得用不上,因为像我这个程序,每次都会新建立datamodel,都是最新的,所以不用刷新

//当然,如果你需要在内存中存储下model,然后自己的taste_preferences时刻在变化,此时是需要刷新的。

//model.refresh(null);

//测试的brandIds可以从自己的数据库中获得,这里为了简单,只是加了几个做测试。

ArrayList brandIDs = new ArrayList();

brandIDs.add(2215L);

brandIDs.add(458L);

brandIDs.add(691L);

brandIDs.add(3027L);

brandIDs.add(1143L);

ArrayList userIDs = new ArrayList();

userIDs.add(2640L);

userIDs.add(1640L);

userIDs.add(22845512L);

Test test = new Test();

hashMap = test.SVDlist(model, userIDs, brandIDs);

//在之后你可以把这数据写入自己的数据库,或者直接post给他前端,让前端显示相应的产品给用户。

}

}

由于刚开始mahout只有jdbcDatamodel,这个不是内存计算,导致运算速度巨慢无比,所以很多人对mahout直接连接数据库建立model都非常抵触,其实现在的ReloadFromJDBCDataModel速度还不错,反正我用可以了,o(∩∩)o…哈哈。

如果文章有错误,敬请指正,共同学习。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐