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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > windows >内容正文

windows

【推荐系统】基于协同过滤的图书推荐系统

發(fā)布時(shí)間:2024/3/12 windows 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【推荐系统】基于协同过滤的图书推荐系统 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

推薦系統(tǒng)一直讓我的思緒占據(jù)了一段時(shí)間,由于我傾向于閱讀書籍,因此探索Book Crossing數(shù)據(jù)集非常吸引人。

在線推薦系統(tǒng)是許多電子商務(wù)網(wǎng)站的事情。推薦系統(tǒng)廣泛地向最適合其口味和特征的顧客推薦產(chǎn)品。有關(guān)推薦系統(tǒng)的更多詳細(xì)信息,請(qǐng)閱讀我關(guān)于推薦系統(tǒng)的介紹性文章以及使用Python的一些插圖。

當(dāng)我遇到Book Crossing數(shù)據(jù)集時(shí),我開始構(gòu)建圖書推薦系統(tǒng)。該數(shù)據(jù)集由Cai-Nicolas Ziegler于2004年編制,包含三個(gè)用戶,書籍和評(píng)級(jí)表。顯式評(píng)級(jí)以1-10的等級(jí)表示(較高的值表示較高的升值),隱式評(píng)級(jí)以0表示。

在構(gòu)建任何機(jī)器學(xué)習(xí)模型之前,了解數(shù)據(jù)是什么以及我們要實(shí)現(xiàn)的目標(biāo)至關(guān)重要。數(shù)據(jù)探索揭示了隱藏的趨勢(shì)和見解,數(shù)據(jù)預(yù)處理使數(shù)據(jù)可供ML算法使用。


目錄

開始

圖書

用戶數(shù)據(jù)集

評(píng)級(jí)數(shù)據(jù)集

基于簡(jiǎn)單流行度的推薦系統(tǒng)

基于協(xié)同過濾的推薦系統(tǒng)

基于用戶的協(xié)同過濾

基于項(xiàng)目的協(xié)同過濾

代碼


?

?

開始

導(dǎo)入支持庫

import pandas as pd import matplotlib.pyplot as plt import sklearn.metrics as metrics import numpy as np from sklearn.neighbors import NearestNeighbors from scipy.spatial.distance import correlation from sklearn.metrics.pairwise import pairwise_distances import ipywidgets as widgets from IPython.display import display, clear_output from contextlib import contextmanager import warnings warnings.filterwarnings('ignore') import numpy as np import os, sys import re import seaborn as sns

?

首先,我們加載數(shù)據(jù)集并檢查書籍,用戶和評(píng)級(jí)數(shù)據(jù)集的形狀,如下所示:

books = pd.read_csv('dataset/BX-Books.csv', sep=';', error_bad_lines=False, encoding="latin-1") books.columns = ['ISBN', 'bookTitle', 'bookAuthor', 'yearOfPublication', 'publisher', 'imageUrlS', 'imageUrlM', 'imageUrlL'] users = pd.read_csv('dataset/BX-Users.csv', sep=';', error_bad_lines=False, encoding="latin-1") users.columns = ['userID', 'Location', 'Age'] ratings = pd.read_csv('dataset/BX-Book-Ratings.csv', sep=';', error_bad_lines=False, encoding="latin-1") ratings.columns = ['userID', 'ISBN', 'bookRating'] print (books.shape) print (users.shape) print (ratings.shape) (271360, 8) (278858, 3) (1149780, 3)

?

圖書

逐個(gè)探索每個(gè)數(shù)據(jù)集并從書籍?dāng)?shù)據(jù)集開始,我們可以看到圖像URL列似乎不需要進(jìn)行分析,因此可以刪除這些列。

books.head()

books.drop(['imageUrlS', 'imageUrlM', 'imageUrlL'],axis=1,inplace=True) books.head()

我們現(xiàn)在檢查每個(gè)列的數(shù)據(jù)類型,并更正缺失和不一致的條目。我也在調(diào)整列寬以顯示列的全文。

books.dtypes ISBN object bookTitle object bookAuthor object yearOfPublication object publisher object dtype: object

?

yearOfPublication

現(xiàn)在我們檢查此屬性的唯一值。

books.yearOfPublication.unique() array([2002, 2001, 1991, 1999, 2000, 1993, 1996, 1988, 2004, 1998, 1994,2003, 1997, 1983, 1979, 1995, 1982, 1985, 1992, 1986, 1978, 1980,1952, 1987, 1990, 1981, 1989, 1984, 0, 1968, 1961, 1958, 1974,1976, 1971, 1977, 1975, 1965, 1941, 1970, 1962, 1973, 1972, 1960,1966, 1920, 1956, 1959, 1953, 1951, 1942, 1963, 1964, 1969, 1954,1950, 1967, 2005, 1957, 1940, 1937, 1955, 1946, 1936, 1930, 2011,1925, 1948, 1943, 1947, 1945, 1923, 2020, 1939, 1926, 1938, 2030,1911, 1904, 1949, 1932, 1928, 1929, 1927, 1931, 1914, 2050, 1934,1910, 1933, 1902, 1924, 1921, 1900, 2038, 2026, 1944, 1917, 1901,2010, 1908, 1906, 1935, 1806, 2021, '2000', '1995', '1999', '2004','2003', '1990', '1994', '1986', '1989', '2002', '1981', '1993','1983', '1982', '1976', '1991', '1977', '1998', '1992', '1996','0', '1997', '2001', '1974', '1968', '1987', '1984', '1988','1963', '1956', '1970', '1985', '1978', '1973', '1980', '1979','1975', '1969', '1961', '1965', '1939', '1958', '1950', '1953','1966', '1971', '1959', '1972', '1955', '1957', '1945', '1960','1967', '1932', '1924', '1964', '2012', '1911', '1927', '1948','1962', '2006', '1952', '1940', '1951', '1931', '1954', '2005','1930', '1941', '1944', 'DK Publishing Inc', '1943', '1938','1900', '1942', '1923', '1920', '1933', 'Gallimard', '1909','1946', '2008', '1378', '2030', '1936', '1947', '2011', '2020','1919', '1949', '1922', '1897', '2024', '1376', '1926', '2037'],dtype=object)

yearOfPublication中有一些不正確的條目。

由于csv文件中的一些錯(cuò)誤,發(fā)布商名稱'DK Publishing Inc'和'Gallimard'在數(shù)據(jù)集中被錯(cuò)誤地加載為yearOfPublication。

此外,某些值是字符串,并且在某些地方已將相同年份作為數(shù)字輸入。

我們將對(duì)這些行進(jìn)行必要的更正,并將yearOfPublication的數(shù)據(jù)類型設(shè)置為int。

books.loc[books.yearOfPublication == 'DK Publishing Inc',:]

從上面可以看出,bookAuthor錯(cuò)誤地裝載了bookTitle,因此需要進(jìn)行修正。

# ISBN '0789466953' books.loc[books.ISBN == '0789466953','yearOfPublication'] = 2000 books.loc[books.ISBN == '0789466953','bookAuthor'] = "James Buckley" books.loc[books.ISBN == '0789466953','publisher'] = "DK Publishing Inc" books.loc[books.ISBN == '0789466953','bookTitle'] = "DK Readers: Creating the X-Men, How Comic Books Come to Life (Level 4: Proficient Readers)" #ISBN '078946697X' books.loc[books.ISBN == '078946697X','yearOfPublication'] = 2000 books.loc[books.ISBN == '078946697X','bookAuthor'] = "Michael Teitelbaum" books.loc[books.ISBN == '078946697X','publisher'] = "DK Publishing Inc" books.loc[books.ISBN == '078946697X','bookTitle'] = "DK Readers: Creating the X-Men, How It All Began (Level 4: Proficient Readers)" books.loc[(books.ISBN == '0789466953') | (books.ISBN == '078946697X'),:]

繼續(xù)糾正出版年鑒的類型

books.yearOfPublication=pd.to_numeric(books.yearOfPublication, errors='coerce') sorted(books['yearOfPublication'].unique()) [0, 1376, 1378, 1806, 1897, 1900, 1901, 1902, 1904, 1906, 1908, 1909, 1910, 1911, 1914, 1917, 1919, 1920, 1921, 1922, 1923, 1924, 1925, 1926, 1927, 1928, 1929, 1930, 1931, 1932, 1933, 1934, 1935, 1936, 1937, 1938, 1939, 1940, 1941, 1942, 1943, 1944, 1945, 1946, 1947, 1948, 1949, 1950, 1951, 1952, 1953, 1954, 1955, 1956, 1957, 1958, 1959, 1960, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1971, 1972, 1973, 1974, 1975, 1976, 1977, 1978, 1979, 1980, 1981, 1982, 1983, 1984, 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2008, 2010, 2011, 2012, 2020, 2021, 2024, 2026, 2030, 2037, 2038, 2050]

現(xiàn)在可以看出yearOfPublication的類型為int,其值范圍為0-2050。

由于該數(shù)據(jù)集建于2004年,我假設(shè)2006年之后的所有年份都無效,保留兩年的保證金,以防數(shù)據(jù)集可能已更新。

對(duì)于所有無效條目(包括0),我將這些條目轉(zhuǎn)換為NaN,然后??用剩余年份的平均值替換它們。

books.loc[(books.yearOfPublication > 2006) | (books.yearOfPublication == 0),'yearOfPublication'] = np.NAN

用年出版的平均價(jià)值代替NaNs在案例數(shù)據(jù)集被更新的情況下保留一定的空白

books.yearOfPublication.fillna(round(books.yearOfPublication.mean()), inplace=True) books.yearOfPublication.isnull().sum() 0

將dtype重置為int32

books.yearOfPublication = books.yearOfPublication.astype(np.int32)

?

publisher

來到“publisher”專欄,我已經(jīng)處理了兩個(gè)NaN值,將其替換為“其他”,因?yàn)樵谶M(jìn)行一些調(diào)查后無法推斷出版商名稱(檢查jupyter notebook embed)。

books.loc[books.publisher.isnull(),:]

調(diào)查有NaNs的行

以“Tyrant Moon”的書名來查看是否能得到任何線索

books.loc[(books.bookTitle == 'Tyrant Moon'),:]

檢查行是否有書簽作為查找器,看看我們是否能得到任何線索

與不同的出版商和圖書作者的所有行

books.loc[(books.bookTitle == 'Finders Keepers'),:]

由圖書作者檢查以找到模式

都有不同的出版商。這里沒有線索

books.loc[(books.bookAuthor == 'Elaine Corvidae'),:]

由圖書作者檢查以找到模式

books.loc[(books.bookAuthor == 'Linnea Sinclair'),:]

?

因?yàn)闆]有什么共同的東西可以推斷出NaNs的發(fā)布者,將它們替換為“other”

books.loc[(books.ISBN == '193169656X'),'publisher'] = 'other' books.loc[(books.ISBN == '1931696993'),'publisher'] = 'other'

?

用戶數(shù)據(jù)集

現(xiàn)在我們探索用戶數(shù)據(jù)集,首先檢查其形狀,前幾列和數(shù)據(jù)類型。

print (users.shape) users.head()

users.dtypes userID int64 Location object Age float64 dtype: object

userID

users.userID.values array([ 1, 2, 3, ..., 278856, 278857, 278858], dtype=int64)

?

Age

檢查唯一值后,userID看起來正確。但是,Age列具有NaN和一些非常高的值。在我看來,5歲以下和90歲以上的年齡沒有多大意義,因此,這些正在被NaN取代。然后將所有NaN替換為Age的平均值,并將其數(shù)據(jù)類型設(shè)置為int。

sorted(users.Age.unique()) [nan, 0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0, 17.0, 18.0, 19.0, 20.0, 21.0, 22.0, 23.0, 24.0, 25.0, 26.0, 27.0, 28.0, 29.0, 30.0, 31.0, 32.0, 33.0, 34.0, 35.0, 36.0, 37.0, 38.0, 39.0, 40.0, 41.0, 42.0, 43.0, 44.0, 45.0, 46.0, 47.0, 48.0, 49.0, 50.0, 51.0, 52.0, 53.0, 54.0, 55.0, 56.0, 57.0, 58.0, 59.0, 60.0, 61.0, 62.0, 63.0, 64.0, 65.0, 66.0, 67.0, 68.0, 69.0, 70.0, 71.0, 72.0, 73.0, 74.0, 75.0, 76.0, 77.0, 78.0, 79.0, 80.0, 81.0, 82.0, 83.0, 84.0, 85.0, 86.0, 87.0, 88.0, 89.0, 90.0, 91.0, 92.0, 93.0, 94.0, 95.0, 96.0, 97.0, 98.0, 99.0, 100.0, 101.0, 102.0, 103.0, 104.0, 105.0, 106.0, 107.0, 108.0, 109.0, 110.0, 111.0, 113.0, 114.0, 115.0, 116.0, 118.0, 119.0, 123.0, 124.0, 127.0, 128.0, 132.0, 133.0, 136.0, 137.0, 138.0, 140.0, 141.0, 143.0, 146.0, 147.0, 148.0, 151.0, 152.0, 156.0, 157.0, 159.0, 162.0, 168.0, 172.0, 175.0, 183.0, 186.0, 189.0, 199.0, 200.0, 201.0, 204.0, 207.0, 208.0, 209.0, 210.0, 212.0, 219.0, 220.0, 223.0, 226.0, 228.0, 229.0, 230.0, 231.0, 237.0, 239.0, 244.0]

年齡欄有一些無效的條目,比如nan,0和非常高的值,比如100和以上

在我看來,低于5和90以上的值對(duì)我們的圖書評(píng)級(jí)案例沒有多大意義。因此,用NaNs替換這些

users.loc[(users.Age > 90) | (users.Age < 5), 'Age'] = np.nan

用平均值代替NaN

users.Age = users.Age.fillna(users.Age.mean())

將數(shù)據(jù)類型設(shè)置為int

users.Age = users.Age.astype(np.int32) sorted(users.Age.unique()) [5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90]

我這里沒有對(duì)Location列進(jìn)行任何處理。但是,如果您希望可以進(jìn)一步將其拆分為城市,州,國(guó)家,并使用文本處理模型進(jìn)行一些處理。

?

評(píng)級(jí)數(shù)據(jù)集

我們檢查評(píng)級(jí)數(shù)據(jù)集的形狀和前幾行。它揭示了我們的用戶手冊(cè)評(píng)級(jí)矩陣將非常稀疏,因?yàn)榕c評(píng)級(jí)矩陣的大小(用戶數(shù)量×?xí)當(dāng)?shù)量)相比,實(shí)際評(píng)級(jí)非常低。

ratings.shape (1149780, 3)

如果每個(gè)用戶對(duì)每個(gè)條目進(jìn)行評(píng)級(jí),那么評(píng)級(jí)數(shù)據(jù)集將有nusers * nbooks條目,這表明數(shù)據(jù)集非常稀疏。

n_users = users.shape[0] n_books = books.shape[0] print (n_users * n_books) 75670906880 ratings.head(5)

ratings.bookRating.unique() array([ 0, 5, 3, 6, 8, 7, 10, 9, 4, 1, 2], dtype=int64)

除非將新書添加到圖書數(shù)據(jù)集中,否則評(píng)級(jí)數(shù)據(jù)集應(yīng)該只存在于我們的圖書數(shù)據(jù)集里的書籍。

ratings_new = ratings[ratings.ISBN.isin(books.ISBN)] print (ratings.shape) print (ratings_new.shape) (1149780, 3) (1031136, 3)

可以看到,有許多行,有圖書ISBN,而不是書籍?dāng)?shù)據(jù)集的一部分被刪除了

除非新用戶被添加到用戶數(shù)據(jù)集,否則評(píng)級(jí)數(shù)據(jù)集應(yīng)該有來自用戶數(shù)據(jù)集的用戶的評(píng)級(jí)。

ratings = ratings[ratings.userID.isin(users.userID)] print (ratings.shape) print (ratings_new.shape) (1149780, 3) (1031136, 3)

沒有新用戶添加,因此我們將使用高于數(shù)據(jù)集的新用戶(1031136,3)

print ("number of users: " + str(n_users)) print ("number of books: " + str(n_books)) number of users: 278858 number of books: 271360

很明顯,用戶已經(jīng)評(píng)價(jià)了一些書籍,這些書籍不是原始書籍?dāng)?shù)據(jù)集的一部分。數(shù)據(jù)集的稀疏度可以如下計(jì)算:

sparsity=1.0-len(ratings_new)/float(n_users*n_books) print ('圖書交叉數(shù)據(jù)集的稀疏級(jí)別是 ' + str(sparsity*100) + ' %') 圖書交叉數(shù)據(jù)集的稀疏級(jí)別是 99.99863734155898 %

由1-10表示的顯式評(píng)級(jí)和由0表示的隱含評(píng)級(jí)現(xiàn)在必須分開。我們將僅使用明確的評(píng)級(jí)來構(gòu)建我們的圖書推薦系統(tǒng)。同樣,用戶也被分為明確評(píng)級(jí)的人和記錄其隱性行為的人。

ratings.bookRating.unique() array([ 0, 5, 3, 6, 8, 7, 10, 9, 4, 1, 2], dtype=int64)

因此,對(duì)隱式和顯式的評(píng)級(jí)數(shù)據(jù)集進(jìn)行了劃分

ratings_explicit = ratings_new[ratings_new.bookRating != 0] ratings_implicit = ratings_new[ratings_new.bookRating == 0] print (ratings_new.shape) print( ratings_explicit.shape) print (ratings_implicit.shape) (1031136, 3) (383842, 3) (647294, 3)

統(tǒng)計(jì)

bookRating的計(jì)數(shù)圖表示更高的評(píng)級(jí)在用戶中更常見,評(píng)級(jí)8的評(píng)級(jí)最高。

sns.countplot(data=ratings_explicit , x='bookRating') plt.show()

?

基于簡(jiǎn)單流行度的推薦系統(tǒng)

此時(shí),可以基于不同書籍的用戶評(píng)級(jí)的計(jì)數(shù)來構(gòu)建基于簡(jiǎn)單流行度的推薦系統(tǒng)。很明顯,?J. K. Rowling撰寫的書很受歡迎。

ratings_count = pd.DataFrame(ratings_explicit.groupby(['ISBN'])['bookRating'].sum()) top10 = ratings_count.sort_values('bookRating', ascending = False).head(10) print ("推薦下列書籍") top10.merge(books, left_index = True, right_on = 'ISBN')

類似地隔離那些在1-10中給出明確評(píng)分的用戶以及那些隱含行為被跟蹤的用戶

users_exp_ratings = users[users.userID.isin(ratings_explicit.userID)] users_imp_ratings = users[users.userID.isin(ratings_implicit.userID)] print (users.shape) print (users_exp_ratings.shape) print (users_imp_ratings.shape) (278858, 3) (68091, 3) (52451, 3)

?

基于協(xié)同過濾的推薦系統(tǒng)

為了應(yīng)對(duì)我的機(jī)器具有的計(jì)算能力并減少數(shù)據(jù)集大小,我正在考慮已經(jīng)評(píng)定至少100本書籍和至少有100個(gè)評(píng)級(jí)的書籍的用戶。

counts1 = ratings_explicit['userID'].value_counts() ratings_explicit = ratings_explicit[ratings_explicit['userID'].isin(counts1[counts1 >= 100].index)] counts = ratings_explicit['bookRating'].value_counts() ratings_explicit = ratings_explicit[ratings_explicit['bookRating'].isin(counts[counts >= 100].index)]

從顯式的評(píng)級(jí)表生成評(píng)級(jí)矩陣

構(gòu)建基于CF的推薦系統(tǒng)的下一個(gè)關(guān)鍵步驟是從評(píng)級(jí)表生成用戶項(xiàng)目評(píng)級(jí)矩陣。

ratings_matrix = ratings_explicit.pivot(index='userID', columns='ISBN', values='bookRating') userID = ratings_matrix.index ISBN = ratings_matrix.columns print(ratings_matrix.shape) ratings_matrix.head()

?

n_users = ratings_matrix.shape[0] #只考慮那些給出明確評(píng)級(jí)的用戶 n_books = ratings_matrix.shape[1] print (n_users, n_books) 449 66574

因?yàn)镹aN不能通過訓(xùn)練算法來處理,將它們替換為0,這表示沒有評(píng)級(jí)

設(shè)置數(shù)據(jù)類型

ratings_matrix.fillna(0, inplace = True) ratings_matrix = ratings_matrix.astype(np.int32) ratings_matrix.head(5)

復(fù)查稀疏

sparsity=1.0-len(ratings_explicit)/float(users_exp_ratings.shape[0]*n_books) print ('圖書交叉數(shù)據(jù)集的稀疏級(jí)別是 ' + str(sparsity*100) + ' %') 圖書交叉數(shù)據(jù)集的稀疏級(jí)別是 99.99772184106935 %

?

基于用戶的協(xié)同過濾

我將重用我的基于CF的推薦系統(tǒng)示例的功能。函數(shù)findksimilarusers輸入userID和rating矩陣并返回k個(gè)類似用戶的相似性和索引。(閱讀我之前的故事,了解基于用戶/項(xiàng)目的CF方法的概念和公式)

這個(gè)函數(shù)找到k個(gè)相似的用戶,給定用戶id和評(píng)級(jí)矩陣

這些相似點(diǎn)是通過使用配對(duì)距離獲得的

def findksimilarusers(user_id, ratings, metric = metric, k=k):similarities=[]indices=[]model_knn = NearestNeighbors(metric = metric, algorithm = 'brute') model_knn.fit(ratings)loc = ratings.index.get_loc(user_id)distances, indices = model_knn.kneighbors(ratings.iloc[loc, :].values.reshape(1, -1), n_neighbors = k+1)similarities = 1-distances.flatten()return similarities,indices

函數(shù)predict_userbased基于基于用戶的方法預(yù)測(cè)指定用戶 - 項(xiàng)目組合的評(píng)級(jí)。

def predict_userbased(user_id, item_id, ratings, metric = metric, k=k):prediction=0user_loc = ratings.index.get_loc(user_id)item_loc = ratings.columns.get_loc(item_id)similarities, indices=findksimilarusers(user_id, ratings,metric, k) #similar users based on cosine similaritymean_rating = ratings.iloc[user_loc,:].mean() #to adjust for zero based indexingsum_wt = np.sum(similarities)-1product=1wtd_sum = 0 for i in range(0, len(indices.flatten())):if indices.flatten()[i] == user_loc:continue;else: ratings_diff = ratings.iloc[indices.flatten()[i],item_loc]-np.mean(ratings.iloc[indices.flatten()[i],:])product = ratings_diff * (similarities[i])wtd_sum = wtd_sum + product#在非常稀疏的數(shù)據(jù)集的情況下,使用基于協(xié)作的方法的相關(guān)度量可能會(huì)給出負(fù)面的評(píng)價(jià)#在這里的處理如下if prediction <= 0:prediction = 1 elif prediction >10:prediction = 10prediction = int(round(mean_rating + (wtd_sum/sum_wt)))print ('用戶預(yù)測(cè)等級(jí) {0} -> item {1}: {2}'.format(user_id,item_id,prediction))return prediction

測(cè)試

predict_userbased(11676,'0001056107',ratings_matrix) 用戶預(yù)測(cè)等級(jí) 11676 -> item 0001056107: 2

功能recommendedItem使用上述功能來推薦基于用戶或基于項(xiàng)目的方法的書籍(基于所選方法和度量組合)。如果圖書的預(yù)測(cè)評(píng)級(jí)大于或等于6,并且圖書尚未評(píng)級(jí),則會(huì)提出建議。您可以在調(diào)用此函數(shù)時(shí)選擇相似性度量(余弦/相關(guān))。

而且Voila !!!?根據(jù)基于用戶的CF方法,檢查用戶4385的前10本書籍建議。

?

基于項(xiàng)目的協(xié)同過濾

已經(jīng)為基于項(xiàng)目的CF編寫了類似的函數(shù)來查找類似的書籍并預(yù)測(cè)用戶對(duì)每本書的評(píng)級(jí)。相同的功能recommendedItem可用于根據(jù)基于項(xiàng)目的方法和選定的指標(biāo)推薦書籍。如果圖書的預(yù)測(cè)評(píng)級(jí)大于或等于6,并且圖書尚未評(píng)級(jí),則會(huì)提出建議。

def findksimilaritems(item_id, ratings, metric=metric, k=k):similarities=[]indices=[]ratings=ratings.Tloc = ratings.index.get_loc(item_id)model_knn = NearestNeighbors(metric = metric, algorithm = 'brute')model_knn.fit(ratings)distances, indices = model_knn.kneighbors(ratings.iloc[loc, :].values.reshape(1, -1), n_neighbors = k+1)similarities = 1-distances.flatten()return similarities,indices def predict_itembased(user_id, item_id, ratings, metric = metric, k=k):prediction= wtd_sum =0user_loc = ratings.index.get_loc(user_id)item_loc = ratings.columns.get_loc(item_id)similarities, indices=findksimilaritems(item_id, ratings) #similar users based on correlation coefficientssum_wt = np.sum(similarities)-1product=1for i in range(0, len(indices.flatten())):if indices.flatten()[i] == item_loc:continue;else:product = ratings.iloc[user_loc,indices.flatten()[i]] * (similarities[i])wtd_sum = wtd_sum + product prediction = int(round(wtd_sum/sum_wt))#在非常稀疏的數(shù)據(jù)集的情況下,使用基于協(xié)作的方法的相關(guān)度量可能會(huì)給出負(fù)面的評(píng)價(jià)#在這里處理的是下面的//代碼,沒有下面的代碼片段,下面的代碼片段是為了避免負(fù)面影響#在使用相關(guān)度規(guī)時(shí),可能會(huì)出現(xiàn)非常稀疏的數(shù)據(jù)集的預(yù)測(cè)if prediction <= 0:prediction = 1 elif prediction >10:prediction = 10print ('用戶預(yù)測(cè)等級(jí) {0} -> item {1}: {2}'.format(user_id,item_id,prediction) ) return prediction

測(cè)試

prediction = predict_itembased(11676,'0001056107',ratings_matrix) 用戶預(yù)測(cè)等級(jí) 11676 -> item 0001056107: 1

哇!!!根據(jù)基于項(xiàng)目的CF方法檢查用戶4385的前10本書籍建議。這些與基于用戶的方法建議的顯著不同。

?

代碼

原文代碼:

在這篇文章中,交叉驗(yàn)證,測(cè)試列車拆分和推薦系統(tǒng)評(píng)估等領(lǐng)域尚未涉及,這些領(lǐng)域值得探討。這段代碼的Jupyter筆記本:https://github.com/csaluja/JupyterNotebooks-Medium/blob/master/Book%20Recommendation%20System.ipynb

本人翻譯的代碼:

https://github.com/935048000/BookRecommendationSystem

?

?

原文:https://towardsdatascience.com/my-journey-to-building-book-recommendation-system-5ec959c41847

?

總結(jié)

以上是生活随笔為你收集整理的【推荐系统】基于协同过滤的图书推荐系统的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。