<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    【機(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開(kāi)發(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開(kāi)發(fā)框架)部署最終系統(tǒng)

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

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

    這種方法可以基于用戶過(guò)去的行為和其他用戶做出的類(lèi)似決策來(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表示,不提供其他信息?!?/p>

    另外請(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'列從字符串類(lèi)型轉(zhuǎn)換為double類(lèi)型(數(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ō)尤其如此,比如你公司的銷(xiāo)售團(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í)上,這些電影的類(lèi)型并沒(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)。

    寫(xiě)一整篇文章來(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開(kāi)發(fā)略知一二。

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

    實(shí)際上,用戶將從100部最受歡迎電影的目錄中選擇3部電影開(kāi)始,并且這些電影是根據(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è)表保存在最后。

    這允許我們基于類(lèi)似的用戶配置文件向用戶提供電影推薦。另一個(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ì)于為每種類(lèi)型的產(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="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    亚洲AV无码成人国产精品色 | 肏屄视频在线播放 | 奇米成人影视 | 视频一区三区 | 豆花视频成人版在线入口 |