理解梯度下降,随机梯度下降,附电影推荐系统的简单代码小样 1.
来源:互联网 发布:布哈里圣训软件 编辑:程序博客网 时间:2024/05/12 04:40
白话梯度下降:
梯度下降的官方概念网上有很多,说了也没用,反正我刚学的时候是没太看懂。
需要的背景知识,偏导率(很重要)
两个坐标点的距离,是两个向量的点乘积
以实际问题为例,一个电影推荐系统,向量v(v1,v2)代表这个电影本应存在的位置,用户向量u(u1,u2)代表用户存在的位置,现在有实际数据是每个电影的网站评分,和一些用户对某些电影的评分,去评估每个电影应该存在的位置以及每个用户应该存在的位置。
用梯度下降的方法就是,首先得出一个目标方程,这里的目标方程我们选择的是误差方程,所以如下图:
目标方程中 s-ij 代表 0 或者 1, 如果第i个用户对第j个电影有评分,则是1,如果这个用户没有评价这个电影则为0(因为不可能每个用户对所有的电影都有评分,所以这个coefficient 是调整矩阵值的。
图片中的最后一个公式就是对u求的偏导,以下的代码都是根据这个公式展开的。
这里用到梯度下降的原理就是,这个偏导数是现有值对真实值的方向指向,因为方程是根据误差方程得出来的,所以每次用这个偏导值 * 学习速率,就可以使得这个点在固定的步长下,一步一步的逼近正确的值。(在计算过程中,除了电影本身评分和用户的打分 这些观测值不变之外,其他的数值在每一次迭代的时候都是会更新的。
而对v求偏导的结果,和对u的偏导差不多,过程也是假设除v外其他的值都是常量,然后求v的导数。
null——————这部分是数据处理,老师给的代码,就不贴了。
数据处理完成之后,我们需要把数据读取出来:import pandas as pd
import os
movies = pd.read_csv(os.path.join('/Users/zhoumeng/Documents/Sheffield/machine learning/mlai17/labs/class_movie', 'movies.csv'),encoding='latin-1').set_index('index')
user_names = list(set(movies.columns)-set(movies.columns[:9]))
Y = pd.melt(movies.reset_index(), id_vars=['Film', 'index'], var_name='user', value_name='rating', value_vars=user_names)
Y = Y.dropna(axis=0)
我们可以看一下原始数据的样子:
Film index user rating
下面我们随机生成两个二维数组 分别是用户和电影的预测值,然后通过不断迭代找到他们的值应该存在的位置:
U = pd.DataFrame(np.random.normal(size=(len(user_names), 2))*0.001, index=user_names)
V = pd.DataFrame(np.random.normal(size=(len(movies.index), 2))*0.001, index=movies.index)
将原始数组的评分减去他们的均值:#在我看来 这样做,高于均值的rating为正,低于它的为负,计算的时候自带符号
Y['rating'] -= Y['rating'].mean()
下面就开始描述如何用代码表达梯度下降了:
def objective_gradient(Y, U, V):
gU = pd.DataFrame(np.zeros((U.shape)), index=U.index)
gV = pd.DataFrame(np.zeros((V.shape)), index=V.index)
obj = 0.
for ind, series in Y.iterrows():
film = series['index']
user = series['user']
rating = series['rating']
prediction = np.dot(U.loc[user], V.loc[film]) # u^T v
diff = prediction - rating # u^T v - y
obj += diff*diff
gU.loc[user] += 2*diff*V.loc[film]##??????
gV.loc[film] += 2*diff*U.loc[user]
return obj, gU, gV
定义了一个随机梯度下降的方法,用pd数组的series将所有数据都迭代一遍,因为一个用户可能评论多个电影,不同用户评论的次数也有所不同,这里将所有次数全部迭代进去的意义在于,评论次数多的用户,我们默认他活跃,所以斜率比重占得高。
接下来是梯度下降的迭代:
learn_rate = 0.01
iterations = 100
for i in range(iterations):
obj, gU, gV = objective_gradient(Y, U, V)
print("iteration", i+1, " objective function:", obj)
U -= learn_rate*gU
V -= learn_rate*gV
uv被不断修正,整体误差稳定在两位数。
下面是自己探索的一个随机梯度下降:
def stochastic_descent(Y,U,V):
gU = pd.DataFrame(np.zeros((U.shape)), index=U.index)
gV = pd.DataFrame(np.zeros((V.shape)), index=V.index)
#get a random name
names = np.array(list(set(np.array(Y.user))))
random_name = names[np.random.randint(names.shape[0]-1)]
#get films rated by this user
films = Y[Y.user==random_name]
for ind, serise in films.iterrows():#using index to represent the film, because one user are connected to more than one film
rating = serise.rating
pre = np.dot(U_new.loc[random_name], V_new.loc[serise['index']])
diff = pre - rating
gU.loc[random_name] += 2*diff*V.loc[serise['index']]
gV.loc[serise['index']] += 2*U.loc[random_name]
return gU, gV
主要思想是取用户,然后更新这个用户以及该用户评论的电影们,但是效果不太理想,可能是我的想法有问题,希望大神们给我评论指出。
这里是我不断修改learning_rate 以及iterations 得到的不同结果:
learn_rate = 0.01 #0.01 3700 384.~~~ # 0.03 848 404.~~ #0.05 411 428.~~~ #0.1 335 416.~~~ #0.005 6500 385.~~
# 0.015 2180 393.~~ # 0.013 2553 389.~~ #0.11 3331 384.~~ # 0.009 3936 385.~~ #0.001 35507 385.~~
# 0.005 40000 386.~~# 0.8 56 474.~~
算上没写的,总过得迭代了超过十万次,也找不到一个很好的rate使得整个误差方程收敛,所以,很无力。。。
- 理解梯度下降,随机梯度下降,附电影推荐系统的简单代码小样 1.
- 理解梯度下降,随机梯度下降,附电影推荐系统的简单代码小样 2
- 梯度下降法和随机梯度下降法的理解
- 随机梯度下降和批量梯度下降的简单代码实现
- 随机梯度下降中,momentum的理解
- 随机梯度下降的momentum 理解
- 梯度下降的理解
- 三种梯度下降的方式:批量梯度下降、小批量梯度下降、随机梯度下降
- 【stanford】梯度、梯度下降,随机梯度下降
- 梯度、梯度下降,随机梯度下降
- 梯度、梯度下降,随机梯度下降
- 梯度、梯度下降,随机梯度下降
- 梯度、梯度下降,随机梯度下降
- 随机梯度下降法求解SVM(附matlab代码)
- 对梯度下降的简单理解
- 对梯度下降法的简单理解
- 对梯度下降法的简单理解
- 梯度下降法的简单理解
- HDU 2665 Kth number 可持久化线段树
- 激光物理学第一次作业
- 顺序表——基本概念、顺序表类实现、基本操作
- hdu2089 不要62和4
- 常见排序算法
- 理解梯度下降,随机梯度下降,附电影推荐系统的简单代码小样 1.
- C语言学习
- tomcat-------------tomcat文件结构及简介
- Django model字段类型清单
- Python3的基本语法学习(一)
- Docker's 学习资料
- 今天发现的一个有用的爬虫视频,对静态网页爬取整体关系有很好的讲解
- Kali Linux安装中文输入法全纪录
- c++DLL编程详解