赣州网站建设专家,福州市高速公路建设指挥部网站,西安手机商城网站设计,做网站项目前怎么收集需求一、概念
相信大家对如下的 Category 都很熟悉#xff0c;很多网站都有类似如下的功能#xff0c;“商品推荐”,猜你喜欢“#xff0c;在实体店中我们有导购来为我们服务#xff0c;在网络上我们需要同样的一种替代物#xff0c;如果简简单单的在数据库里面去捞很多网站都有类似如下的功能“商品推荐”,猜你喜欢“在实体店中我们有导购来为我们服务在网络上我们需要同样的一种替代物如果简简单单的在数据库里面去捞去比较几乎是完成不了的,这时我们就需要一种协同推荐算法来高效的推荐浏览者喜欢的商品。 SlopeOne 的思想很简单就是用均值化的思想来掩盖个体的打分差异举个例子说明一下 在这个图中系统该如何计算“王五“对”电冰箱“的打分值呢刚才我们也说了slopeone 是采用均值化的思想,也就是R 王五 4-{[(5-10)(4-5)]/2}7 。 下面我们看看多于两项的商品如何计算打分值。 rb (n * (ra - R(A-B)) m * (rc - R(C-B)))/(mn) 注意 a,b,c 代表“商品”。 ra 代表“商品的打分值”。 ra-b 代表“A组到B组的平均差均值化”。 m,n 代表人数。 根据公式我们来算一下。 r 王五 (2 * (4 - R(洗衣机- 彩电)) 2 * (10 - R(电冰箱- 彩电)) 2 * (5 - R(空调- 彩电)))/(222)6.8 是的slopeOne 就是这么简单实战效果非常不错。
二、实现
1、定义一个评分类 Rating。 /// summary/// 评分实体类/// /summarypublic class Rating{/// summary/// 记录差值/// /summarypublic float Value { get; set; }/// summary/// 记录评分人数方便公式中的 m 和 n 的值/// /summarypublic int Freq { get; set; }/// summary/// 记录打分用户的ID/// /summarypublic HashSetint hash_user new HashSetint();/// summary/// 平均值/// /summarypublic float AverageValue{get { return Value / Freq; }}}2、定义一个产品类 /// summary/// 产品类/// /summarypublic class Product{public int ProductID { get; set; }public string ProductName { get; set; }/// summary/// 对产品的打分/// /summarypublic float Score { get; set; }}3、SlopeOne 类
参考了网络上的例子将二维矩阵做成线性表有效的降低了空间复杂度。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;namespace SupportCenter.Test
{#region Slope One 算法/// summary/// Slope One 算法/// /summarypublic class SlopeOne{/// summary/// 评分系统/// /summarypublic static Dictionaryint, Product dicRatingSystem new Dictionaryint, Product();public Dictionarystring, Rating dic_Martix new Dictionarystring, Rating();public HashSetint hash_items new HashSetint();#region 接收一个用户的打分记录/// summary/// 接收一个用户的打分记录/// /summary/// param nameuserRatings/parampublic void AddUserRatings(IDictionaryint, ListProduct userRatings){foreach (var user1 in userRatings){//遍历所有的Itemforeach (var item1 in user1.Value){//该产品的编号具有唯一性int item1Id item1.ProductID;//该项目的评分float item1Rating item1.Score;//将产品编号字存放在hash表中hash_items.Add(item1.ProductID);foreach (var user2 in userRatings){//再次遍历item用于计算俩俩 Item 之间的差值foreach (var item2 in user2.Value){//过滤掉同名的项目if (item2.ProductID item1Id)continue;//该产品的名字int item2Id item2.ProductID;//该项目的评分float item2Rating item2.Score;Rating ratingDiff;//用表的形式构建矩阵var key Tools.GetKey(item1Id, item2Id);//将俩俩 Item 的差值 存放到 Rating 中if (dic_Martix.Keys.Contains(key))ratingDiff dic_Martix[key];else{ratingDiff new Rating();dic_Martix[key] ratingDiff;}//方便以后以后userrating的编辑操作add)if (!ratingDiff.hash_user.Contains(user1.Key)){//value保存差值ratingDiff.Value item1Rating - item2Rating;//说明计算过一次ratingDiff.Freq 1;}//记录操作人的ID方便以后再次添加评分ratingDiff.hash_user.Add(user1.Key);}}}}}#endregion#region 根据矩阵的值预测出该Rating中的值/// summary/// 根据矩阵的值预测出该Rating中的值/// /summary/// param nameuserRatings/param/// returns/returnspublic IDictionaryint, float Predict(ListProduct userRatings){Dictionaryint, float predictions new Dictionaryint, float();var productIDs userRatings.Select(i i.ProductID).ToList();//循环遍历_Items中所有的Itemsforeach (var itemId in this.hash_items){//过滤掉不需要计算的产品编号if (productIDs.Contains(itemId))continue;Rating itemRating new Rating();// 内层遍历userRatingsforeach (var userRating in userRatings){if (userRating.ProductID itemId)continue;int inputItemId userRating.ProductID;//获取该key对应项目的两组AVG的值var key Tools.GetKey(itemId, inputItemId);if (dic_Martix.Keys.Contains(key)){Rating diff dic_Martix[key];//关键点运用公式求解这边为了节省空间对角线两侧的值呈现奇函数的特性itemRating.Value diff.Freq * (userRating.Score diff.AverageValue * ((itemId inputItemId) ? 1 : -1));//关键点运用公式求解 累计每两组的人数itemRating.Freq diff.Freq;}}predictions.Add(itemId, itemRating.AverageValue);}return predictions;}#endregion}#endregion#region 工具类/// summary/// 工具类/// /summarypublic class Tools{public static string GetKey(int Item1Id, int Item2Id){return (Item1Id Item2Id) ? Item1Id - Item2Id : Item2Id - Item1Id;}}#endregion
}4、测试类 Program
这里我们灌入了 userid100020003000 的这三个人然后我们预测 userID3000 这个人对 “彩电” 的打分会是多少 public class Program{static void Main(string[] args){SlopeOne test new SlopeOne();Dictionaryint, ListProduct userRating new Dictionaryint, ListProduct();//第一位用户ListProduct list new ListProduct(){new Product(){ ProductID1, ProductName洗衣机,Score5},new Product(){ ProductID2, ProductName电冰箱, Score10},new Product(){ ProductID3, ProductName彩电, Score10},new Product(){ ProductID4, ProductName空调, Score5},};userRating.Add(1000, list);test.AddUserRatings(userRating);userRating.Clear();userRating.Add(1000, list);test.AddUserRatings(userRating);//第二位用户list new ListProduct(){new Product(){ ProductID1, ProductName洗衣机,Score4},new Product(){ ProductID2, ProductName电冰箱, Score5},new Product(){ ProductID3, ProductName彩电, Score4},new Product(){ ProductID4, ProductName空调, Score10},};userRating.Clear();userRating.Add(2000, list);test.AddUserRatings(userRating);//第三位用户list new ListProduct(){new Product(){ ProductID1, ProductName洗衣机, Score4},new Product(){ ProductID2, ProductName电冰箱, Score10},new Product(){ ProductID4, ProductName空调, Score5},};userRating.Clear();userRating.Add(3000, list);test.AddUserRatings(userRating);//那么我们预测userID3000这个人对 “彩电” 的打分会是多少var userID userRating.Keys.FirstOrDefault();var result userRating[userID];var predictions test.Predict(result);foreach (var rating in predictions)Console.WriteLine(ProductID rating.Key Rating: rating.Value);}}