<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          【機(jī)器學(xué)習(xí)】從電影數(shù)據(jù)集到推薦系統(tǒng)

          共 21267字,需瀏覽 43分鐘

           ·

          2021-06-16 11:16

          作者 | Amine Zaamoun

          編譯 | VK
          來(lái)源 | Towards Data Science

          最初是一個(gè)數(shù)據(jù)集,現(xiàn)在是一個(gè)由Amine Zaamoun開發(fā)的電影推薦系統(tǒng):

          為什么是推薦系統(tǒng)?

          你們可能曾經(jīng)花上幾分鐘甚至幾個(gè)小時(shí)去選擇一部電影單獨(dú)看或者和家人一起看,不幸的是沒(méi)有成功?你希望有人在這種時(shí)候替你做決定,這正是推薦系統(tǒng)的作用。

          推薦系統(tǒng)是網(wǎng)易和亞馬遜巨頭目前取得成功的主要原因之一。我設(shè)計(jì)這篇文章是為了向你展示,任何在數(shù)據(jù)科學(xué)和編程方面有一點(diǎn)創(chuàng)造力和經(jīng)驗(yàn)的人,都可以通過(guò)遵循我將要描述的幾個(gè)步驟來(lái)實(shí)現(xiàn)他們自己的推薦系統(tǒng)。

          我在德國(guó)電信公司(DEUTSCHE TELEKOM AG)數(shù)據(jù)科學(xué)創(chuàng)新中心(IHUB)8個(gè)月的實(shí)習(xí)期間實(shí)現(xiàn)了這個(gè)項(xiàng)目。我們的想法也是把重點(diǎn)放在實(shí)踐方面,而不是放在理論和數(shù)學(xué)方面,你可以在互聯(lián)網(wǎng)上找到科學(xué)文獻(xiàn)。

          系統(tǒng)概述和體系結(jié)構(gòu)

          本文介紹的推薦系統(tǒng)分四個(gè)主要步驟實(shí)現(xiàn):

          • 第1步:計(jì)算每部電影的加權(quán)平均分,以便向最終用戶推薦最受歡迎的100部電影的目錄

          • 第2步:使用機(jī)器學(xué)習(xí)算法建立5部“流行”電影的推薦:使用Scikit learn的k近鄰(kNN)

          • 第3步:建立5部由深度學(xué)習(xí)算法推薦的“鮮為人知”電影的推薦:使用Tensorflow和Keras的深度神經(jīng)矩陣分解(DNMF)實(shí)現(xiàn)

          • 第4步:使用來(lái)自Flask(python web開發(fā)框架)部署最終系統(tǒng)

          我們使用的數(shù)據(jù)集中,用戶對(duì)他們看過(guò)的電影進(jìn)行了評(píng)分。

          協(xié)同過(guò)濾方法

          這種方法可以基于用戶過(guò)去的行為和其他用戶做出的類似決策來(lái)構(gòu)建模型。

          事實(shí)上,它是基于在數(shù)據(jù)集中選擇的電影和這些電影的評(píng)分。然后,通過(guò)預(yù)測(cè)這些電影的收視率,使用該模型來(lái)預(yù)測(cè)用戶可能感興趣的電影。

          MovieLens’ ratings.csv 數(shù)據(jù)集

          這個(gè)數(shù)據(jù)集中突出顯示的一行內(nèi)容如下:4號(hào)用戶觀看了21號(hào)電影,并將其評(píng)分為3.0/5.0。

          有關(guān)此數(shù)據(jù)集的所有信息可以直接從以下鏈接:https://grouplens.org/datasets/movielens/latest/的README.html得到

          “這個(gè)數(shù)據(jù)集[1](ml-latest-small)描述了電影推薦服務(wù)MovieLens的評(píng)分(滿分5分)和文本信息。它包含100836個(gè)收視率和3683個(gè)標(biāo)簽,涵蓋9742部電影。這些數(shù)據(jù)由610名用戶在1996年3月29日至2018年9月24日期間創(chuàng)建。該數(shù)據(jù)集于2018年9月26日生成。

          用戶是隨機(jī)選擇的。所有選定的用戶都對(duì)至少20部電影進(jìn)行了評(píng)分。不包括人口統(tǒng)計(jì)信息。每個(gè)用戶都由一個(gè)id表示,不提供其他信息。”

          另外請(qǐng)注意,對(duì)于本文介紹的推薦系統(tǒng),只使用了電影的評(píng)分,而沒(méi)有使用標(biāo)簽。

          第1步:計(jì)算每部電影的加權(quán)平均分

          這第一步的目標(biāo)是為我們推薦系統(tǒng)的最終用戶提供一個(gè)流行電影的目錄,他們可以從中選擇自己喜歡的電影。

          代碼本身是非常不言自明的,唯一值得注意的元素是使用PySpark來(lái)執(zhí)行此計(jì)算。

          實(shí)際上,這個(gè)庫(kù)允許使用SQL語(yǔ)言固有的“mean”和“col”函數(shù),從而促進(jìn)代碼的組織和可讀性。然而,同樣的計(jì)算在pandas庫(kù)也是完全可行的,因?yàn)閜andas庫(kù)在數(shù)據(jù)科學(xué)初學(xué)者中更受歡迎。

          我們電影推薦系統(tǒng)實(shí)現(xiàn)的第一步代碼

          import os
          from pyspark.sql.functions import mean, col

          """路徑設(shè)置"""
          data_path = os.environ['DATA_PATH']
          movies_datapath = os.path.join(data_path, 'Movies/MovieLens/movies_data-100k')
          trained_datapath = os.path.join(movies_datapath, 'Already_Trained')

          """加載數(shù)據(jù)集"""
          ratings = spark.read.load(os.path.join(movies_datapath, 'ratings.csv'), format='csv', header=True, inferSchema=True).drop("timestamp")
          movies = spark.read.load(os.path.join(movies_datapath, 'movies.csv'), format='csv', header=True, inferSchema=True)

          """計(jì)算每部電影的平均評(píng)分和評(píng)分?jǐn)?shù)量"""
          df = ratings.join(movies, on="movieId")
          number_ratings = df.groupBy('movieId').count()
          average_ratings = df.groupBy('movieId').avg('rating')
          df_ratings = average_ratings.join(number_ratings, on="movieId")
          df = df.join(df_ratings, on="movieId")
          mostRatedMovies = df.where("count >= 50")

          """計(jì)算每部電影的加權(quán)平均分"""
          # 我們必須將'vote_count'列從字符串類型轉(zhuǎn)換為double類型(數(shù)值型),以便計(jì)算分位數(shù)
          changedTypedf = mostRatedMovies.withColumn("vote_count", df["count"].cast("double"))
          quantile_df = changedTypedf.approxQuantile("count", [0.75], 0)
          m = quantile_df[0]

          # collect()用于在驅(qū)動(dòng)程序中以數(shù)組的形式返回?cái)?shù)據(jù)集的所有元素。
          mean_df = mostRatedMovies.select(mean(col('avg(rating)')).alias('mean')).collect()
          C = mean_df[0]['mean']

          movies_cleaned_df = mostRatedMovies.withColumn("weighted_average", ((mostRatedMovies['avg(rating)']*mostRatedMovies['count']) + (C*m)) / (mostRatedMovies['count']+m))

          """將表保存到CSV文件中以供以后訪問(wèn)"""
          movies_cleaned_pd.to_csv(os.path.join(trained_datapath, 'MostPopularMovies.csv'), index=False)

          第2步:使用k近鄰(kNN)設(shè)置5部“流行”電影的推薦

          第2步的目標(biāo)是向最終用戶推薦一系列可以稱為“流行”的電影。

          首先,它幫助用戶放心,因?yàn)樗辽贂?huì)認(rèn)出推薦的電影之一。事實(shí)上,如果他不認(rèn)識(shí)任何推薦的電影,他可能會(huì)拒絕我們系統(tǒng)的有用性。不幸的是,這一心理和人的因素是無(wú)法量化的。這也證明,如果不考慮文化方面,最好的數(shù)學(xué)和統(tǒng)計(jì)模型可能不適合一些用戶。

          其次,使用kNN算法推薦的電影都是“流行”的,這是在訓(xùn)練機(jī)器學(xué)習(xí)模型之前對(duì)數(shù)據(jù)進(jìn)行預(yù)先過(guò)濾的直接結(jié)果。

          事實(shí)上,我們數(shù)據(jù)集中的評(píng)估頻率遵循“長(zhǎng)尾”分布。這意味著大多數(shù)電影的收視率非常低,而“少數(shù)壓倒性”的收視率遠(yuǎn)遠(yuǎn)高于其他電影的總和。因此,這個(gè)過(guò)濾器只允許使用最流行的電影來(lái)訓(xùn)練kNN算法,因此得到的推薦也只能是流行電影。

          該算法還具有易于理解和解釋的優(yōu)點(diǎn)。對(duì)于非技術(shù)人員來(lái)說(shuō)尤其如此,比如你公司的銷售團(tuán)隊(duì),或者僅僅是你的朋友和家人,他們不一定對(duì)數(shù)據(jù)科學(xué)十分理解。

          Kevin Liao在文章中所解釋的:“當(dāng)KNN對(duì)一部電影進(jìn)行推斷時(shí),KNN將計(jì)算目標(biāo)電影與其數(shù)據(jù)庫(kù)中其他每部電影之間的‘距離’,然后對(duì)其距離進(jìn)行排序,并返回前K個(gè)最近鄰居電影作為最相似的電影推薦”。

          正如你在本例中所看到的,與“鋼鐵俠(2008)”最接近的電影是“黑暗騎士(2008)”,其余弦相似性(或簡(jiǎn)稱“距離”)約為0.33。

          這個(gè)結(jié)果,從主觀和個(gè)人的角度來(lái)看,似乎非常連貫的意義上說(shuō),他們是兩個(gè)超級(jí)英雄電影。我們還可以注意到《阿凡達(dá)(2009)》和《盜夢(mèng)空間(2010)》這兩部科幻電影的出現(xiàn)。

          我感謝有必要注意到機(jī)器學(xué)習(xí)算法的魔力,因?yàn)檎缥姨嵝涯愕哪菢?,只使用?.0到5.0的評(píng)分。事實(shí)上,這些電影的類型并沒(méi)有被用來(lái)提供這些建議。

          下面是相關(guān)的代碼片段,向你展示如何使用Scikit學(xué)習(xí)庫(kù)實(shí)現(xiàn)此算法,并根據(jù)選定的電影標(biāo)題獲取建議

          我們的電影推薦系統(tǒng)實(shí)現(xiàn)的第2步中的kNN算法片段:

          from scipy.sparse import csr_matrix
          from sklearn.neighbors import NearestNeighbors
          import numpy as np
          import pandas as pd

          """創(chuàng)建透視表"""
          movies_pivot = mostRatedMovies.groupBy('title').pivot('userId').sum('rating').fillna(0)
          movie_features_df = movies_pivot.toPandas().set_index('title')
          movie_features_df_matrix = csr_matrix(movie_features_df.values)

          """使用整個(gè)數(shù)據(jù)集擬合最終的無(wú)監(jiān)督模型,以找到每一個(gè)最相似的電影"""
          model_knn = NearestNeighbors(metric='cosine', algorithm='brute', n_neighbors=11, n_jobs=-1)
          model_knn.fit(movie_features_df_matrix)

          # 選擇一個(gè)標(biāo)題
          favoriteMovie = 'Iron Man (2008)'
          query_index = movie_features_df.index.get_loc(favoriteMovie)
          distances, indices = model_knn.kneighbors(movie_features_df.loc[favoriteMovie,:].values.reshape(1-1), n_neighbors=11)

          # 根據(jù)kNN模型打印10部最相似的電影
          for i in range(0, len(distances.flatten())):
              if i == 0:
                  print('Recommendations for {0}:\n'.format(movie_features_df.index[query_index]))
              else:
                  print('{0}: {1}, with distance of {2}:'.format(i, movie_features_df.index[indices.flatten()[i]], distances.flatten()[i]))

          第3步:使用深層神經(jīng)矩陣分解(DNMF)建立5部“鮮為人知”電影的推薦

          第3步的目的和該算法的選擇是向最終用戶推薦一系列往往“鮮為人知”的電影。

          不需要過(guò)多的細(xì)節(jié),只需要記住,不需要預(yù)先過(guò)濾,而且電影可以用作訓(xùn)練數(shù)據(jù),而不管它的受歡迎程度如何。

          實(shí)際上,這個(gè)算法在數(shù)學(xué)上非常復(fù)雜,它結(jié)合了數(shù)據(jù)科學(xué)中常用的兩個(gè)模型。第一個(gè)模型是矩陣分解,例如,交替最小二乘(ALS)算法。另一個(gè)模型是深層神經(jīng)網(wǎng)絡(luò)的一個(gè)例子,例如多層感知器(MLP)。

          寫一整篇文章來(lái)正確地解釋它必要的,但正如我之前已經(jīng)宣布,目標(biāo)是是偏向于實(shí)現(xiàn)。因此,我讓你閱讀這兩篇已經(jīng)很好地解釋了這些概念的參考資料:(https://towardsdatascience.com/prototyping-a-recommender-system-step-by-step-part-2-alternating-least-square-als-matrix-4a76c58714a1;https://towardsdatascience.com/building-a-deep-learning-model-using-keras-1548ca149d37)

          第3步中使用的深層神經(jīng)矩陣分解算法(DNMF)具有以下體系結(jié)構(gòu):

          該算法的原理與經(jīng)典的矩陣分解相同。使用這個(gè)模型,我們?cè)噲D預(yù)測(cè)某個(gè)用戶對(duì)某部電影的評(píng)價(jià)。我指定了“他會(huì)給出”的評(píng)分,因?yàn)檫@個(gè)算法填充了當(dāng)前數(shù)據(jù)存在的空白值。

          讓我解釋一下:即使是一個(gè)大影迷也可能沒(méi)有看過(guò)或評(píng)價(jià)過(guò)我們數(shù)據(jù)集中的所有9742部電影。這樣一來(lái),他就可以給自己還沒(méi)有打分的電影打分,以此來(lái)決定自己是否喜歡這些電影。這正是我們算法的矩陣分解部分所做的。

          神經(jīng)網(wǎng)絡(luò)的加入使得進(jìn)一步提高模型的預(yù)測(cè)性能成為可能,從而減少預(yù)測(cè)和實(shí)際評(píng)分之間的誤差。下面是一個(gè)代碼片段,向你展示如何使用Tensorflow和Keras庫(kù)實(shí)現(xiàn)這樣的模型。我們將使用它來(lái)預(yù)測(cè)與一對(duì)不存在的(userId,movieId)的評(píng)分。

          我們的電影推薦系統(tǒng)實(shí)現(xiàn)的第三步中的DNMF算法片段

          import numpy as np
          import pandas as pd
          from tensorflow import keras

          """計(jì)算不同userid和movieid的數(shù)量,創(chuàng)建輸入用戶和電影向量和潛在因子的數(shù)量"""
          n_users = len(df_ratings_reduced["userId"].unique())
          n_movies = len(df_ratings_reduced["movieId"].unique())
          userIds_vector = np.asarray(df_ratings.userId).astype(np.int32)
          movieIds_vector = np.asarray(df_ratings.movieId).astype(np.int32)
          n_latent_factors = 20

          """實(shí)現(xiàn)模型架構(gòu),并使其擬合到輸入用戶和電影向量"""
          # 用戶矩陣分解和多層感知機(jī)嵌入路徑
          users_input = keras.layers.Input(shape=[1], dtype='int32', name="users_input")
          users_mf_embedding = keras.layers.Embedding(input_dim=n_users + 1, output_dim=n_latent_factors, name='users_mf_embedding')
          users_flattened_mf = keras.layers.Flatten()(users_mf_embedding(users_input))
          users_mlp_embedding = keras.layers.Embedding(input_dim=n_users + 1, output_dim=n_latent_factors, name='users_mlp_embedding')
          users_flattened_mlp = keras.layers.Flatten()(users_mlp_embedding(users_input))

          # 矩陣分解和多層感知機(jī)嵌入路徑
          movies_input = keras.layers.Input(shape=[1], dtype='int32', name="movies_input")
          movies_mf_embedding = keras.layers.Embedding(input_dim=n_movies + 1, output_dim=n_latent_factors, name='movies_mf_embedding')
          movies_flattened_mf = keras.layers.Flatten()(movies_mf_embedding(movies_input))
          movies_mlp_embedding = keras.layers.Embedding(input_dim=n_movies + 1, output_dim=n_latent_factors, name='movies_mlp_embedding')
          movies_flattened_mlp = keras.layers.Flatten()(movies_mlp_embedding(movies_input))

          # 用戶與電影的點(diǎn)積矩陣分解嵌入和連接用戶與電影的多層感知機(jī)嵌入
          interaction_matrix = keras.layers.Dot(name="interaction_matrix", axes=1)([movies_flattened_mf, users_flattened_mf])
          concatenation_vector = keras.layers.Concatenate(name="concatenation_vector")([movies_flattened_mlp, users_flattened_mlp])

          # 添加全連接層,矩陣分解和多層感知機(jī)部分的連接和輸出層
          dense_1 = keras.layers.Dense(50, activation='elu', kernel_initializer="he_normal")(concatenation_vector)
          dense_2 = keras.layers.Dense(25, activation='elu', kernel_initializer="he_normal")(dense_1)
          dense_3 = keras.layers.Dense(12, activation='elu', kernel_initializer="he_normal")(dense_2)
          dense_4 = keras.layers.Dense(6, activation='elu', kernel_initializer="he_normal")(dense_3)
          dense_5 = keras.layers.Dense(3, activation='elu', kernel_initializer="he_normal")(dense_4)
          final_concatenation = keras.layers.Concatenate(name="final_concatenation")([interaction_matrix, dense_5])
          output_layer = keras.layers.Dense(1)(final_concatenation)

          # 拼接輸入輸出,編譯模型
          dnmf_model_final = keras.models.Model(inputs=[users_input, movies_input], outputs=output_layer)
          dnmf_model_final.compile(loss="mean_squared_error", optimizer=keras.optimizers.SGD(lr=0.01, momentum=0.9, nesterov=True, clipvalue=1.0), metrics=[keras.metrics.RootMeanSquaredError()])

          # 擬合模型
          history = dnmf_model_final.fit([userIds_vector, movieIds_vector], ratings_vector, epochs=100)

          """生成與尚未存在的(userId, movieId)的預(yù)測(cè)評(píng)分,將用于進(jìn)一步的推薦"""
          # 選擇一個(gè)不存在于ratings.csv文件中的(userId, movieId)對(duì),例如(1,10)
          userIdChosed_vector = np.asarray([1]).astype(np.int32)
          movieIdChosed_vector = np.asarray([10]).astype(np.int32)

          # 根據(jù)DNMF模型預(yù)測(cè)userid_chosen將給movieid_chosen的評(píng)分
          predicted_rating = dnmf_model_final.predict([userIdChosed_vector, movieIdChosed_vector])
          print(predicted_rating)

          現(xiàn)在,我們可以按照同樣的邏輯來(lái)預(yù)測(cè)我們數(shù)據(jù)庫(kù)中所有尚未存在的(userId,movieId)。以用戶401為例,通過(guò)DNMF算法計(jì)算出前10位如下:

          現(xiàn)在,我們可以將使用此模型生成的兩個(gè)表的結(jié)果保存在兩個(gè)不同的csv文件中:為每個(gè)電影推薦的前10個(gè)用戶和為每個(gè)用戶推薦的前10個(gè)電影。

          pdUserRecs.to_csv(os.path.join(trained_datapath, 'DNMF_MovieRecommendationsForAllUsers.csv'), index=False)

          pdMovieRecs.to_csv(os.path.join(trained_datapath, 'DNMF_UserRecommendationsForAllMovies.csv'), index=False)

          第4步:使用Flask部署最終系統(tǒng)

          我們終于到了最后一步,這一步需要對(duì)web開發(fā)略知一二。

          將系統(tǒng)作為一個(gè)真正的應(yīng)用程序進(jìn)行適當(dāng)?shù)牟渴饘⒎浅S杏?。在這個(gè)web應(yīng)用程序中,我們將鏈接本文前面步驟中完成的所有工作。

          實(shí)際上,用戶將從100部最受歡迎電影的目錄中選擇3部電影開始,并且這些電影是根據(jù)第一步中這些電影的加權(quán)平均分計(jì)算出來(lái)的。

          這3部電影將作為我們的2個(gè)模型的輸入數(shù)據(jù),以獲得10部電影的最終推薦,其中5部來(lái)自kNN,5部來(lái)自DNMF。

          此外,為了給最終用戶提供快速而流暢的體驗(yàn),已經(jīng)預(yù)先計(jì)算了DNMF模型將給出的預(yù)測(cè)。

          這意味著對(duì)于選中的3部電影中的每一部,系統(tǒng)都會(huì)在“DNMF_UserRecommendationsForAllMovies”中進(jìn)行搜索。根據(jù)預(yù)測(cè)得分“匹配”5個(gè)用戶:

          然后,系統(tǒng)將使用此匹配的用戶列表重復(fù)與前面相同的過(guò)程。

          換言之,它將在另一個(gè)列表中添加每個(gè)用戶最喜愛(ài)的5部電影,其中5部將使用另一個(gè)表保存在最后。

          這允許我們基于類似的用戶配置文件向用戶提供電影推薦。另一個(gè)非常重要的一點(diǎn)是,這些建議已經(jīng)快速和準(zhǔn)確地給出,而不必等待數(shù)小時(shí)的模型進(jìn)行重新訓(xùn)練,因此預(yù)先計(jì)算DNMF結(jié)果十分有用。

          @app.route('/recommended_movies', methods=['POST'])
          def make_recommendations():

              finalRecommendations = []

              popular_movies_list = show_popular_movies(mostPopularMovies)
              favorite_movieTitles = request.form.getlist('cb')
              favorite_ids = get_movieIds(movies, favorite_movieTitles)
              popular_movieIds_list = get_movieIds(movies, popular_movies_list)

              # 對(duì)于用戶選擇的每一部最喜歡的電影,將他們最近的10部電影添加到kNN_recommendations列表中,隨機(jī)保留5部
              kNN_recommendations = []
              for i in range(3):
                  userMovie = favorite_movieTitles[i]
                  query_index = kNNmovieMatrix.index.get_loc(userMovie)
                  distances, indices = loaded_kNN_model.kneighbors(kNNmovieMatrix.iloc[query_index,:].values.reshape(1-1), n_neighbors = 11)
                  for j in range(1, len(distances.flatten())):
                      movieTitle = kNNmovieMatrix.index[indices.flatten()[j]]
                      distance = distances.flatten()[j]
                      if (movieTitle not in popular_movies_list) and (movieTitle not in kNN_recommendations) and (movieTitle not in favorite_movieTitles):
                          kNN_recommendations.append(movieTitle)
              final_kNN_recommendations = random.sample(kNN_recommendations, 5)
              kNN_recommendedIds = get_movieIds(movies, final_kNN_recommendations)

              # 對(duì)于用戶選擇的每個(gè)最喜歡的電影,將他們推薦的前5個(gè)用戶添加到DNMF_usersRecommendation列表中
              DNMF_usersRecommendation = []
              for i in range(3):
                  movieChosed = favorite_ids[i]
                  for j in range(5):
                      userRecommended = pdMovieRecs[pdMovieRecs.movieId == movieChosed]["userRecommendations"].iloc[0][j]
                      predictedMatch = pdMovieRecs[pdMovieRecs.movieId == movieChosed]["userRatings"].iloc[0][j]
                      if (userRecommended not in DNMF_usersRecommendation):
                          DNMF_usersRecommendation.append(userRecommended)
              # 對(duì)于模型推薦的每個(gè)用戶,將他們推薦的前5部電影添加到DNMF_moviesRecommendation列表中,并隨機(jī)保留5部
              DNMF_moviesRecommendation = []
              for i in range(len(DNMF_usersRecommendation)):
                  userChosed = DNMF_usersRecommendation[i]
                  for j in range(5):
                      movieRecommended = pdUserRecs[pdUserRecs.userId == userChosed]["movieRecommendations"].iloc[0][j]
                      predictedRating = pdUserRecs[pdUserRecs.userId == userChosed]["movieRatings"].iloc[0][j]
                      if (movieRecommended not in DNMF_moviesRecommendation) and (movieRecommended not in kNN_recommendedIds) and (movieRecommended not in favorite_ids) and (movieRecommended not in popular_movieIds_list):
                          DNMF_moviesRecommendation.append(movieRecommended)            
              final_DNMF_recommendations = random.sample(DNMF_moviesRecommendation, 5)
              recommendedMovieTitles = get_movieTitles(movies, final_DNMF_recommendations)

              # 加入兩個(gè)列表,以便從kNN模型給出5部電影推薦和從DNMF模型給出5部電影推薦
              finalRecommendations = final_kNN_recommendations + recommendedMovieTitles
              recommendedMoviePosters = get_moviePosters(movies, finalRecommendations)

              return render_template('index.html',
                  choose_message="Here is a list of the most popular movies in our database, please choose 3 :",
                  favorite_movies_message="Your 3 favorite movies are :",
                  favorite_movies_list=favorite_movieTitles,
                  recommendations_message="We recommend you the following movies :",
                  recommendations_list=finalRecommendations,
                  recommendations_posters=recommendedMoviePosters)

          正如你所注意到的,當(dāng)用戶選擇了他的3部電影并按下按鈕以獲得他的推薦時(shí),POST請(qǐng)求被發(fā)送到服務(wù)器。處理此請(qǐng)求時(shí),呈現(xiàn)的函數(shù)將返回幾個(gè)與“模板”關(guān)聯(lián)的變量。下面是如何在index.html讀取變量:

              <div id="recommendationsDiv">
                {{ favorite_movies_message}}
                <ul>
                {% for favorite_movie in favorite_movies_list %}
                  <li>{{ favorite_movie }}</li>
                {% endfor %}
                </ul>
                {{ recommendations_message }}
                <br><br>
                {% if (recommendations_list is defined) and (recommendations_posters is defined) %}
                  <img src="{{ recommendations_posters[0] }}" alt="{{ recommendations_list[0] }}" />
                  <p>{{ recommendations_list[0] }}</p><br><br>
                  <img src="{{ recommendations_posters[1] }}" alt="{{ recommendations_list[1] }}" />
                  <p>{{ recommendations_list[1] }}</p><br><br>
                  <img src="{{ recommendations_posters[2] }}" alt="{{ recommendations_list[2] }}" />
                  <p>{{ recommendations_list[2] }}</p><br><br>
                  <img src="{{ recommendations_posters[3] }}" alt="{{ recommendations_list[3] }}" />
                  <p>{{ recommendations_list[3] }}</p><br><br>
                  <img src="{{ recommendations_posters[4] }}" alt="{{ recommendations_list[4] }}" />
                  <p>{{ recommendations_list[4] }}</p><br><br>
                  <img src="{{ recommendations_posters[5] }}" alt="{{ recommendations_list[5] }}" />
                  <p>{{ recommendations_list[5] }}</p><br><br>
                  <img src="{{ recommendations_posters[6] }}" alt="{{ recommendations_list[6] }}" />
                  <p>{{ recommendations_list[6] }}</p><br><br>
                  <img src="{{ recommendations_posters[7] }}" alt="{{ recommendations_list[7] }}" />
                  <p>{{ recommendations_list[7] }}</p><br><br>
                  <img src="{{ recommendations_posters[8] }}" alt="{{ recommendations_list[8] }}" />
                  <p>{{ recommendations_list[8] }}</p><br><br>
                  <img src="{{ recommendations_posters[9] }}" alt="{{ recommendations_list[9] }}" />
                  <p>{{ recommendations_list[9] }}</p>
                {% endif %}
              </div>

          以下是最終結(jié)果:

          就這樣!你現(xiàn)在可以嘗試實(shí)現(xiàn)你自己的系統(tǒng)版本了。

          總結(jié)

          在本文中,我們共同了解了如何使用Python編程語(yǔ)言將一個(gè)簡(jiǎn)單的數(shù)據(jù)集轉(zhuǎn)換為一個(gè)真正的電影推薦系統(tǒng),并將其部署為一個(gè)web應(yīng)用程序。

          我們還了解到,推薦系統(tǒng)通?;诓煌幕ミB算法。這對(duì)于為每種類型的產(chǎn)品(無(wú)論是“流行的”還是“鮮為人知的”)提供建議確實(shí)很有用。

          我盡我所能以一種更實(shí)際而非理論的方式來(lái)表達(dá)這個(gè)話題,這樣任何人都能理解我在說(shuō)什么,希望你喜歡。源代碼可以在我的GitHub找到:https://github.com/Zaamine/Movie_Recommender_System-Python

          參考引用

          [1] F. Maxwell Harper and Joseph A. Konstan. The MovieLens Datasets: History and Context (2015), ACM Transactions on Interactive Intelligent Systems (TiiS) 5, 4: 19:1–19:19.

          往期精彩回顧





          本站qq群851320808,加入微信群請(qǐng)掃碼:

          瀏覽 151
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  三级国产网站 | 黄色视频在线观看日本极品尤物 | 91三级在线 | 日韩AV在线动漫国产 | 亚洲成人经典 |