tensorflow怎麼作個性推薦?

個性推薦算法說的不少了,經常使用的模型是:html

U*V= Q算法

其中Q是評分表,通常共3列:用戶id,物品id,評分值數組

U是用戶特徵表,V是物品特徵表。框架

算法的最終目標就是從Q算出U和V。那麼Spark Mllib裏有ALS算法能夠作矩陣分解,其基本原理是最小交叉二乘法,用到了Breeze庫的矩陣函數庫。所謂交叉二乘就是輪流固定U或V,來算出V或U。好比第一輪固定U,來算出V,第二輪固定算出的V,來算出U。直到最後偏差收斂。dom

Spark裏主要是用RDD框架來對數據分塊計算,達到並行的特色。函數

而Tensorflow裏用深度學習的方法來實現矩陣分解就更簡便了,其基本原理是根據U*V和Q的差值來自動優化,深度學習的特色就是隻要你搭建好了學習模型,那麼只要自動訓練就能夠找到最優解,所以實現起來也很方便。學習

TensorFlow的代碼能夠參考以下。優化

一、收集原始數據scala

import pandas as pd
import numpy as np
import tensorflow as tf
 
# 第一步:------------------------收集和清洗數據 
ratings_df = pd.read_csv('F:\Machine\data_sets\ml-latest-small/ratings.csv')
# print(ratings_df.tail())
# tail命令用於輸入文件中的尾部內容。tail命令默認在屏幕上顯示指定文件的末尾5行。
# 相對應的有:ratings_df.head()
movies_df = pd.read_csv('F:\Machine\data_sets\ml-latest-small/movies.csv')
movies_df['movieRow'] = movies_df.index
# 生成一列‘movieRow’,等於索引值index
# print(movies_df.tail())
 
movies_df = movies_df[['movieRow', 'movieId', 'title']]
# 篩選三列出來
movies_df.to_csv('F:\Machine\data_sets\ml-latest-small/moviesProcessed.csv', index=False, header=True, encoding='utf-8')
# 生成一個新的文件moviesProcessed.csv
print(movies_df.tail())
 
ratings_df = pd.merge(ratings_df, movies_df, on='movieId')
# print(ratings_df.head())
ratings_df = ratings_df[['userId', 'movieRow', 'rating']]
# 篩選出三列
ratings_df.to_csv('F:\Machine\data_sets\ml-latest-small/ratingsProcessed.csv', index=False, header=True, encoding='utf-8')
# 導出一個新的文件ratingsProcessed.csv
print(ratings_df.head())

 

​​​​​​​二、建立用戶矩陣和電影矩陣code

# 第二步:-----------------------建立電影評分矩陣rating和評分紀錄矩陣record
userNo = ratings_df['userId'].max() + 1
# userNo的最大值
movieNo = ratings_df['movieRow'].max() + 1
# movieNo的最大值
 
rating = np.zeros((movieNo, userNo))
print(rating.shape)
# 建立一個值都是0的數據
flag = 0
ratings_df_length = np.shape(ratings_df)[0]
 
print(np.shape(ratings_df))
# 查看矩陣ratings_df的第一維度是多少
for index, row in ratings_df.iterrows():
    # interrows(),對錶格ratings_df進行遍歷
    # rating[int(row['movieRow']), int(row['userId'])] = row['rating']
    # 等價於:
    rating[int(row['movieRow'])][int(row['userId'])] = row['rating']
    # 在rating表裏的'movieRow'行和'userId'列處,填上row的‘評分’,即ratings_df對應的評分
    flag += 1
    # if (ratings_df_length-flag) % 5000 == 0:
    #     print(u'還剩多少待處理:%d' %(ratings_df_length-flag))
# print(rating[3][450])
record = rating > 0
record = np.array(record, dtype=int)
print(record)
 

 

三、預處理數據

對上一步的數據進行歸一化處理。

# 第三步:----------------------------預處理數據 
def normalizeRatings(rating, record):
    m, n = rating.shape
    #m表明電影數量,n表明用戶數量
    rating_mean = np.zeros((m, 1))
    #每部電影的平均得分
    rating_norm = np.zeros((m, n))
    #處理過的評分
    for i in range(m):
        idx = (record[i, :] != 0)
        #每部電影的評分,[i,:]表示每一行的全部列
        rating_mean[i] = np.mean(rating[i, idx])
        # 第i行,評過份idx的用戶的平均得分
        # np.mean() 對全部元素求均值
        rating_norm[i, idx] = rating[i, idx] - rating_mean[i]
        #rating_norm = 原始得分-平均得分
    return rating_norm, rating_mean
 
rating_norm, rating_mean = normalizeRatings(rating, record)
rating_norm = np.nan_to_num(rating_norm)
# 對值爲NaNN進行處理,改爲數值0
# print(rating_norm)
rating_mean = np.nan_to_num(rating_mean)
# 對值爲NaNN進行處理,改爲數值0
# print(rating_mean)

 

四、構建模型和損失函數

# 構建模型
num_features = 12
X_parameters = tf.Variable(tf.random_normal([movieNo, num_features], stddev = 0.35))
Theta_parameters = tf.Variable(tf.random_normal([userNo, num_features], stddev = 0.35))
# tf.Variables()初始化變量
# tf.random_normal()函數用於從服從指定正太分佈的數值中取出指定個數的值,mean: 正態分佈的均值。stddev: 正態分佈的標準差。dtype: 輸出的類型
loss = 1/2 * tf.reduce_sum(((tf.matmul(X_parameters, Theta_parameters, transpose_b=True) - rating_norm) * record) ** 2) + \
       0.5*(1/2 * (tf.reduce_sum(X_parameters ** 2) + tf.reduce_sum(Theta_parameters ** 2)))
# 基於內容的推薦算法模型
train = tf.train.AdamOptimizer(1e-3).minimize(loss)

 

五、訓練模型

# 第四步:------------------------------------訓練模型 
tf.summary.scalar('train_loss', loss)
# 用來顯示標量信息
summaryMerged = tf.summary.merge_all()
# merge_all 能夠將全部summary所有保存到磁盤,以便tensorboard顯示。
filename = 'F:\Machine\data_sets\ml-latest-small/movie_tensorborad.csv'
writer = tf.summary.FileWriter(filename)
# 指定一個文件用來保存圖。
sess = tf.Session()
init = tf.global_variables_initializer()
sess.run(init)
# 運行
for i in range(2000):
    _, movie_summary = sess.run([train, summaryMerged])
    # 把訓練的結果summaryMerged存在movie裏
    writer.add_summary(movie_summary, i)
    # 把訓練的結果保存下來 

 

六、評估模型

# 第五步:-------------------------------------評估模型
 Current_X_parameters, Current_Theta_parameters = sess.run([X_parameters, Theta_parameters])
# Current_X_parameters爲電影內容矩陣,Current_Theta_parameters用戶喜愛矩陣
predicts = np.dot(Current_X_parameters, Current_Theta_parameters.T) + rating_mean
# dot函數是np中的矩陣乘法,np.dot(x,y) 等價於 x.dot(y)
errors = np.sqrt(np.sum(((predicts - rating) * record)**2))
# sqrt(arr) ,計算各元素的平方根
print(u'模型評估errors:', errors)

 

七、推薦電影

# 第六步:--------------------------------------構建完整的電影推薦系統 
user_id = input(u'您要想哪位用戶進行推薦?請輸入用戶編號:')
sortedResult = predicts[:, int(user_id)].argsort()[::-1]
# argsort()函數返回的是數組值從小到大的索引值; argsort()[::-1] 返回的是數組值從大到小的索引值
print(u'爲該用戶推薦的評分最高的20部電影是:'.center(80, '='))
# center() 返回一個原字符串居中,並使用空格填充至長度 width 的新字符串。默認填充字符爲空格。
idx = 0
for i in sortedResult:
    print(u'評分: %.2f, 電影名: %s' % (predicts[i, int(user_id)]-2, movies_df.iloc[i]['title']))
    # .iloc的用法:https://www.cnblogs.com/harvey888/p/6006200.html
    idx += 1
    if idx == 20:
        break
相關文章
相關標籤/搜索