基于随机梯度下降的矩阵分解推荐算法(python)


Posted in Python onAugust 31, 2018

SVD是矩阵分解常用的方法,其原理为:矩阵M可以写成矩阵A、B与C相乘得到,而B可以与A或者C合并,就变成了两个元素M1与M2的矩阵相乘可以得到M。

矩阵分解推荐的思想就是基于此,将每个user和item的内在feature构成的矩阵分别表示为M1与M2,则内在feature的乘积得到M;因此我们可以利用已有数据(user对item的打分)通过随机梯度下降的方法计算出现有user和item最可能的feature对应到的M1与M2(相当于得到每个user和每个item的内在属性),这样就可以得到通过feature之间的内积得到user没有打过分的item的分数。

本文所采用的数据是movielens中的数据,且自行切割成了train和test,但是由于数据量较大,没有用到全部数据。

代码如下:

# -*- coding: utf-8 -*-
"""
Created on Mon Oct 9 19:33:00 2017
@author: wjw
"""
import pandas as pd
import numpy as np
import os
 
def difference(left,right,on): #求两个dataframe的差集
 df = pd.merge(left,right,how='left',on=on) #参数on指的是用于连接的列索引名称
 left_columns = left.columns
 col_y = df.columns[-1] # 得到最后一列
 df = df[df[col_y].isnull()]#得到boolean的list
 df = df.iloc[:,0:left_columns.size]#得到的数据里面还有其他同列名的column
 df.columns = left_columns # 重新定义columns
 return df
 
def readfile(filepath): #读取文件,同时得到训练集和测试集
 
 pwd = os.getcwd()#返回当前工程的工作目录
 os.chdir(os.path.dirname(filepath))
 #os.path.dirname()获得filepath文件的目录;chdir()切换到filepath目录下
 initialData = pd.read_csv(os.path.basename(filepath))
 #basename()获取指定目录的相对路径
 os.chdir(pwd)#回到先前工作目录下
 predData = initialData.iloc[:,0:3] #将最后一列数据去掉
 newIndexData = predData.drop_duplicates()
 trainData = newIndexData.sample(axis=0,frac = 0.1) #90%的数据作为训练集
 testData = difference(newIndexData,trainData,['userId','movieId']).sample(axis=0,frac=0.1)
 return trainData,testData
 
def getmodel(train):
 slowRate = 0.99
 preRmse = 10000000.0
 max_iter = 100
 features = 3
 lamda = 0.2
 gama = 0.01 #随机梯度下降中加入,防止更新过度
 user = pd.DataFrame(train.userId.drop_duplicates(),columns=['userId']).reset_index(drop=True) #把在原来dataFrame中的索引重新设置,drop=True并抛弃
 
 movie = pd.DataFrame(train.movieId.drop_duplicates(),columns=['movieId']).reset_index(drop=True)
 userNum = user.count().loc['userId'] #671
 movieNum = movie.count().loc['movieId'] 
 userFeatures = np.random.rand(userNum,features) #构造user和movie的特征向量集合
 movieFeatures = np.random.rand(movieNum,features)
 #假设每个user和每个movie有3个feature
 userFeaturesFrame =user.join(pd.DataFrame(userFeatures,columns = ['f1','f2','f3']))
 movieFeaturesFrame =movie.join(pd.DataFrame(movieFeatures,columns= ['f1','f2','f3']))
 userFeaturesFrame = userFeaturesFrame.set_index('userId')
 movieFeaturesFrame = movieFeaturesFrame.set_index('movieId') #重新设置index
 
 for i in range(max_iter): 
  rmse = 0
  n = 0
  for index,row in user.iterrows():
   uId = row.userId
   userFeature = userFeaturesFrame.loc[uId] #得到userFeatureFrame中对应uId的feature
 
   u_m = train[train['userId'] == uId] #找到在train中userId点评过的movieId的data
   for index,row in u_m.iterrows(): 
    u_mId = int(row.movieId)
    realRating = row.rating
    movieFeature = movieFeaturesFrame.loc[u_mId] 
 
    eui = realRating-np.dot(userFeature,movieFeature)
    rmse += pow(eui,2)
    n += 1
    userFeaturesFrame.loc[uId] += gama * (eui*movieFeature-lamda*userFeature) 
    movieFeaturesFrame.loc[u_mId] += gama*(eui*userFeature-lamda*movieFeature)
  nowRmse = np.sqrt(rmse*1.0/n)
  print('step:%f,rmse:%f'%((i+1),nowRmse))
  if nowRmse<preRmse:
   preRmse = nowRmse
  elif nowRmse<0.5:
   break
  elif nowRmse-preRmse<=0.001:
   break
  gama*=slowRate
 return userFeaturesFrame,movieFeaturesFrame
 
def evaluate(userFeaturesFrame,movieFeaturesFrame,test):
 test['predictRating']='NAN' # 新增一列
 
 for index,row in test.iterrows(): 
  
  print(index)
  userId = row.userId
  movieId = row.movieId
  if userId not in userFeaturesFrame.index or movieId not in movieFeaturesFrame.index:
   continue
  userFeature = userFeaturesFrame.loc[userId]
  movieFeature = movieFeaturesFrame.loc[movieId]
  test.loc[index,'predictRating'] = np.dot(userFeature,movieFeature) #不定位到不能修改值
  
 return test 
 
if __name__ == "__main__":
 filepath = r"E:\学习\研究生\推荐系统\ml-latest-small\ratings.csv"
 train,test = readfile(filepath)
 userFeaturesFrame,movieFeaturesFrame = getmodel(train)
 result = evaluate(userFeaturesFrame,movieFeaturesFrame,test)

在test中得到的结果为:

基于随机梯度下降的矩阵分解推荐算法(python)

NAN则是训练集中没有的数据

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python使用urllib2提交http post请求的方法
May 26 Python
Python八大常见排序算法定义、实现及时间消耗效率分析
Apr 27 Python
Python使用win32 COM实现Excel的写入与保存功能示例
May 03 Python
详解Python最长公共子串和最长公共子序列的实现
Jul 07 Python
Python常用特殊方法实例总结
Mar 22 Python
Python3实现汉语转换为汉语拼音
Jul 08 Python
Python对列表的操作知识点详解
Aug 20 Python
python中必要的名词解释
Nov 20 Python
Python更新所有已安装包的操作
Feb 13 Python
关于python中的xpath解析定位
Mar 06 Python
为什么是 Python -m
Jun 19 Python
聊聊Python pandas 中loc函数的使用,及跟iloc的区别说明
Mar 03 Python
python实现梯度下降算法
Mar 24 #Python
wtfPython—Python中一组有趣微妙的代码【收藏】
Aug 31 #Python
opencv python 图像去噪的实现方法
Aug 31 #Python
python+numpy+matplotalib实现梯度下降法
Aug 31 #Python
python实现随机梯度下降法
Mar 24 #Python
python实现决策树分类(2)
Aug 30 #Python
python实现决策树分类
Aug 30 #Python
You might like
php中static静态变量的使用方法详解
2010/06/04 PHP
腾讯QQ php程序员面试题目整理
2010/06/08 PHP
延长phpmyadmin登录时间的方法
2011/02/06 PHP
关于onScroll事件在IE6下每次滚动触发三次bug说明
2011/09/21 Javascript
jQuery实现的导航条切换可显示隐藏
2014/10/22 Javascript
jQuery带进度条全屏图片轮播特效代码分享
2020/06/28 Javascript
js传值后台中文出现乱码的解决方法
2016/06/30 Javascript
对javascript继承的理解
2016/10/11 Javascript
如何使用Vuex+Vue.js构建单页应用
2016/10/27 Javascript
微信小程序 wxapp内容组件 text详细介绍
2016/10/31 Javascript
基于nodejs 的多页面爬虫实例代码
2017/05/31 NodeJs
第一个Vue插件从封装到发布
2017/11/22 Javascript
使用webpack-dev-server处理跨域请求的方法
2018/04/18 Javascript
taro小程序添加骨架屏的实现代码
2019/11/15 Javascript
jQuery中event.target和this的区别详解
2020/08/13 jQuery
[46:12]完美世界DOTA2联赛循环赛 DM vs Matador BO2第一场 11.04
2020/11/04 DOTA
[09:13]DOTA2-DPC中国联赛 正赛 Ehome vs Magma 选手采访 1月19日
2021/03/11 DOTA
python中日期和时间格式化输出的方法小结
2015/03/19 Python
Python语言实现获取主机名根据端口杀死进程
2016/03/31 Python
详解python的几种标准输出重定向方式
2016/08/15 Python
django 发送手机验证码的示例代码
2018/04/25 Python
python线程池threadpool使用篇
2018/04/27 Python
python实现文件助手中查看微信撤回消息
2019/04/29 Python
Python编程实现tail-n查看日志文件的方法
2019/07/08 Python
Python倒排索引之查找包含某主题或单词的文件
2019/11/13 Python
python实现npy格式文件转换为txt文件操作
2020/07/01 Python
python 星号(*)的多种用途
2020/09/21 Python
Html5实现首页动态视频背景的示例代码
2019/09/25 HTML / CSS
中国医药集团国药在线:国药网
2017/02/06 全球购物
naturalizer加拿大官网:美国娜然女鞋
2017/04/04 全球购物
介绍Ibatis的核心类
2013/11/18 面试题
实现向右循环移位
2014/07/31 面试题
小学生竞选班干部演讲稿
2014/04/24 职场文书
主题实践活动总结
2014/05/08 职场文书
团组织推荐意见
2015/06/05 职场文书
安全事故隐患排查治理制度
2015/08/05 职场文书