基于用户的协同过滤算法(java代码)

1.User_collaborative_Filtering类

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;



public class User_collaborative_Filtering {
		double finally_up = 0;//存放最终上面数据
		double finally_down =0;//存放最终上面数据
		int m;//记录用户数
		int n;//记录项目数
		int rate_level = 5;//存放用户的评分
		public Triple[] Obj_User;//初始化运行
		int[] User_rate_times ;//初始化运行
		double[] User_quality;//各个商品的质量
		int[] Same_User;//定义与评价过商品的用户赋值为1
		double[] Pearson_correlation_coefficient;//计算邻居与目标用户的皮尔逊系数
		double[][] User_Obj_rate;//创建用户评价项目的评分矩阵
		double User_p;//存放皮尔逊相关系数
		double[] User_Pearson_correlation;
		double predict_Score;//输出预测分数
		int seek_User;//存放预测用户
		int seek_Item;//存放预测项
		double[] after_same_array;//存放皮尔逊相关系数排序后的数组
		int[] same_index;//存放相似用户的编号
		double[] same_User_Pearson_correlation;//创建查找皮尔逊最大两个值的数组下标
		int count;
		
		private File file=new File(""); //输入读取的文件
		FileInputStream in = null;
		InputStreamReader reader=null;
		BufferedReader buf_reader=null;
		
		public void input_value (){
			System.out.println("请输入预测的用户和项目编号:");
			Scanner input = new Scanner(System.in);
			this.seek_User = input.nextInt();//nextInt()方法读取输入数据为int的类型
			this.seek_Item = input.nextInt();
			input.close();
		}
		
		public User_collaborative_Filtering() {
			this.m=0;
			this.n=0;
			Init();
		}
		
		public void Init()  {
			try {
				String str;
				in=new FileInputStream(file);
				reader = new InputStreamReader(in);
				buf_reader = new BufferedReader(reader);
				ArrayList<Double> Rate = new ArrayList<Double>();
				ArrayList<Integer> Users = new ArrayList<Integer>();
				ArrayList<Integer> Objs = new ArrayList<Integer>();
				int h=0;//读取行数
				while((str=buf_reader.readLine())!=null) {
					String[] string= str.split("\t");
					if(Integer.parseInt(string[0])>m) {
						m=Integer.parseInt(string[0]);
					}
					if(Integer.parseInt(string[1])>n) {
						n=Integer.parseInt(string[1]);
					}
					h++;
					Users.add(Integer.parseInt(string[0]));
					Rate.add(Double.parseDouble(string[2]));
					Objs.add(Integer.parseInt(string[1]));
				}
				Obj_User=new Triple[h];	
				User_quality=new double[m];//存放用户的平均分
				User_rate_times= new int[m]; //用于统计各个用户的购买次数
				Same_User = new int[m];//找出评价过预测商品的用户
				Pearson_correlation_coefficient = new double[m];
				User_Obj_rate =new double[m][n];
				User_Pearson_correlation = new double[m];
				after_same_array = new double[m];
				same_index = new int[m];
				same_User_Pearson_correlation = new double[m];
				for(int n=0;n<h;n++) {
					Obj_User[n]=new Triple();
				}
				for(int n=0;n<h;n++) {
					if(Rate.get(n)!=0) {
						Obj_User[n].i=Users.get(n);//将初始信息存放在三元组之中
						Obj_User[n].j=Objs.get(n);
						Obj_User[n].data=Rate.get(n);
					}
				}
				
				
			}
			catch (FileNotFoundException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
				} 
			catch (IOException e) {
					// TODO 自动生成的 catch 块
					e.printStackTrace();
					}
			}
		
		public void Init_User_Obj_rate(){
			for(int i=0;i<Obj_User.length;i++) {
				User_Obj_rate[Obj_User[i].i-1][Obj_User[i].j-1]=Obj_User[i].data;
			}
		}
		
		public void Init_User_rate_time() {//统计用户的评分次数
			for(int i=0;i<Obj_User.length;i++) {
				User_rate_times[Obj_User[i].i-1]++;
			}
		
		}
		
		public void Init_User_quality(){//计算每个用户的平均分
			for(int i = 0;i < Obj_User.length;i++){
				User_quality[Obj_User[i].i-1] += Obj_User[i].data;
			}
			for(int i = 0;i < m;i++){
				User_quality[i] = User_quality[i]/User_rate_times[i];
			}
		}
		
		public void Select_Same_User(int a_item,int b_user){//传递需要预测的商品编号,其中a代表商品编号,b代表用户编号
			for(int i = 0;i < m;i++){
				int count3 = 0;
				if(User_Obj_rate[i][(a_item-1)]!= 0){
						for(int j =0;j<n;j++){
							if(User_Obj_rate[i][j]!=0 && User_Obj_rate[b_user-1][j]!=0){
								count3++;
								if(count3>=10){//限制用户之间的度至少要大于多少
								Same_User[i]=1;
							}
						
					}
				}
			}
			}
		}
		//这边往上都没问题
		public void Calcuate_Pearson_correlation_coefficient(int b){//传入用户编号
			
			for(int i = 0;i < m;i++){
				if(Same_User[i]==1){
				double s_up = 0;//存放皮尔逊系数的上半部分
				double s_down = 0;
				double s_down1 = 0;//存放相同用户皮尔逊系数的下半部分
				double s_down2 = 0;//存放相同用户皮尔逊系数的下半部分
				if(i != (b-1)){
					//System.out.println("此时用户为: "+(i+1));
					for(int j = 0;j < n;j++){
						if(User_Obj_rate[i][j]!=0 && User_Obj_rate[b-1][j]!=0){
							s_up += (User_Obj_rate[b-1][j]-User_quality[b-1])*(User_Obj_rate[i][j]-User_quality[i]);
							s_down1 +=((User_Obj_rate[b-1][j]-User_quality[b-1])*(User_Obj_rate[b-1][j]-User_quality[b-1]));
							s_down2 +=(User_Obj_rate[i][j]-User_quality[i])*(User_Obj_rate[i][j]-User_quality[i]);
						}
					}
					s_down =((Math.sqrt(s_down1))*(Math.sqrt(s_down2)));
					//System.out.println("这是当用户为: "+(i+1)+"时,s_up: "+s_up+"s_down1: "+s_down1+"s_down2: "+s_down2+"s_down: "+s_down);
					User_p = s_up/s_down;
					User_Pearson_correlation[i]=User_p;	
				}
			}	
			}
		}
		
		public void creat_same_User_Pearson_correlation(){//创建皮尔逊查找数组下标数组
			for(int i = 0;i<m;i++){
				same_User_Pearson_correlation[i]=User_Pearson_correlation[i];
			}
		}
		
		
		
		public void select_userNumbers(){//选择相似用户的个数
			int count = 2;//设置选择相近用户的个数 
			for(int j = 0;j< count;j++){
				double max1=same_User_Pearson_correlation[0];
					for(int i = 0;i < m-1;i++){//该循环为了找最大值
						if(same_User_Pearson_correlation[i+1]>max1){
							max1 = same_User_Pearson_correlation[i+1];
						}
					}
					for(int i = 0;i < m;i++){//该循环为了找最大值的下标
						if(same_User_Pearson_correlation[i]==max1){
							same_index[i] = 1;
							same_User_Pearson_correlation[i]=0;
						}
					}
			}
		}
		
		public void predict_score(int a,int b){//a传递商品编号,b传递用户编号
			
			for(int i = 0;i < m;i++){
				if(same_index[i]!=0&&User_Pearson_correlation[i]>0 && i!=(b-1)){
					this.finally_up +=User_Pearson_correlation[i]*(User_Obj_rate[i][a-1]-User_quality[i]);
					this.finally_down +=Math.abs(User_Pearson_correlation[i]);
					
					}
				}
			
			this.predict_Score = finally_up/finally_down+User_quality[b-1];
		}
		
		public void Calculate(){
			
			input_value();
			Init();
			Init_User_Obj_rate();
			Init_User_rate_time();
			Init_User_quality();
			Select_Same_User(seek_Item,seek_User);
			Calcuate_Pearson_correlation_coefficient(seek_User);
			creat_same_User_Pearson_correlation();
			select_userNumbers();
			predict_score(seek_Item,seek_User);
			System.out.println("用户 "+seek_User+" 对商品 "+seek_Item+" 的评分预测为:"+predict_Score);
		}
}

2.Triple类

public class Triple {
	public int i;//分别用来表示行和列
	public int j;
	public double  data;//用于存储数值
	public Triple(int i,int j,double data) {
		this.i=i;
		this.j=j;
		this.data=data;
	}
	public Triple() {
	}
}

3.Run_code类(主类)

public class Run_code {
	public static void main(String[] arguments){
		User_collaborative_Filtering test = new User_collaborative_Filtering();
		test.Calculate();   
	}
}

本文是是利用皮尔逊计算相似用户,来预测用户对商品的评分,该代码可以实现用户对商品的预测评分,只需要在上面的代码中,输入相应的文件即可。