zoukankan      html  css  js  c++  java
  • 尝试神经网络用于电影评分

    在之前的随笔《非对称SVD电影推荐系统》中应用SVD,得到还不错的结果。

    此次尝试将BP神经网络应用于预测用户评分,由于同类用户不同电影评分差异巨大,神经网络输出神经元不易设置。

    仅取movie id=0 的用户作为测试数据(350 条记录),这样只需要5个输出神经元。movie id 共有三千多个,训练会比较慢,检测依然可以很快。

    得到的最佳rmse=0.588,预测(左)和实际试评分(右)如下(评分已减1)。单独这个电影,用户实际评分比较接近。

    [(3, 3.0), (3, 4.0), (3, 3.0), (3, 4.0), (4, 3.0), (3, 4.0), (3, 3.0), (4, 4.0), (3, 4.0), (3, 4.0), (4, 3.0), (3, 3.0), (3, 4.0), (3, 3.0), (4, 4.0), (3, 3.0), (3, 3.0), (3, 2.0), (3, 3.0), (4, 4.0), (4, 4.0), (4, 4.0), (4, 4.0), (3, 4.0), (3, 3.0), (4, 4.0), (3, 2.0), (3, 4.0), (3, 4.0), (3, 3.0), (3, 4.0), (3, 3.0), (3, 4.0), (3, 0.0), (3, 2.0), (3, 4.0), (3, 3.0), (3, 4.0), (3, 3.0), (3, 2.0), (3, 4.0), (3, 3.0), (4, 4.0), (4, 4.0), (4, 3.0), (4, 4.0), (3, 4.0), (3, 3.0), (4, 3.0), (3, 2.0), (3, 4.0), (4, 3.0), (3, 4.0), (3, 3.0), (4, 3.0), (3, 3.0), (3, 3.0), (4, 3.0), (4, 4.0), (3, 4.0), (4, 3.0), (4, 4.0), (4, 2.0), (3, 3.0), (4, 3.0), (3, 4.0), (3, 3.0), (3, 2.0), (4, 4.0), (4, 4.0), (3, 2.0), (4, 4.0), (3, 2.0), (3, 4.0), (3, 4.0), (2, 4.0), (3, 4.0), (3, 4.0), (3, 1.0), (4, 4.0), (3, 4.0), (3, 3.0), (3, 4.0), (3, 3.0), (4, 3.0), (3, 0.0), (3, 2.0), (3, 2.0), (3, 4.0), (3, 3.0), (4, 3.0), (3, 4.0), (3, 4.0), (4, 4.0), (3, 3.0), (3, 2.0), (3, 4.0), (3, 3.0), (3, 3.0), (3, 3.0), (4, 2.0), (3, 3.0), (3, 2.0), (3, 3.0), (3, 4.0), (3, 3.0), (4, 4.0), (3, 4.0), (3, 1.0), (4, 4.0), (3, 4.0), (3, 4.0), (4, 4.0), (3, 3.0), (3, 1.0), (4, 3.0), (4, 4.0), (3, 1.0), (3, 4.0), (3, 4.0), (3, 4.0), (4, 4.0), (4, 4.0), (3, 2.0), (3, 3.0), (3, 2.0), (3, 3.0), (3, 2.0), (3, 3.0), (3, 3.0), (3, 3.0), (3, 3.0), (4, 3.0), (3, 4.0), (4, 4.0), (3, 3.0), (3, 2.0), (4, 3.0), (4, 3.0), (4, 3.0), (3, 4.0), (3, 4.0), (3, 2.0), (3, 3.0), (4, 4.0), (4, 2.0), (3, 4.0), (4, 3.0), (3, 4.0), (4, 3.0), (4, 3.0), (3, 2.0), (3, 1.0), (3, 3.0), (3, 3.0), (4, 3.0), (3, 4.0), (3, 1.0), (4, 4.0), (3, 3.0), (4, 2.0), (3, 2.0), (3, 3.0), (3, 4.0), (4, 2.0), (4, 4.0), (3, 3.0), (3, 3.0), (3, 1.0), (3, 4.0), (4, 3.0), (3, 3.0), (4, 3.0), (3, 2.0), (3, 4.0), (4, 4.0), (3, 3.0), (3, 3.0), (3, 2.0), (4, 4.0), (4, 4.0), (3, 1.0), (3, 2.0), (3, 2.0), (3, 4.0), (4, 3.0), (4, 3.0), (3, 3.0), (4, 4.0), (3, 3.0), (3, 3.0), (4, 4.0), (3, 4.0), (4, 4.0), (4, 3.0), (3, 4.0), (3, 3.0), (3, 3.0), (3, 4.0), (3, 4.0), (4, 4.0), (4, 4.0), (3, 3.0), (3, 2.0), (3, 4.0), (3, 3.0), (3, 2.0), (3, 1.0), (4, 4.0), (4, 4.0), (3, 3.0), (3, 3.0), (3, 4.0), (3, 4.0), (4, 4.0), (3, 3.0), (4, 3.0), (3, 4.0), (4, 4.0), (3, 3.0), (3, 4.0), (3, 4.0), (3, 3.0), (3, 4.0), (4, 3.0), (3, 3.0), (4, 3.0), (4, 3.0), (3, 3.0), (4, 2.0), (2, 3.0), (3, 4.0), (4, 4.0), (3, 4.0), (3, 1.0), (4, 4.0), (3, 3.0), (4, 3.0), (3, 4.0), (3, 2.0), (3, 2.0), (4, 3.0), (3, 4.0), (3, 4.0), (3, 4.0), (4, 3.0), (4, 2.0), (3, 3.0), (3, 4.0), (3, 4.0), (3, 2.0), (3, 2.0), (3, 3.0), (3, 3.0), (3, 4.0), (3, 3.0), (3, 4.0), (4, 4.0), (4, 2.0), (4, 3.0), (3, 3.0), (3, 3.0), (3, 3.0), (4, 4.0), (3, 3.0), (3, 4.0), (4, 3.0), (4, 3.0), (3, 2.0), (3, 4.0), (4, 3.0), (4, 0.0), (3, 3.0), (4, 3.0), (3, 4.0), (3, 2.0), (3, 4.0), (4, 3.0), (4, 2.0), (3, 4.0), (3, 2.0), (3, 4.0), (3, 3.0), (3, 4.0), (3, 2.0), (3, 3.0), (3, 2.0), (3, 0.0), (3, 3.0), (4, 3.0), (3, 3.0), (3, 4.0), (3, 4.0), (3, 3.0), (3, 4.0), (3, 3.0), (3, 3.0), (4, 4.0), (3, 4.0), (3, 3.0), (3, 2.0), (4, 3.0), (3, 4.0), (3, 4.0), (3, 1.0), (4, 4.0), (3, 4.0), (3, 4.0), (3, 1.0), (3, 2.0), (4, 4.0), (3, 2.0), (3, 4.0), (3, 3.0), (3, 4.0), (4, 3.0), (4, 4.0), (3, 3.0), (3, 2.0), (4, 2.0), (3, 2.0), (3, 0.0), (3, 4.0), (3, 3.0), (3, 3.0), (4, 4.0), (3, 4.0), (3, 3.0), (3, 4.0), (3, 4.0), (3, 0.0), (3, 2.0), (3, 3.0), (4, 3.0), (4, 4.0), (3, 4.0), (4, 3.0), (3, 3.0), (3, 2.0), (3, 4.0), (4, 4.0), (3, 3.0), (3, 0.0), (4, 4.0), (3, 3.0), (3, 2.0), (3, 2.0), (4, 4.0), (4, 4.0), (3, 4.0)]

      1 # coding:utf8
      2 import cPickle
      3 import numpy as np
      4 
      5 
      6 class Network(object):
      7     def __init__(self, sizes):
      8         self.num_layers = len(sizes)
      9         self.sizes = sizes
     10         self.biases = [np.random.randn(y, 1) for y in sizes[1:]]  # L(n-1)->L(n)
     11         self.weights = [np.random.randn(y, x)
     12                         for x, y in zip(sizes[:-1], sizes[1:])]
     13 
     14     def feedforward(self, a):
     15         for b_, w_ in zip(self.biases, self.weights):
     16             a = self.sigmoid(np.dot(w_, a)+b_)
     17         return a
     18 
     19     def SGD(self, training_data, test_data,epochs, mini_batch_size, eta=1.0):
     20         n_test = len(test_data)
     21         n = len(training_data)
     22         for j in xrange(epochs):
     23             np.random.shuffle(training_data)  # shuffle
     24             for k in xrange(0, n, mini_batch_size):
     25                 mini_batch = training_data[k:k+mini_batch_size]
     26                 self.update_mini_batch(mini_batch, eta)
     27             rmse=np.sqrt(self.evaluate(test_data)/1000.0)
     28             print "Epoch {0}: {1} / {2}".format(
     29                     j, rmse, n_test)
     30 
     31     def update_mini_batch(self, mini_batch, eta):
     32         for x, y in mini_batch:
     33             delta_b, delta_w = self.backprop(x, y)
     34             self.weights -= eta/len(mini_batch)*delta_w
     35             self.biases -= eta/len(mini_batch)*delta_b
     36 
     37     def backprop(self, x, y):
     38         b=np.zeros_like(self.biases)
     39         w=np.zeros_like(self.weights)
     40         a_ = x
     41         a = [x]
     42         for b_, w_ in zip(self.biases, self.weights):
     43             a_ = self.sigmoid(np.dot(w_, a_)+b_)
     44             a.append(a_)
     45         for l in xrange(1, self.num_layers):
     46             if l==1:
     47                 delta= self.sigmoid_prime(a[-1])*(a[-1]-y)  # O(k)=a[-1], t(k)=y
     48             else:
     49                 sp = self.sigmoid_prime(a[-l])   # O(j)=a[-l]
     50                 delta = np.dot(self.weights[-l+1].T, delta) * sp
     51             b[-l] = delta
     52             w[-l] = np.dot(delta, a[-l-1].T)
     53         return (b, w)
     54 
     55     def evaluate(self, test_data):
     56         test_results = [(np.argmax(self.feedforward(x)), y)
     57                         for (x, y) in test_data]
     58         print test_results
     59         return sum((x- y)**2 for (x, y) in test_results)
     60 
     61     def sigmoid(self,z):
     62         return 1.0/(1.0+np.exp(-z))
     63 
     64     def sigmoid_prime(self,z):
     65         return z*(1-z)
     66 
     67 if __name__ == '__main__':
     68 
     69     def get_label(i):
     70         c=np.zeros((5,1))
     71         c[i]=1
     72         return c
     73 
     74     fi=open('test.dat','r')
     75     tt_data=[[int(line.split('::')[0])-1,int(line.split('::')[1])-1,float(line.split('::')[2])] for line in fi]
     76     tt_data.sort(key=lambda x:x[1])
     77     t_data= tt_data[:350]  # movie id=0
     78     fi.close()
     79 
     80     fi=open('train.dat','r')
     81     data=np.zeros((6040,3952))
     82     for line in fi:
     83         content=line.split('::')
     84         user=int(content[0])-1
     85         item=int(content[1])-1
     86         rating=float(content[2])
     87         data[user][item]=rating
     88     fi.close()
     89 
     90     train_data=[]
     91     for a in data:
     92         if a[0]>0:
     93             label=int(a[0]-1)
     94             a[0]=0
     95             train_data.append([np.reshape(a,(3952,1)),get_label(label)])
     96     test_data=[]
     97     for t in t_data:
     98         label=t[2]-1
     99         test_data.append([np.reshape(data[t[0]],(3952,1)),label])
    100 
    101     net = Network([3952, 30, 5])
    102     net.SGD(train_data,test_data,10,10,3.0)  # 0.588
  • 相关阅读:
    iOS数据持久化的方式
    Runtime
    <02>
    <01>
    <02>
    UIActivityIndicatorView
    <01>数据存储
    UI<10>
    UI<09>
    UI<08>
  • 原文地址:https://www.cnblogs.com/qw12/p/6105301.html
Copyright © 2011-2022 走看看