這裡採用的是.net的一個引用NReco.Recommender.dll,這是一個國外電影網站推薦系統衍生而來的,有興趣的可以到他們的官網看看。 以圖書商城為例 MVC 構造行為數據 首先需要對資料庫進行設計,增加一張用戶的行為數據表,記錄用戶訪問網站的行為,例如商城的一般記錄瀏覽的商品和購買過的商 ...
這裡採用的是.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 "\t" item.bookID "\t" item.stars "\t" WebCommon.DateTimeToUnixTimestamp(Convert.ToDateTime(item.addTime)) "\r\n");
}
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;
}
當然直接這樣會有冷啟動問題,就是用戶沒有登錄的情況和用戶還沒有行為數據的情況,本人採用熱門商品的推薦。你也可以根據你的業務邏輯進行設計。
這隻是本人的簡單實現方案,還需要不斷的完善,歡迎提出意見或建議,感謝您的閱讀。