因前一篇https://blog.csdn.net/fjssharpsword/article/details/97000479采样问题未解决,发现如下github上有BPMF代码,采用wishart先验,性能和pymc3一致。

参考:https://github.com/LoryPack/BPMF

# coding:utf-8
'''
@author: Jason.F
@data: 2019.08.01
@function: baseline BPMF(Bayesian Probabilistic Matrix Factorization)Datatset: MovieLens-1m:https://grouplens.org/datasets/movielens/  Evaluation: RMSE
'''import numpy as np
import random
import pandas as pd
from numpy.random import multivariate_normal
from scipy.stats import wishartclass DataSet:def __init__(self):self.trainset, self.testset, self.maxu, self.maxi, self.maxr = self._getDataset_as_list()def _getDataset_as_list(self):#trainsetfilePath = "/data/fjsdata/BMF/ml-1m.train.rating" data = pd.read_csv(filePath, sep='\t', header=None, names=['user', 'item', 'rating'], \usecols=[0, 1, 2], dtype={0: np.int32, 1: np.int32, 2: np.float})maxu, maxi, maxr = data['user'].max()+1, data['item'].max()+1, data['rating'].max()print('Dataset Statistics: Interaction = %d, User = %d, Item = %d, Sparsity = %.4f' % \(data.shape[0], maxu, maxi, data.shape[0]/(maxu*maxi)))trainset = data.values.tolist()#testsetfilePath = "/data/fjsdata/BMF/ml-1m.test.rating" data = pd.read_csv(filePath, sep='\t', header=None, names=['user', 'item', 'rating'], \usecols=[0, 1, 2], dtype={0: np.int32, 1: np.int32, 2: np.float})testset = data.values.tolist()return trainset, testset, maxu, maxi, maxr def list_to_matrix(self, dataset, maxu, maxi):              dataMat = np.zeros([maxu, maxi], dtype=np.float32)for u,i,r in dataset:dataMat[int(u)][int(i)] = float(r)return np.array(dataMat)def Normal_Wishart(mu_0, lamb, W, nu, seed=None):"""Function extracting a Normal_Wishart random variable"""# first draw a Wishart distribution:Lambda = wishart(df=nu, scale=W, seed=seed).rvs()  # NB: Lambda is a matrix.# then draw a Gaussian multivariate RV with mean mu_0 and(lambda*Lambda)^{-1} as covariance matrix.cov = np.linalg.inv(lamb * Lambda)  # this is the bottleneck!!mu = multivariate_normal(mu_0, cov)return mu, Lambda, covdef BPMF(R, R_test, U_in, V_in, T, D, initial_cutoff, lowest_rating, highest_rating,mu_0=None, Beta_0=None, W_0=None, nu_0=None):"""R is the ranking matrix (NxM, N=#users, M=#movies); we are assuming that R[i,j]=0 means that user i has not ranked movie jR_test is the ranking matrix that contains test values. Same assumption as above. U_in, V_in are the initial values for the MCMC procedure. T is the number of steps. D is the number of hidden features that are assumed in the model.    mu_0 is the average vector used in sampling the multivariate normal variableBeta_0 is a coefficient (?)W_0 is the DxD scale matrix in the Wishart sampling nu_0 is the number of degrees of freedom used in the Wishart sampling. U matrices are DxN, while V matrices are DxM."""def ranked(i, j):  # function telling if user i ranked movie j in the train dataset.if R[i, j] != 0:return Trueelse:return Falsedef ranked_test(i, j):  # function telling if user i ranked movie j in the test dataset.if R_test[i, j] != 0:return Trueelse:return FalseN = R.shape[0]M = R.shape[1]R_predict = np.zeros((N, M))U_old = np.array(U_in)V_old = np.array(V_in)train_err_list = []test_err_list = []train_epoch_list = []# initialize now the hierarchical priors:alpha = 2  # observation noise, they put it = 2 in the papermu_u = np.zeros((D, 1))mu_v = np.zeros((D, 1))Lambda_U = np.eye(D)Lambda_V = np.eye(D)# COUNT HOW MAY PAIRS ARE IN THE TEST AND TRAIN SET:pairs_test = 0pairs_train = 0for i in range(N):for j in range(M):if ranked(i, j):pairs_train = pairs_train + 1if ranked_test(i, j):pairs_test = pairs_test + 1# print(pairs_test, pairs_train)# SET THE DEFAULT VALUES for Wishart distribution# we assume that parameters for both U and V are the same.if mu_0 is None:mu_0 = np.zeros(D)if nu_0 is None:nu_0 = Dif Beta_0 is None:Beta_0 = 2if W_0 is None:W_0 = np.eye(D)# results = pd.DataFrame(columns=['step', 'train_err', 'test_err'])for t in range(T):# print("Step ", t)# FIRST SAMPLE THE HYPERPARAMETERS, conditioned on the present step user and movie feature matrices U_t and V_t:# parameters common to both distributions:Beta_0_star = Beta_0 + Nnu_0_star = nu_0 + NW_0_inv = np.linalg.inv(W_0)  # compute the inverse once and for all# movie hyperparameters:V_average = np.sum(V_old, axis=1) / N  # in this way it is a 1d array!!# print (V_average.shape)S_bar_V = np.dot(V_old, np.transpose(V_old)) / N  # CHECK IF THIS IS RIGHT!mu_0_star_V = (Beta_0 * mu_0 + N * V_average) / (Beta_0 + N)W_0_star_V_inv = W_0_inv + N * S_bar_V + Beta_0 * N / (Beta_0 + N) * np.dot(np.transpose(np.array(mu_0 - V_average, ndmin=2)), np.array((mu_0 - V_average), ndmin=2))W_0_star_V = np.linalg.inv(W_0_star_V_inv)mu_V, Lambda_V, cov_V = Normal_Wishart(mu_0_star_V, Beta_0_star, W_0_star_V, nu_0_star, seed=None)# user hyperparameters# U_average=np.transpose(np.array(np.sum(U_old, axis=1)/N, ndmin=2)) #the np.array and np.transpose are needed for it to be a column vectorU_average = np.sum(U_old, axis=1) / N  # in this way it is a 1d array!!  #D-long# print (U_average.shape)S_bar_U = np.dot(U_old, np.transpose(U_old)) / N  # CHECK IF THIS IS RIGHT! #it is DxDmu_0_star_U = (Beta_0 * mu_0 + N * U_average) / (Beta_0 + N)W_0_star_U_inv = W_0_inv + N * S_bar_U + Beta_0 * N / (Beta_0 + N) * np.dot(np.transpose(np.array(mu_0 - U_average, ndmin=2)), np.array((mu_0 - U_average), ndmin=2))W_0_star_U = np.linalg.inv(W_0_star_U_inv)mu_U, Lambda_U, cov_U = Normal_Wishart(mu_0_star_U, Beta_0_star, W_0_star_U, nu_0_star, seed=None)# print (S_bar_U.shape, S_bar_V.shape)# print (np.dot(np.transpose(np.array(mu_0-U_average, ndmin=2)),np.array((mu_0-U_average), ndmin=2).shape))# UP TO HERE IT PROBABLY WORKS, FROM HERE ON IT HAS TO BE CHECKED!!!"""SAMPLE THEN USER FEATURES (possibly in parallel):"""U_new = np.array([])  # define the new stuff.V_new = np.array([])for i in range(N):  # loop over the users# first compute the parameters of the distributionLambda_U_2 = np.zeros((D, D))  # second term in the construction of Lambda_Umu_i_star_1 = np.zeros(D)  # first piece of mu_i_starfor j in range(M):  # loop over the moviesif ranked(i, j):  # only if movie j has been ranked by user i!Lambda_U_2 = Lambda_U_2 + np.dot(np.transpose(np.array(V_old[:, j], ndmin=2)),np.array((V_old[:, j]), ndmin=2))  # CHECKmu_i_star_1 = V_old[:, j] * R[i, j] + mu_i_star_1  # CHECK DIMENSIONALITY!!!!!!!!!!!!# coeff=np.transpose(np.array(V_old[j]*R[i,j], ndmin=2))+coeff  #CHECK DIMENSIONALITY!!!!!!!!!!!!Lambda_i_star_U = Lambda_U + alpha * Lambda_U_2Lambda_i_star_U_inv = np.linalg.inv(Lambda_i_star_U)mu_i_star_part = alpha * mu_i_star_1 + np.dot(Lambda_U,mu_U)  ###CAREFUL!! Multiplication matrix times a row vector!! It should give as an output a row vector as for how it worksmu_i_star = np.dot(Lambda_i_star_U_inv, mu_i_star_part)# extract now the U values!U_new = np.append(U_new, multivariate_normal(mu_i_star, Lambda_i_star_U_inv))# you need to reshape U_new and transpose it!!U_new = np.transpose(np.reshape(U_new, (N, D)))# print (U_new.shape)"""SAMPLE THEN MOVIE FEATURES (possibly in parallel):"""for j in range(M):Lambda_V_2 = np.zeros((D, D))  # second term in the construction of Lambda_Umu_i_star_1 = np.zeros(D)  # first piece of mu_i_starfor i in range(N):  # loop over the moviesif ranked(i, j):Lambda_V_2 = Lambda_V_2 + np.dot(np.transpose(np.array(U_new[:, i], ndmin=2)),np.array((U_new[:, i]), ndmin=2))mu_i_star_1 = U_new[:, i] * R[i, j] + mu_i_star_1  # CHECK DIMENSIONALITY!!!!!!!!!!!!# coeff=np.transpose(np.array(V_old[j]*R[i,j], ndmin=2))+coeff  #CHECK DIMENSIONALITY!!!!!!!!!!!!Lambda_j_star_V = Lambda_V + alpha * Lambda_V_2Lambda_j_star_V_inv = np.linalg.inv(Lambda_j_star_V)mu_i_star_part = alpha * mu_i_star_1 + np.dot(Lambda_V, mu_V)mu_j_star = np.dot(Lambda_j_star_V_inv, mu_i_star_part)V_new = np.append(V_new, multivariate_normal(mu_j_star, Lambda_j_star_V_inv))# you need to reshape U_new and transpose it!!V_new = np.transpose(np.reshape(V_new, (M, D)))# save U_new and V_new in U_old and V_old for next iteration:         U_old = np.array(U_new)V_old = np.array(V_new)if t > initial_cutoff:  # initial_cutoff is needed to discard the initial transientR_step = np.dot(np.transpose(U_new), V_new)for i in range(N):  # reduce all the predictions to the correct ratings range.for j in range(M):if R_step[i, j] > highest_rating:R_step[i, j] = highest_ratingelif R_step[i, j] < lowest_rating:R_step[i, j] = lowest_ratingR_predict = (R_predict * (t - initial_cutoff - 1) + R_step) / (t - initial_cutoff)train_err = 0  # initialize the errors.test_err = 0# compute now the RMSE on the train dataset:for i in range(N):for j in range(M):if ranked(i, j):train_err = train_err + (R_predict[i, j] - R[i, j]) ** 2train_err_list.append(np.sqrt(train_err / pairs_train))print("Training RMSE at iteration ", t - initial_cutoff, " :   ", "{:.4}".format(train_err_list[-1]))# compute now the RMSE on the test dataset:for i in range(N):for j in range(M):if ranked_test(i, j):test_err = test_err + (R_predict[i, j] - R_test[i, j]) ** 2test_err_list.append(np.sqrt(test_err / pairs_test))print("Test RMSE at iteration ", t - initial_cutoff, " :   ", "{:.4}".format(test_err_list[-1]))return R_predictif __name__ == "__main__":ds = DataSet()#loading dataset\R = ds.list_to_matrix(ds.trainset, ds.maxu, ds.maxi)#get matrixR_test = ds.list_to_matrix(ds.testset, ds.maxu, ds.maxi)#get matrixfor K in [8, 16, 32, 64]:U_in = np.zeros((K, ds.maxu))  V_in = np.zeros((K, ds.maxi))R_pred = BPMF(R, R_test, U_in, V_in, T=100, D=K, initial_cutoff=0, lowest_rating=0, highest_rating=ds.maxr)squaredError = []for u,i,r in ds.testset:error=r - nR[int(u)][int(i)]squaredError.append(error * error)rmse =math.sqrt(sum(squaredError) / len(squaredError))print("RMSE@{}:{}".format(K, rmse))

推荐经典算法实现之BPMF(python+MovieLen)相关推荐

  1. 推荐经典算法实现之BPMF(pymc3+MovieLen)

    BPMF是用贝叶斯推断方法求解MF的概率模型,参考:https://gist.github.com/macks22/00a17b1d374dfc267a9a 1.利用其本身数据集的代码如下: # -* ...

  2. 机器学习经典算法具体解释及Python实现--K近邻(KNN)算法

    (一)KNN依旧是一种监督学习算法 KNN(K Nearest Neighbors,K近邻 )算法是机器学习全部算法中理论最简单.最好理解的.KNN是一种基于实例的学习,通过计算新数据与训练数据特征值 ...

  3. 经典算法 之 折半查找 python实现

    ​ ​ 活动地址:CSDN21天学习挑战赛 折半查找 1.查找算法 基本概念 不同查找算法分类 2. 折半查找 伪代码 算法评价 3. 算法实践(Python) 折半查找 参考 1.查找算法 查找(S ...

  4. 机器学习经典算法详解及Python实现--元算法、AdaBoost

    http://blog.csdn.net/suipingsp/article/details/41822313 第一节,元算法略述 遇到罕见病例时,医院会组织专家团进行临床会诊共同分析病例以判定结果. ...

  5. 经典算法详解--CART分类决策树、回归树和模型树

    Classification And Regression Tree(CART)是一种很重要的机器学习算法,既可以用于创建分类树(Classification Tree),也可以用于创建回归树(Reg ...

  6. 经典算法书籍推荐以及算法书排行【算法四库全书】

    经典算法书籍推荐以及算法书排行[算法四库全书] 作者:霞落满天   https://linuxstyle.blog.csdn.net/    https://blog.csdn.net/21aspne ...

  7. python经典好书-推荐几本高质量的Python书籍--附github下载路径

    一 为什么要分享? 最近碰到了一些人和事,感触挺大的.就是发现很多类似自己的软件工程师,一旦工作三五年之后,工作中算是一个熟练工,但是进步的脚步突然慢了下来,虽然你在工作中仍旧很努力.到底是什么原因呢 ...

  8. python 笔试题 英方_经典算法题 :找字符串中的逆序对(百度笔试题)

    脚本之家 你与百万开发者在一起 来自:百度研发工程师2015深圳笔试卷 编程题:给定一个文件每一行是字符串,找出所有的逆序对,比如abc和cba是逆序的对. 小贴士:返回上一级搜索"算法题& ...

  9. 【Python】学习笔记总结8(经典算法)

    文章目录 八.Python经典算法 0.Python画图 1.回归-线性回归 2.分类-k最近邻 3.聚类 3.1.Kmeans(k均值聚类算法) 3.2.DBSCAN(基于密度的聚类算法) 3.3. ...

最新文章

  1. pytorch loss function 总结
  2. 深度linux安装双,Deepin 20正式发布,新的外观和感觉,双内核安装
  3. BZOJ3916 [Baltic2014]friends
  4. synchronized细节问题
  5. UEFI Shell 常用命令
  6. 在MapPath的Path参数中不允许字符'..',解决方法。
  7. 因果关系和相关关系 大数据_数据科学中的相关性与因果关系
  8. zoj1738 Lagrange's Four-Square Theorem(DP)
  9. 安徽对口计算机本科分数线,考试查询网:安徽对口高考录取分数线
  10. PHP连接mysql8.0出错“SQLSTATE[HY000] [2054] The server requested authentication method unknow........
  11. MySQL中table_schema的基本操作
  12. javascript 弹出窗口中是否显示地址栏
  13. presentation健身主题HTML,如何用英文做presentation
  14. For ‘mall-coupon‘ URL not provided. Will try picking an instance via load-balancing. org.springfram
  15. 如何让不给听得ge乖乖听话?python教你如何做...
  16. C#读取txt 乱码问题的解决方案
  17. 历年阿里面试题汇总(2017年不断更新中)
  18. 【摸鱼神器】UCode Cms管理系统 内置超好用的代码生成器 解决多表连接痛点
  19. C语言 谭浩强 题目 -第八章
  20. Android-Rxjava 常用操作符

热门文章

  1. miui 8.5 android,小米MIUI 8.5稳定版更新来了:直达服务功能秒开应用
  2. mysql级联查询_mysql 各种级联查询后更新(update select)
  3. 软考高项之进度管理——攻坚记忆
  4. 基于Spark MLlib平台的协同过滤算法---电影推荐系统
  5. [codeforces 508E]Maximum Matching
  6. BZOJ 2244: [SDOI2011]拦截导弹 DP+CDQ分治
  7. Linux下使用curl进行http请求(转)
  8. Minimum Path Sum,最短路径问题,动态规划
  9. java.lang.OutOfMemoryError处理错误
  10. 【Android 界面效果9】9patch图片