因为工作需要,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<Long, Long> hashMap = new HashMap<Long, Long>(); //返回一个<userID,itemID>的hashMap,意义是为User推荐对应的item。 public HashMap<Long, Long> SVDlist(DataModel model, ArrayList<Long> userIDs, ArrayList<Long> 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<Long, Long>) 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<Long> brandIDs = new ArrayList<Long>(); brandIDs.add(2215L); brandIDs.add(458L); brandIDs.add(691L); brandIDs.add(3027L); brandIDs.add(1143L); ArrayList<Long> userIDs = new ArrayList<Long>(); userIDs.add(2640L); userIDs.add(1640L); userIDs.add(22845512L); Test test = new Test(); hashMap = test.SVDlist(model, userIDs, brandIDs); //在之后你可以把这数据写入自己的数据库,或者直接post给他前端,让前端显示相应的产品给用户。 } }
如果文章有错误,敬请指正,共同学习。