• 如何轻松实现个性化推荐系统


    这里采用的是.net的一个引用NReco.Recommender.dll,这是一个国外电影网站推荐系统衍生而来的,有兴趣的可以到他们的官网看看。

    以图书商城为例 MVC

    构造行为数据

    首先需要对数据库进行设计,增加一张用户的行为数据表,记录用户访问网站的行为,例如商城的一般记录浏览的商品和购买过的商品,根据你的业务逻辑进行设计。

    构造评分数据

    需要对商品的进行评分,一般采用5分制,可以根据你的业务逻辑进行设计。

    生成评分离线数据

     public class IndexJobRatings : IJob
        {
            Irecommend_ratingBLL ratingbll = new BLL.recommend_ratingBLL();
            ISettingsBLL setingsbll = new BLL.SettingsBLL();
            #region IJob 成员
            /// <summary>
            /// 定时处理任务都要放在这个方法
            /// </summary>
            /// <param name="context"></param>
            public void Execute(JobExecutionContext context)
            {
                var list = ratingbll.LoadEntities(c => true).ToList();
                StringBuilder sb = new StringBuilder();
                foreach (var item in list)
                {
                    //需要过滤 取平均值
                    sb.Append(item.userID   "	"   item.bookID   "	"   item.stars   "	"   WebCommon.DateTimeToUnixTimestamp(Convert.ToDateTime(item.addTime))   "
    ");
                }
                var logmodel = setingsbll.LoadEntities(c=>c.id==16).FirstOrDefault();
                if (logmodel != null && logmodel.value == "true")
                {
                    System.IO.File.WriteAllText(WebCommon.MapPath("/data/ratings.dat"), sb.ToString());//写入文件  
                    logmodel.value = "false";
                    setingsbll.UpdateEntity(logmodel);
                }
                else
                {
                    System.IO.File.WriteAllText(WebCommon.MapPath("/data/ratings1.dat"), sb.ToString());//写入文件
                    logmodel.value = "true";
                    setingsbll.UpdateEntity(logmodel);
                }
            }
    
            #endregion
        }
    

    本人使用时间进度插件定时执行改任务,更新数据提高数据的准确率。

    添加引用

    直接在NuGet管理中添加即可,搜索NReco.Recommender

    实现推荐

    /// <summary>
            /// 推荐
            /// </summary>
            /// <param name="pageIndex">当前页</param>
            /// <param name="pageSize">页容量</param>
            /// <param name="showCount">显示数量</param>
            /// <returns></returns>
            public List<Books> RecommendBooks(int pageIndex, int pageSize, int showCount)
            {
                #region 推荐
                List<Books> books = null;
                if (Session["user"] != null)
                {
                    Users user = Session["user"] as Users;
    
                    #region 构建用户行为数组
                    var loglist = logbll.LoadEntities(c => c.userID == user.Id).ToList();
                    StringBuilder sb = new StringBuilder();
                    if (loglist.Count > 0)
                    {
                        sb.Append("[");
                        int j = 0;
                        foreach (var item in loglist)
                        {
                            j  ;
                            sb.Append(item.itemID.ToString());
                            if (j != loglist.Count)
                            {
                                sb.Append(",");
                            }
                        }
                        sb.Append("]");
                    }
                    #endregion
    
                    if (string.IsNullOrEmpty(sb.ToString()))
                    {
                        //冷启动
                        books = booksbll.LoadEntities(c => true).OrderByDescending(c => c.rating).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                    }
                    else
                    {
                        var filmIds = (new JavaScriptSerializer()).Deserialize<long[]>(sb.ToString());
    
                        var logmodel = settingbll.LoadEntities(c => c.id == 16).FirstOrDefault();
                        string path = "";
                        if (logmodel != null && logmodel.value == "true")
                        {
                            path = "data/ratings1.dat";
                        }
                        else
                        {
                            path = "data/ratings.dat";
                        }
    
                        var pathToDataFile =
                                Path.Combine(System.Web.HttpRuntime.AppDomainAppPath, path);
    
                        if (dataModel == null)
                        {
                            dataModel = new FileDataModel(pathToDataFile, false, FileDataModel.DEFAULT_MIN_RELOAD_INTERVAL_MS, false);
                        }
    
                        var plusAnonymModel = new PlusAnonymousUserDataModel(dataModel);
                        var prefArr = new GenericUserPreferenceArray(filmIds.Length);
                        prefArr.SetUserID(0, PlusAnonymousUserDataModel.TEMP_USER_ID);
                        for (int i = 0; i < filmIds.Length; i  )
                        {
                            prefArr.SetItemID(i, filmIds[i]);
                            prefArr.SetValue(i, 5); // lets assume max rating
                        }
                        plusAnonymModel.SetTempPrefs(prefArr);
    
                        var similarity = new LogLikelihoodSimilarity(plusAnonymModel);
                        var neighborhood = new NearestNUserNeighborhood(15, similarity, plusAnonymModel);
                        var recommender = new GenericUserBasedRecommender(plusAnonymModel, neighborhood, similarity);
                        var recommendedItems = recommender.Recommend(PlusAnonymousUserDataModel.TEMP_USER_ID, showCount, null);
                        List<Books> newbooks = new List<Books>();
                        foreach (var item in recommendedItems)
                        {
                            int bid = Convert.ToInt32(item.GetItemID());
                            newbooks.Add(booksbll.LoadEntities(c => c.Id == bid).FirstOrDefault());
                        }
    
                        books = newbooks.Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                    }
                }
                else //不推荐
                {
                    books = booksbll.LoadEntities(c => true).OrderByDescending(c => c.rating).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList();
                }
                #endregion
    
                return books.Count() <= 0 ? booksbll.LoadEntities(c => true).OrderByDescending(c => c.rating).Skip((pageIndex - 1) * pageSize).Take(pageSize).ToList() : books;
            }
    

    当然直接这样会有冷启动问题,就是用户没有登录的情况和用户还没有行为数据的情况,本人采用热门商品的推荐。你也可以根据你的业务逻辑进行设计。


    > 这只是本人的简单实现方案,还需要不断的完善,欢迎提出意见或建议,感谢您的阅读。
  • 相关阅读:
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    每日总结
    Windows邮件添加QQ邮箱
  • 原文地址:https://www.cnblogs.com/liujiaxian/p/6336814.html
Copyright © 2020-2023  润新知