mahout连接mysql,使用ReloadFromJDBCDataModel,采用SVD推荐算法。

因为工作需要,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给他前端,让前端显示相应的产品给用户。

	}
}

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

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

    原文作者:pan12jian
    原文地址: https://blog.csdn.net/pan12jian/article/details/26451495
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞