RBM 推荐系统 Java代码(质量堪忧,仅供参考,欢迎讨论)

这是一段代码段,用Java写的,关于RBM ,也关于推荐系统。效率比较低,代码也有点问题。贴出来,仅仅是为了给大家提供一点思路,也是希望大家多多指教。仅仅贴出最重要的代码块,完整的代码,大家可以给我留言,我抽出时间来再来给大家发一份。抛砖引玉,希望能有同学或工程师来一起交流,大家共同进步,共同提高。


package rbm_1th;
import java.awt.List;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import static rbm_1th.utils.*;
import static rbm_1th.Get_data.*;
public class RBM
{
    public int N;
    public int n_visible;
    public int n_hidden;
    public double[][] W;
    public double[] hbias;
    public double[] vbias;
    public Random rng;
    //RBM的构造函数
    public RBM(int N,int n_visiable,int n_hidden,double[][] W,double[] hbias,double[] vbias,Random rng)
    {
        this.N = N;
        this.n_visible = n_visiable;
        this.n_hidden = n_hidden;
        
        if (rng == null)
        {
            this.rng = new Random(1234);
        }
        else{
            this.rng = rng;
        }

        if (W == null){
            this.W =new double[this.n_hidden][this.n_visible];
            double a = 1.0/this.n_visible;

            for (int i = 0; i < this.n_hidden; i++)
            {
                for (int j = 0; j< this.n_visible ; j++ )
                {
                    this.W[i][j] = uniform(-a,a,rng);
                }
            }
        }else
        {
            this.W = W;
        }
        
        if(hbias == null){
            this.hbias = new double[this.n_hidden];
            for (int i = 0;i<this.n_hidden;i++ )
            {
                this.hbias[i] = 0;
            }
        }else{
            this.hbias = hbias;
        }

        if (vbias == null)
        {
            this.vbias = new double[this.n_visible];
            for (int j = 0; j < this.n_visible ; j++ )
            {
                this.vbias[j] = 0;
            }
        }else{
            this.vbias = vbias;
        }

    }


    //CD-k算法
    public void contrastive_divergence(Map<Integer,Integer> input,double lr,int k)
    {
        
        double[] ph_mean = new double[n_hidden];
        int[] ph_sample = new int[n_hidden];
        double[] nv_means = new double[n_visible];
        Map<Integer,Integer> nv_samples = new HashMap<>();
        double[] nh_means = new double[n_hidden];
        int[] nh_samples = new int[n_hidden];
        
        sample_h_given_v(input,ph_mean,ph_sample);
        for (int step = 0; step < k;step++)
        {
            if (step == 0)
            {
                gibbs_hvh(ph_sample,nv_means,nv_samples,nh_means,nh_samples);

            }else {
                gibbs_hvh(nh_samples,nv_means,nv_samples,nh_means,nh_samples);
            }
        }
        /**这块儿代码可能有点问题,即在推荐系统里面是应该对所有的权重都改变还是只改变有过用户行为的显层和隐层的连接权重,这会儿脑子太乱,不想想了,欢迎大家拍砖指正**/
        for (int i=0; i<n_hidden; i++)
        {
            for (int j: input.keySet())//此处可能有问题,各位看看
            {
                W[i][j] += lr *(ph_mean[i]*input.get(j) - nh_means[i]*nv_samples.get(j));//此处可能有问题,各位看看,欢迎各位指正

                
            }
            hbias[i] += lr * (ph_sample[i] - nh_means[i]);
        }

        for (int j: input.keySet())
        {
            vbias[j] += lr *(input.get(j) - nv_samples.get(j));
        }


    }


    //可见层到隐藏层
    public double propup(Map<Integer,Integer> v,double[] w,double b)
    {
        double pre_sigmoid_activation = 0.0;
        for (int j :v.keySet() )
        {
            pre_sigmoid_activation += w[j] * v.get(j);
        }
        pre_sigmoid_activation += b;
        return sigmoid(pre_sigmoid_activation);
    }
    
    //隐藏层到可见层
    public double propdown(int[] h,int j,double b)
    {
        double pre_sigmoid_activation = 0.0;
        for (int i =0; i < h.length ; i++ )
        {
            pre_sigmoid_activation += W[i][j] * h[i];
        }
        pre_sigmoid_activation += b;
        
        return sigmoid(pre_sigmoid_activation);
    }
    
    //吉布斯
    public void gibbs_hvh(int[] h0_sample,double[] nv_means,Map<Integer,Integer> nv_samples,double[] nh_means,int[] nh_samples)
    {
        sample_v_given_h(h0_sample,nv_means,nv_samples);
        sample_h_given_v(nv_samples,nh_means,nh_samples);
    }
    
    //sample given hidden get visible
    public void sample_v_given_h(int[] h0_sample,double[] mean,Map<Integer,Integer> sample)
    {
        for (int j:sample.keySet() )
        {
            mean[j] = propdown(h0_sample, j,vbias[j]);
            int oz = binomial(1,mean[j],rng);
            sample.put(j, oz);
        }
    }

    //given visible get hidden
    public void sample_h_given_v(Map<Integer,Integer> v0_sample,double[] mean , int[] sample)
    {
        for (int i = 0;i<n_hidden;i++)
        {
            mean[i] = propup(v0_sample,W[i],hbias[i]);
            sample[i] = binomial(1,mean[i],rng);
        }

    }

    
    //函数重构
    public void reconstruct(Map<Integer,Integer> v,double[] reconstructed_v)
    {
        double[] h = new double[n_hidden];
        double pre_sigmoid_activation;

        for (int i = 0;i<n_hidden ;i++ )
        {
            h[i] = propup(v,W[i],hbias[i]);
        }

        for (int j :v.keySet() )
        {
            pre_sigmoid_activation = 0.0;
            for (int i =0; i<n_hidden ;i++ )
            {
                pre_sigmoid_activation += W[i][j] * h[i];
            }
            pre_sigmoid_activation += vbias[j];

            reconstructed_v[j] = sigmoid(pre_sigmoid_activation);
        }
    }
    //训练模型
    public static double[][] train_rbm()
    {
        Random rng = new Random(123);

        double learning_rate = 0.1;
        int training_epochs = 1;
        int k = 1;

        //获得数据
        String inpath = "D:/ml-1m/ratings.dat";
        Map<String,Map<String,Double>> u_p_s = loadData(inpath);
        Map<String,Integer> pid2num = get_pid2num(u_p_s);
        Map<String,Double> u_means = getU_mean(u_p_s);


        int train_N = u_p_s.size();
        
        int n_visible = pid2num.size();
        int n_hidden = 2;
        RBM rbm = new RBM(train_N,n_visible,n_hidden,null,null,null,rng);
        ArrayList<String> uid_list = new ArrayList<String>(u_p_s.keySet());

    
        for(int epoch = 0;epoch < training_epochs;epoch++)
        {
            for (int i =0 ; i <uid_list.size() ;i++)
            {
                String uid = uid_list.get(i);
                Map<String,Double> p_s = u_p_s.get(uid);
                
                double u_m = u_means.get(uid);

                Map<Integer,Integer> pid_oz = new HashMap<Integer,Integer>();

                for (String pid:p_s.keySet())
                {
                    Double score = u_p_s.get(uid).get(pid);
                    int x = pid2num.get(pid);
                    if (score > u_m)
                    {
                        pid_oz.put(x,1);
                    }
                    else
                    {
                        pid_oz.put(x,0);
                    }

                }
                rbm.contrastive_divergence(pid_oz,learning_rate,k);//注意此处
            }
        }
        
        return rbm.W;
        
        
    }
    
    

    public static void main(String[] args)
    {
        double[][] w =train_rbm();
        
    }
    
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
项目完整可用,配合压缩包内数据库可直接运行使用。 eclipse+mysql5.7+jdk1.8 功能:推荐引擎利用特殊的信息过滤(IF,Information Filtering)技术,将不同的内容(例如电影、音乐、书籍、新闻、图片、网页等)推荐给可能感兴趣的用户。通常情况下,推荐引擎的实现是通过将用户的个人喜好与特定的参考特征进行比较,并试图预测用户对一些未评分项目的喜好程度。参考特征的选取可能是从项目本身的信息中提取的,或是基于用户所在的社会或社团环境。 根据如何抽取参考特征,我们可以将推荐引擎分为以下四大类: • 基于内容的推荐引擎:它将计算得到并推荐给用户一些与该用户已选择过的项目相似的内容。例如,当你在网上购书时,你总是购买与历史相关的书籍,那么基于内容的推荐引擎就会给你推荐一些热门的历史方面的书籍。 • 基于协同过滤的推荐引擎:它将推荐给用户一些与该用户品味相似的其他用户喜欢的内容。例如,当你在网上买衣服时,基于协同过滤的推荐引擎会根据你的历史购买记录或是浏览记录,分析出你的穿衣品位,并找到与你品味相似的一些用户,将他们浏览和购买的衣服推荐给你。 • 基于关联规则的推荐引擎:它将推荐给用户一些采用关联规则发现算法计算出的内容。关联规则的发现算法有很多,如 Apriori、AprioriTid、DHP、FP-tree 等。 • 混合推荐引擎:结合以上各种,得到一个更加全面的推荐效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值