[ユーザーベース]協調フィルタリング推奨アルゴリズム(UserCFアルゴリズムの実装)

協調フィルタリングアルゴリズムは、主にユーザー(UserCF)アイテムベース(ItemCF)の 2つの異なるタイプ基づいて、推奨アルゴリズムの分野で広く使用されています。

  • ユーザーベースの推奨アルゴリズム:同様の関心を持つユーザーを見つけるアルゴリズムです。学習リソース共有プラットフォームを構築している場合、ユーザーグループは、一般的に安定した専門家であり、比較的固定された読書と学習の趣味を持っています。ユーザーA(つまり、ログインしたユーザー)がパーソナライズされた推奨事項を必要とする場合、彼はまず自分の興味に似ているユーザーグループGを見つけ、次にGに含まれAには含まれないものを予測して評価し、最後に予測された評価値に基づいて評価できます。ユーザーAが推奨を行います。
  • アイテムベースの推奨アルゴリズム:以前に花を購入したなどの理由でユーザーがパーソナライズされた推奨を必要とする場合、他の多くのユーザーが同時に花とフラワーポットを購入するため、フラワーポットを彼に推奨します。アイテムベースの推奨アルゴリズムでは、最初にアイテム間の類似性を計算し、次にアイテムの類似性とユーザーの過去の行動に基づいてユーザーの推奨リストを生成する必要があります。

この記事の作成者は、最初のアルゴリズムであるユーザーベースの協調フィルタリングアルゴリズム(UserCF)の実装を紹介します。前述のように、ステップを3つのステップに分けます。

1.ユーザーAと同様の関心を持つユーザーグループを見つける

  •   まず、ユーザー間の類似度を計算する必要があります。このペーパーでは、コサイン類似度を使用して計算します。式は次のとおりです。

                                                           

       (N(u)はユーザーuが購入したアイテムのセットを表し、| N(u)|はユーザーuが購入したアイテムの数、N(v)は同じであり、ユーザーvのオブジェクトです) 

        分母部分を計算します。類似性マトリックスsparseMatrixを作成します。sparseMatrix[u] [v]は、ユーザーuとユーザーvが購入した同一アイテムの数を表します

  •   次に、ユーザーの類似性を降順で並べ替え、しきい値内で最も類似したユーザーグループのみを取得します。 

2. Aが聞いたことも見たこともないGに含まれるものを予測および分析します。

        類似ユーザーのグループから、私(ログインユーザー)が持っていない類似ユーザーが購入したアイテムを予測ありのアイテムとして取得します。私の興味を共有しているユーザーがそれらを購入したので、私もそれらを好きかもしれませんこれがUserCFの原則です。これらの項目を予測するには、予測分析を実行する必要があります。式は次のとおりです。

                                                          

ここで、uはユーザー、iはアイテム、(u、k)はユーザーの類似グループu、p(u、i)はユーザーのアイテムiの好意、rは評価、この例では1としますスコアリングシステムでは、重みを調整して結果をより正確にする役割を果たします。

3.予測分析値に基づいてAを推奨

     予測項目の好感度をユーザーが分析した結果、ソート後にソートされたリストを生成することができますが、この例ではより簡潔で、最適なリストのみを推奨しています。

コードは次のとおりです。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
const int maxn = 100;
struct similarty{
	double weight;
	int user;
}similartys[maxn];
void myprint(int userItem[][maxn],int n){
	for(int i=0;i<n;i++){
		cout<<"用户"<<userItem[i][0]<<"买了:";
		int j=1; 
		while(userItem[i][j]!='\0'){
			cout<<userItem[i][j]<<" ";
			j++;
		}
		cout<<endl;
	}
	cout<<"-----------"<<endl;
}
int length(int *array){
	int num=0;
	int p=1;
	while(array[p]!='\0'){
		num++;
		p++; 
	} 
	return num;
}
bool myfind(int userItem[][maxn],int user,int n){
	for(int i=1;i<=length(userItem[user-1]);i++){
		if(userItem[user-1][i]==n) return true;
	}
	return false;
}
bool cmp(similarty a,similarty b){
	return a.weight>b.weight;
}
int main(){
	int n=5;  //用户人数 
	int userId=3;  //推荐给userId 
	int num=2; //匹配用户个数 
	cout<<"用户人数:"<<n<<"  "<<"登录id:"<<userId<<endl<<"具体情况:"<<endl; 
	//数据集
	int userItem[n][maxn]={
		{1,1,2,3,6,7},
		{2,2,3},
		{3,1,2,4,5,7},
		{4,1,2,4,6},
		{5,3,4}
	};
	myprint(userItem,n);
	int sparseMatrix[n+1][n+1];  //记录两个用户之间的相似度的稀疏矩阵 
	memset(sparseMatrix,0,sizeof(sparseMatrix));
	//计算用户之间的相似相似度矩阵 
	for(int i=0;i<n;i++){
		for(int j=i+1;j<n;j++){
			int p=1;
			while(userItem[i][p]!='\0'){
				int q=1;
				while(userItem[j][q]!='\0'){
					if(userItem[i][p] == userItem[j][q]){
						sparseMatrix[userItem[j][0]][userItem[i][0]]++;
						sparseMatrix[userItem[i][0]][userItem[j][0]]++;
						break;
					}
					q++;
				}
				p++;
			}
			
		} 
	} 
	//计算用户之间的相似度 (余弦相似性)
	int userIdLength = length(userItem[userId-1]);
	int cnt=0;
	for(int i=1;i<=n;i++){
		if(i!=userId){
			int iLength = length(userItem[i-1]);
			similartys[cnt].weight = sparseMatrix[userId][i]/sqrt(userIdLength*iLength);
			similartys[cnt].user = i;
			cout<<"用户"<<userId<<"和"<<i<<"相似度:"<<similartys[cnt].weight<<endl;
			cnt++;
		}else{
			similartys[cnt++].weight=-1;
		}
	}
	sort(similartys,similartys+n,cmp);
	cout<<"-----------"<<endl<<"用户匹配度最高的[2]位用户为:"; 
	for(int i=0;i<2;i++){
		cout<<similartys[i].user<<" ";
	}
	set<int> items;   //记录考虑的商品:相似用户有的,而登录用户没有的 
	for(int i=0;i<2;i++){
		for(int j=1;j<=length(userItem[similartys[i].user-1]);j++){
			if(!myfind(userItem,userId,userItem[similartys[i].user-1][j])){
				items.insert(userItem[similartys[i].user-1][j]);
			}
		}		
	} 
	cout<<endl<<"-----------"<<endl<<"考虑商品:"<<endl;
	set<int>::iterator it = items.begin();
	for(it;it!=items.end();it++){
		cout<<*it<<" ";
	}
	cout<<endl<<"它们的匹配度为:"<<endl;
	//计算商品匹配度 
	double maxpick = 0; 
	int recommendation;
	for(it=items.begin();it!=items.end();it++){
		double pick = 0;
		for(int i=0;i<2;i++){
			if(myfind(userItem,similartys[i].user,*it)){
				pick+=similartys[i].weight;
			}
		}
		if(pick>maxpick){
			maxpick = pick;
			recommendation = *it;
		}
		cout<<"商品"<<*it<<":"<<pick<<endl;
	}	
	cout<<"-----------"<<endl<<"推荐商品:"<<recommendation<<endl;
}

操作効果: 

概要:CFアルゴリズムの原理は実際には比較的単純であり、基本的な機能を実現するには、いくつかのステップで計算式を習得する必要があります。

元の記事を20件公開 15 獲得 ビュー216

おすすめ

転載: blog.csdn.net/qq_37414463/article/details/105410992