C#实现协同过滤算法的实例代码
程序员文章站
2023-12-19 23:37:28
复制代码 代码如下:using system;using system.collections.generic;using system.linq;using system...
复制代码 代码如下:
using system;
using system.collections.generic;
using system.linq;
using system.text;
namespace slopeone
{
public class rating
{
public float value { get; set; }
public int freq { get; set; }
public float averagevalue
{
get { return value / freq; }
}
}
public class ratingdifferencecollection : dictionary<string, rating>
{
private string getkey(int item1id, int item2id)
{
return (item1id < item2id) ? item1id + "/" + item2id : item2id + "/" + item1id ;
}
public bool contains(int item1id, int item2id)
{
return this.keys.contains<string>(getkey(item1id, item2id));
}
public rating this[int item1id, int item2id]
{
get {
return this[this.getkey(item1id, item2id)];
}
set { this[this.getkey(item1id, item2id)] = value; }
}
}
public class slopeone
{
public ratingdifferencecollection _diffmarix = new ratingdifferencecollection(); // the dictionary to keep the diff matrix
public hashset<int> _items = new hashset<int>(); // tracking how many items totally
public void adduserratings(idictionary<int, float> userratings)
{
foreach (var item1 in userratings)
{
int item1id = item1.key;
float item1rating = item1.value;
_items.add(item1.key);
foreach (var item2 in userratings)
{
if (item2.key <= item1id) continue; // eliminate redundancy
int item2id = item2.key;
float item2rating = item2.value;
rating ratingdiff;
if (_diffmarix.contains(item1id, item2id))
{
ratingdiff = _diffmarix[item1id, item2id];
}
else
{
ratingdiff = new rating();
_diffmarix[item1id, item2id] = ratingdiff;
}
ratingdiff.value += item1rating - item2rating;
ratingdiff.freq += 1;
}
}
}
// input ratings of all users
public void adduerratings(ilist<idictionary<int, float>> ratings)
{
foreach(var userratings in ratings)
{
adduserratings(userratings);
}
}
public idictionary<int, float> predict(idictionary<int, float> userratings)
{
dictionary<int, float> predictions = new dictionary<int, float>();
foreach (var itemid in this._items)
{
if (userratings.keys.contains(itemid)) continue; // user has rated this item, just skip it
rating itemrating = new rating();
foreach (var userrating in userratings)
{
if (userrating.key == itemid) continue;
int inputitemid = userrating.key;
if (_diffmarix.contains(itemid, inputitemid))
{
rating diff = _diffmarix[itemid, inputitemid];
itemrating.value += diff.freq * (userrating.value + diff.averagevalue * ((itemid < inputitemid) ? 1 : -1));
itemrating.freq += diff.freq;
}
}
predictions.add(itemid, itemrating.averagevalue);
}
return predictions;
}
public static void test()
{
slopeone test = new slopeone();
dictionary<int, float> userrating = new dictionary<int, float>();
userrating.add(1, 5);
userrating.add(2, 4);
userrating.add(3, 4);
test.adduserratings(userrating);
userrating = new dictionary<int, float>();
userrating.add(1, 4);
userrating.add(2, 5);
userrating.add(3, 3);
userrating.add(4, 5);
test.adduserratings(userrating);
userrating = new dictionary<int, float>();
userrating.add(1, 4);
userrating.add(2, 4);
userrating.add(4, 5);
test.adduserratings(userrating);
userrating = new dictionary<int, float>();
userrating.add(1, 5);
userrating.add(3, 4);
idictionary<int, float> predictions = test.predict(userrating);
foreach (var rating in predictions)
{
console.writeline("item " + rating.key + " rating: " + rating.value);
}
}
}
}