日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

【机器学习】从电影数据集到推荐系统

發布時間:2025/3/12 windows 17 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【机器学习】从电影数据集到推荐系统 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

作者 | Amine Zaamoun

編譯 | VK
來源 | Towards Data Science

最初是一個數據集,現在是一個由Amine Zaamoun開發的電影推薦系統:

為什么是推薦系統?

你們可能曾經花上幾分鐘甚至幾個小時去選擇一部電影單獨看或者和家人一起看,不幸的是沒有成功?你希望有人在這種時候替你做決定,這正是推薦系統的作用。

推薦系統是網易和亞馬遜巨頭目前取得成功的主要原因之一。我設計這篇文章是為了向你展示,任何在數據科學和編程方面有一點創造力和經驗的人,都可以通過遵循我將要描述的幾個步驟來實現他們自己的推薦系統。

我在德國電信公司(DEUTSCHE TELEKOM AG)數據科學創新中心(IHUB)8個月的實習期間實現了這個項目。我們的想法也是把重點放在實踐方面,而不是放在理論和數學方面,你可以在互聯網上找到科學文獻。

系統概述和體系結構

本文介紹的推薦系統分四個主要步驟實現:

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

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

  • 第3步:建立5部由深度學習算法推薦的“鮮為人知”電影的推薦:使用Tensorflow和Keras的深度神經矩陣分解(DNMF)實現

  • 第4步:使用來自Flask(python web開發框架)部署最終系統

我們使用的數據集中,用戶對他們看過的電影進行了評分。

協同過濾方法

這種方法可以基于用戶過去的行為和其他用戶做出的類似決策來構建模型。

事實上,它是基于在數據集中選擇的電影和這些電影的評分。然后,通過預測這些電影的收視率,使用該模型來預測用戶可能感興趣的電影。

MovieLens’ ratings.csv 數據集

這個數據集中突出顯示的一行內容如下:4號用戶觀看了21號電影,并將其評分為3.0/5.0。

有關此數據集的所有信息可以直接從以下鏈接:https://grouplens.org/datasets/movielens/latest/的README.html得到

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

用戶是隨機選擇的。所有選定的用戶都對至少20部電影進行了評分。不包括人口統計信息。每個用戶都由一個id表示,不提供其他信息。”

另外請注意,對于本文介紹的推薦系統,只使用了電影的評分,而沒有使用標簽。

第1步:計算每部電影的加權平均分

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

代碼本身是非常不言自明的,唯一值得注意的元素是使用PySpark來執行此計算。

實際上,這個庫允許使用SQL語言固有的“mean”和“col”函數,從而促進代碼的組織和可讀性。然而,同樣的計算在pandas庫也是完全可行的,因為pandas庫在數據科學初學者中更受歡迎。

我們電影推薦系統實現的第一步代碼

import?os from?pyspark.sql.functions?import?mean,?col"""路徑設置""" 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')"""加載數據集""" 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)"""計算每部電影的平均評分和評分數量""" 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")"""計算每部電影的加權平均分""" #?我們必須將'vote_count'列從字符串類型轉換為double類型(數值型),以便計算分位數 changedTypedf?=?mostRatedMovies.withColumn("vote_count",?df["count"].cast("double")) quantile_df?=?changedTypedf.approxQuantile("count",?[0.75],?0) m?=?quantile_df[0]# collect()用于在驅動程序中以數組的形式返回數據集的所有元素。 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文件中以供以后訪問""" movies_cleaned_pd.to_csv(os.path.join(trained_datapath,?'MostPopularMovies.csv'),?index=False)

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

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

首先,它幫助用戶放心,因為他至少會認出推薦的電影之一。事實上,如果他不認識任何推薦的電影,他可能會拒絕我們系統的有用性。不幸的是,這一心理和人的因素是無法量化的。這也證明,如果不考慮文化方面,最好的數學和統計模型可能不適合一些用戶。

其次,使用kNN算法推薦的電影都是“流行”的,這是在訓練機器學習模型之前對數據進行預先過濾的直接結果。

事實上,我們數據集中的評估頻率遵循“長尾”分布。這意味著大多數電影的收視率非常低,而“少數壓倒性”的收視率遠遠高于其他電影的總和。因此,這個過濾器只允許使用最流行的電影來訓練kNN算法,因此得到的推薦也只能是流行電影。

該算法還具有易于理解和解釋的優點。對于非技術人員來說尤其如此,比如你公司的銷售團隊,或者僅僅是你的朋友和家人,他們不一定對數據科學十分理解。

Kevin Liao在文章中所解釋的:“當KNN對一部電影進行推斷時,KNN將計算目標電影與其數據庫中其他每部電影之間的‘距離’,然后對其距離進行排序,并返回前K個最近鄰居電影作為最相似的電影推薦”。

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

這個結果,從主觀和個人的角度來看,似乎非常連貫的意義上說,他們是兩個超級英雄電影。我們還可以注意到《阿凡達(2009)》和《盜夢空間(2010)》這兩部科幻電影的出現。

我感謝有必要注意到機器學習算法的魔力,因為正如我提醒你的那樣,只使用了1.0到5.0的評分。事實上,這些電影的類型并沒有被用來提供這些建議。

下面是相關的代碼片段,向你展示如何使用Scikit學習庫實現此算法,并根據選定的電影標題獲取建議

我們的電影推薦系統實現的第2步中的kNN算法片段:

from?scipy.sparse?import?csr_matrix from?sklearn.neighbors?import?NearestNeighbors import?numpy?as?np import?pandas?as?pd"""創建透視表""" 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)"""使用整個數據集擬合最終的無監督模型,以找到每一個最相似的電影""" model_knn?=?NearestNeighbors(metric='cosine',?algorithm='brute',?n_neighbors=11,?n_jobs=-1) model_knn.fit(movie_features_df_matrix)#?選擇一個標題 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)#?根據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步:使用深層神經矩陣分解(DNMF)建立5部“鮮為人知”電影的推薦

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

不需要過多的細節,只需要記住,不需要預先過濾,而且電影可以用作訓練數據,而不管它的受歡迎程度如何。

實際上,這個算法在數學上非常復雜,它結合了數據科學中常用的兩個模型。第一個模型是矩陣分解,例如,交替最小二乘(ALS)算法。另一個模型是深層神經網絡的一個例子,例如多層感知器(MLP)。

寫一整篇文章來正確地解釋它必要的,但正如我之前已經宣布,目標是是偏向于實現。因此,我讓你閱讀這兩篇已經很好地解釋了這些概念的參考資料:(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步中使用的深層神經矩陣分解算法(DNMF)具有以下體系結構:

該算法的原理與經典的矩陣分解相同。使用這個模型,我們試圖預測某個用戶對某部電影的評價。我指定了“他會給出”的評分,因為這個算法填充了當前數據存在的空白值。

讓我解釋一下:即使是一個大影迷也可能沒有看過或評價過我們數據集中的所有9742部電影。這樣一來,他就可以給自己還沒有打分的電影打分,以此來決定自己是否喜歡這些電影。這正是我們算法的矩陣分解部分所做的。

神經網絡的加入使得進一步提高模型的預測性能成為可能,從而減少預測和實際評分之間的誤差。下面是一個代碼片段,向你展示如何使用Tensorflow和Keras庫實現這樣的模型。我們將使用它來預測與一對不存在的(userId,movieId)的評分。

我們的電影推薦系統實現的第三步中的DNMF算法片段

import?numpy?as?np import?pandas?as?pd from?tensorflow?import?keras"""計算不同userid和movieid的數量,創建輸入用戶和電影向量和潛在因子的數量""" 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"""實現模型架構,并使其擬合到輸入用戶和電影向量""" #?用戶矩陣分解和多層感知機嵌入路徑 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))#?矩陣分解和多層感知機嵌入路徑 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))#?用戶與電影的點積矩陣分解嵌入和連接用戶與電影的多層感知機嵌入 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])#?添加全連接層,矩陣分解和多層感知機部分的連接和輸出層 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)的預測評分,將用于進一步的推薦""" #?選擇一個不存在于ratings.csv文件中的(userId,?movieId)對,例如(1,10) userIdChosed_vector?=?np.asarray([1]).astype(np.int32) movieIdChosed_vector?=?np.asarray([10]).astype(np.int32)#?根據DNMF模型預測userid_chosen將給movieid_chosen的評分 predicted_rating?=?dnmf_model_final.predict([userIdChosed_vector,?movieIdChosed_vector]) print(predicted_rating)

現在,我們可以按照同樣的邏輯來預測我們數據庫中所有尚未存在的(userId,movieId)。以用戶401為例,通過DNMF算法計算出前10位如下:

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

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部署最終系統

我們終于到了最后一步,這一步需要對web開發略知一二。

將系統作為一個真正的應用程序進行適當的部署將非常有用。在這個web應用程序中,我們將鏈接本文前面步驟中完成的所有工作。

實際上,用戶將從100部最受歡迎電影的目錄中選擇3部電影開始,并且這些電影是根據第一步中這些電影的加權平均分計算出來的。

這3部電影將作為我們的2個模型的輸入數據,以獲得10部電影的最終推薦,其中5部來自kNN,5部來自DNMF。

此外,為了給最終用戶提供快速而流暢的體驗,已經預先計算了DNMF模型將給出的預測。

這意味著對于選中的3部電影中的每一部,系統都會在“DNMF_UserRecommendationsForAllMovies”中進行搜索。根據預測得分“匹配”5個用戶:

然后,系統將使用此匹配的用戶列表重復與前面相同的過程。

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

這允許我們基于類似的用戶配置文件向用戶提供電影推薦。另一個非常重要的一點是,這些建議已經快速和準確地給出,而不必等待數小時的模型進行重新訓練,因此預先計算DNMF結果十分有用。

@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)#?對于用戶選擇的每一部最喜歡的電影,將他們最近的10部電影添加到kNN_recommendations列表中,隨機保留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)#?對于用戶選擇的每個最喜歡的電影,將他們推薦的前5個用戶添加到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)#?對于模型推薦的每個用戶,將他們推薦的前5部電影添加到DNMF_moviesRecommendation列表中,并隨機保留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)#?加入兩個列表,以便從kNN模型給出5部電影推薦和從DNMF模型給出5部電影推薦finalRecommendations?=?final_kNN_recommendations?+?recommendedMovieTitlesrecommendedMoviePosters?=?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)

正如你所注意到的,當用戶選擇了他的3部電影并按下按鈕以獲得他的推薦時,POST請求被發送到服務器。處理此請求時,呈現的函數將返回幾個與“模板”關聯的變量。下面是如何在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>

以下是最終結果:

就這樣!你現在可以嘗試實現你自己的系統版本了。

總結

在本文中,我們共同了解了如何使用Python編程語言將一個簡單的數據集轉換為一個真正的電影推薦系統,并將其部署為一個web應用程序。

我們還了解到,推薦系統通常基于不同的互連算法。這對于為每種類型的產品(無論是“流行的”還是“鮮為人知的”)提供建議確實很有用。

我盡我所能以一種更實際而非理論的方式來表達這個話題,這樣任何人都能理解我在說什么,希望你喜歡。源代碼可以在我的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.

往期精彩回顧適合初學者入門人工智能的路線及資料下載機器學習及深度學習筆記等資料打印機器學習在線手冊深度學習筆記專輯《統計學習方法》的代碼復現專輯 AI基礎下載機器學習的數學基礎專輯溫州大學《機器學習課程》視頻 本站qq群851320808,加入微信群請掃碼:

總結

以上是生活随笔為你收集整理的【机器学习】从电影数据集到推荐系统的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。