{"id":2289,"date":"2019-11-13T16:17:19","date_gmt":"2019-11-13T08:17:19","guid":{"rendered":"http:\/\/www.sniper97.cn\/?p=2289"},"modified":"2019-11-13T16:17:19","modified_gmt":"2019-11-13T08:17:19","slug":"%e3%80%90%e6%9c%ba%e5%99%a8%e5%ad%a6%e4%b9%a0%e3%80%91%e6%8e%a8%e8%8d%90%e7%b3%bb%e7%bb%9f","status":"publish","type":"post","link":"http:\/\/www.sniper97.cn\/index.php\/note\/machine-learning-in-action\/2289\/","title":{"rendered":"\u3010\u5434\u6069\u8fbe\u673a\u5668\u5b66\u4e60\u3011\u63a8\u8350\u7cfb\u7edf"},"content":{"rendered":"\n<p> \u5434\u6069\u8fbeMachine-Learning \u7b2c\u4e5d\u5468\uff1a\u63a8\u8350\u7cfb\u7edf\uff08Recommender system\uff09<\/p>\n\n\n<p>\u63a8\u8350\u7cfb\u7edf\u5373\u901a\u8fc7\u7528\u6237\u5bf9\u4e00\u4e9b\u7528\u6237\u7684\u6253\u5206\u800c\u8ba1\u7b97\u51fa\u7528\u6237\u53ef\u80fd\u611f\u5174\u8da3\u7684\u5176\u4ed6\u4e1c\u897f\u3002<\/p>\n\n\n<p>\u6211\u4eec\u4f7f\u7528\u4e24\u4e2a\u53d8\u91cf\uff0c\u5206\u522b\u4ee3\u8868\u7528\u6237\u7684\u559c\u597d\u5411\u91cf\u548c\u7535\u5f71\u7684\u7279\u5f81\u5411\u91cf<\/p>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"199\" height=\"92\" src=\"\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-104.png\" alt=\"\" class=\"wp-image-2290\"\/><\/figure><\/div>\n\n\n<p>\u6211\u4eec\u4f7f\u7528\u8fd9\u4e24\u4e2a\u5411\u91cf\uff0c\u5c31\u53ef\u4ee5\u8ba1\u7b97\u51fa\u7528\u6237\u5bf9\u67d0\u4e00\u7535\u5f71\u53ef\u80fd\u7684\u8bc4\u5206\uff0c\u4ece\u800c\u8fdb\u884c\u63a8\u8350\u3002<\/p>\n\n\n<p>\u90a3\u4e48\u6211\u4eec\u600e\u4e48\u5f97\u5230\u7528\u6237\u7684\u53c2\u6570\u5411\u91cf\u548c\u7279\u5f81\u5411\u91cf\u5462\uff1f\u6211\u4eec\u4f7f\u7528\u534f\u540c\u8fc7\u6ee4\uff0c\u5728\u8ba1\u7b97\u51fatheta\u548cx\u5411\u91cf\uff1a<\/p>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"744\" height=\"79\" src=\"\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-105.png\" alt=\"\" class=\"wp-image-2291\" srcset=\"http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-105.png 744w, http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-105-300x32.png 300w\" sizes=\"(max-width: 744px) 100vw, 744px\" \/><\/figure><\/div>\n\n\n<p>\u5e76\u8ba1\u7b97\u5bfc\u51fd\u6570\u7528\u6765\u8fdb\u884c\u68af\u5ea6\u4e0b\u964d\uff1a<\/p>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"501\" height=\"174\" src=\"\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-106.png\" alt=\"\" class=\"wp-image-2292\" srcset=\"http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-106.png 501w, http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-106-300x104.png 300w\" sizes=\"(max-width: 501px) 100vw, 501px\" \/><\/figure><\/div>\n\n\n<p>\u90a3\u4e48\u5982\u679c\u65b0\u589e\u4e00\u4e2a\u7528\u6237\uff0c\u6211\u4eec\u4e3a\u4ed6\u63a8\u8350\u7535\u5f71\u5462\uff1f<\/p>\n\n\n<p>\u90a3\u6211\u4eec\u5c31\u5148\u8ba1\u7b97\u4e00\u4e2a\u5df2\u6253\u5206\u7684\u5e73\u5747\u503c\uff0c\u518d\u5c06\u6570\u636e\u90fd\u51cf\u53bb\u8fd9\u4e2a\u5e73\u5747\u503c\uff0c\u8fd9\u6837\uff0c\u6211\u4eec\u5c06\u8ba1\u7b97\u51fa\u6765\u9884\u6d4b\u7684\u5206\u52a0\u4e0a\u5e73\u5747\u5206\u4f5c\u4e3a\u9884\u6d4b\u7684\u5206\uff0c\u8fd9\u6837\u5bf9\u4e8e\u65b0\u7528\u6237\uff0c\u6211\u4eec\u5c31\u53ef\u4ee5\u4e3a\u5176\u63a8\u8350\u5e73\u5747\u5206\u6700\u9ad8\u7684\u7535\u5f71\u4e86\u3002<\/p>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"755\" height=\"151\" src=\"\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-107.png\" alt=\"\" class=\"wp-image-2293\" srcset=\"http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-107.png 755w, http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-107-300x60.png 300w\" sizes=\"(max-width: 755px) 100vw, 755px\" \/><\/figure><\/div>\n\n\n<p>\u4e0b\u9762\u662f\u4ee3\u7801\uff1a<\/p>\n\n\n<p>\u9996\u5148\u5bfc\u5305\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\">import numpy as np<br \/>from scipy.io import loadmat<br \/>import matplotlib.pyplot as plt<br \/>import scipy.optimize as opt<\/pre>\n\n\n<p>\u5bfc\u5165\u548c\u67e5\u770b\u6570\u636e\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\">mat = loadmat('.\/data\/ex8_movies.mat')<br \/># dict_keys(['__header__', '__version__', '__globals__', 'Y', 'R'])<br \/>print(mat.keys())<br \/># Y\u662f\u4e0d\u540c\u7535\u6cf3\u7684\u4e0d\u540c\u7528\u6237\u8bc4\u5206\uff0cR\u4ee3\u8868\u7528\u6237i\u5bf9\u7535\u5f71j\u6709\u662f\u5426\u6709\u8bc4\u5206<br \/>Y, R = mat['Y'], mat['R']<br \/>movies_number, user_number = Y.shape<br \/># (1682, 943) (1682, 943)<br \/>print(Y.shape, R.shape)<br \/># # \u8ba1\u7b97\u4e00\u4e0b\u7528\u62370 \u7684\u5e73\u5747\u6253\u5206\u6210\u7ee9  3.8783185840707963<br \/>print(Y[0].sum() \/ R[0].sum())<\/pre>\n\n\n<p>\u67e5\u770b\u4e00\u4e0b\u6570\u636e\u7684\u6837\u5b50\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\"># \u663e\u793a\u4e00\u4e0bY\u77e9\u9635\u7684\u56fe\u793a<br \/>fig = plt.figure(figsize=(8, 8 * (1682. \/ 943.)))<br \/>plt.imshow(Y, cmap='rainbow')<br \/>plt.colorbar()<br \/>plt.ylabel('Movies (%d)' % movies_number, fontsize=20)<br \/>plt.ylabel('USers (%d)' % user_number, fontsize=20)<\/pre>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"688\" height=\"833\" src=\"\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-108.png\" alt=\"\" class=\"wp-image-2294\" srcset=\"http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-108.png 688w, http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-108-248x300.png 248w\" sizes=\"(max-width: 688px) 100vw, 688px\" \/><\/figure><\/div>\n\n\n<p>\u4e0b\u9762\u662f\u534f\u540c\u8fc7\u6ee4\uff0c\u6211\u4eec\u8bfb\u53d6\u5df2\u7ecf\u8ba1\u7b97\u597d\u7684\u7535\u5f71\u53c2\u6570\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\">mat = loadmat('.\/data\/ex8_movieParams.mat')<br \/># dict_keys(['__header__', '__version__', '__globals__', 'X', 'Theta', 'num_users', 'num_movies', 'num_features'])<br \/>print(mat.keys())<br \/><br \/>X = mat['X']<br \/>Theta = mat['Theta']<br \/>num_users = int(mat['num_users'])<br \/>num_movies = int(mat['num_movies'])<br \/>num_features = int(mat['num_features'])<br \/># 943 1682 10<br \/>print(num_users, num_movies, num_features)<br \/># (1682, 10) (943, 10)<br \/>print(X.shape, Theta.shape)<\/pre>\n\n\n<p>\u4e3a\u4e86\u5feb\u901f\u7684\u8ba1\u7b97\uff0c\u6211\u4eec\u5148\u964d\u4f4e\u4e00\u4e0b\u6570\u636e\u7684\u7ef4\u5ea6\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\"># \u964d\u4f4e\u4e00\u4e0b\u6570\u636e\u7684\u5927\u5c0f\uff0c\u76ee\u7684\u662f\u8ba9\u7a0b\u5e8f\u8fd0\u884c\u7684\u66f4\u5feb<br \/>num_users = 4<br \/>num_movies = 5<br \/>num_features = 3<br \/>X = X[:num_movies, :num_features]<br \/>Theta = Theta[:num_users, :num_features]<br \/>Y = Y[:num_movies, :num_users]<br \/>R = R[:num_movies, :num_users]<br \/># (5, 3) (4, 3)<br \/>print(X.shape, Theta.shape)<\/pre>\n\n\n<p>\u7136\u540e\u662f\u5e8f\u5217\u5316\u548c\u53cd\u5e8f\u5217\u5316\u53c2\u6570\uff0c\u4f5c\u7528\u662f\u5c06Theta\u548cX\u62fc\u63a5\uff08\u62c6\u5f00\uff09\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\">def serialize(X, Theta):\n    <em>\"\"\"\n    \u5c55\u5f00\u53c2\u6570\n    <\/em><strong><em>:param<\/em><\/strong><em> X:\u6bcf\u4e2a\u7535\u5f71\u7684\u6253\u5206\n    <\/em><strong><em>:param<\/em><\/strong><em> Theta: \u6bcf\u4e2a\u7528\u6237\u7684\u4e13\u6709\u7535\u5f71\u53c2\u6570\uff1f\u662f\u8fd9\u4e48\u8bf4\u7684\u4e48\n    <\/em><strong><em>:return<\/em><\/strong><em>:\n    \"\"\"\n    <\/em>#\n    return np.r_[X.flatten(), Theta.flatten()]\ndef deserialize(seq, num_movies, num_users, num_features):\n    <em>\"\"\"\n    \u63d0\u53d6\u53c2\u6570\n    <\/em><strong><em>:param<\/em><\/strong><em> seq:\n    <\/em><strong><em>:param<\/em><\/strong><em> num_movies: \u7535\u5f71\u6570\u91cf\n    <\/em><strong><em>:param<\/em><\/strong><em> num_users: \u7528\u6237\u6570\u91cf\n    <\/em><strong><em>:param<\/em><\/strong><em> num_features: \u7279\u5f81\u6570\u91cf\n    <\/em><strong><em>:return<\/em><\/strong><em>:\n    \"\"\"\n    <\/em>return seq[:num_movies * num_features].reshape(num_movies, num_features), seq[num_movies * num_features:].reshape(\n        num_users, num_features)<\/pre>\n\n\n<p>\u7136\u540e\u662f\u8ba1\u7b97\u4ee3\u4ef7\u51fd\u6570\uff1a<\/p>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"744\" height=\"79\" src=\"\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-105.png\" alt=\"\" class=\"wp-image-2291\" srcset=\"http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-105.png 744w, http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-105-300x32.png 300w\" sizes=\"(max-width: 744px) 100vw, 744px\" \/><\/figure><\/div>\n\n\n<pre class=\"wp-block-preformatted\">def cofiCostFunc(params, Y, R, num_movies, num_users, num_features, l=0.0):<br \/>    <em>\"\"\"<br \/><\/em><em>    \u4ee3\u4ef7\u51fd\u6570<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> params: \u4e00\u7ef4\u540e\u7684\u53c2\u6570\uff08X\uff0ctheta\uff09<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> Y: \u8bc4\u5206\u77e9\u9635<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> R: \u6709\u65e0\u8bc4\u5206\u77e9\u9635<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_movies: \u7535\u5f71\u6570\u91cf<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_users: \u7528\u6237\u6570\u91cf<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_features: \u7279\u5f81\u6570\u91cf<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> l: \u6b63\u5219\u5316\u53c2\u6570<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>X, Theta = deserialize(params, num_movies, num_users, num_features)<br \/>    # \u8ba1\u7b97<br \/>    error = 0.5 * np.square((X @ Theta.T - Y) * R).sum()<br \/>    # \u5bf9\u7535\u5f71\u8bc4\u5206\u7684\u6b63\u5219\u5316<br \/>    reg1 = 0.5 * l * np.square(Theta).sum()<br \/>    # \u5bf9\u7535\u5f71\u53c2\u6570\u7684\u6b63\u5219\u5316<br \/>    reg2 = 0.5 * l * np.square(X).sum()<br \/>    return error + reg1 + reg2<\/pre>\n\n\n<p>\u8f93\u51fa\u4e24\u7ec4\u7ed3\u679c\u770b\u770b\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\"># 22.224603725685675<br \/>print(cofiCostFunc(serialize(X, Theta), Y, R, num_movies, num_users, num_features))<br \/># 31.34405624427422<br \/>print(cofiCostFunc(serialize(X, Theta), Y, R, num_movies, num_users, num_features, 1.5))<\/pre>\n\n\n<p>\u68af\u5ea6\u4e0b\u964d\u51fd\u6570\uff1a<\/p>\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><img loading=\"lazy\" decoding=\"async\" width=\"501\" height=\"174\" src=\"\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-106.png\" alt=\"\" class=\"wp-image-2292\" srcset=\"http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-106.png 501w, http:\/\/www.sniper97.cn\/wp-content\/uploads\/2019\/11\/\u56fe\u7247-106-300x104.png 300w\" sizes=\"(max-width: 501px) 100vw, 501px\" \/><\/figure><\/div>\n\n\n<pre class=\"wp-block-preformatted\">def cofiGradient(params, Y, R, num_movies, num_users, num_features, l=0.0):<br \/>    <em>\"\"\"<br \/><\/em><em>    \u8ba1\u7b97X\u548cTheta\u7684\u68af\u5ea6\uff0c\u5e76\u5e8f\u5217\u5316\u8f93\u51fa<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> params:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> Y:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> R:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_movies:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_users:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_features:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> l:<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>X, Theta = deserialize(params, num_movies, num_users, num_features)<br \/>    X_grad = ((X @ Theta.T - Y) * R) @ Theta + 1 * X<br \/>    Theta_grad = ((X @ Theta.T - Y) * R).T @ X + 1 * Theta<br \/>    return serialize(X_grad, Theta_grad)<\/pre>\n\n\n<p>\u5230\u8fd9\u91cc\u6211\u4eec\u5df2\u7ecf\u5177\u5907\u8fd0\u884c\u63a8\u8350\u7cfb\u7edf\u7684\u80fd\u529b\u4e86\uff0c\u4e0b\u9762\u6211\u4eec\u6a21\u62df\u4e00\u4e2a\u65b0\u7528\u6237\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\"># \u8bfb\u53d6\u7535\u5f71\u5217\u8868<br \/>movies = []<br \/>with open('data\/movie_ids.txt', 'r') as f:<br \/>    for line in f:<br \/>        movies.append(''.join(line.strip().split(' ')[1:]))<br \/># \u6a21\u62df\u4e00\u4e2a\u7528\u6237\u7684\u8bc4\u5206<br \/>my_ratings = np.zeros((1682, 1))<br \/>my_ratings[0] = 4<br \/>my_ratings[97] = 2<br \/>my_ratings[6] = 3<br \/>my_ratings[11] = 5<br \/>my_ratings[53] = 4<br \/>my_ratings[63] = 5<br \/>my_ratings[65] = 3<br \/>my_ratings[68] = 5<br \/>my_ratings[182] = 4<br \/>my_ratings[225] = 5<br \/>my_ratings[354] = 5<br \/><br \/>for i in range(len(my_ratings)):<br \/>    if my_ratings[i] &gt; 0:<br \/>        print(my_ratings[i], movies[i])<\/pre>\n\n\n<p>\u8f93\u51fa\u4e0a\u8fb9\u6a21\u62df\u6253\u5206\u7684\u7535\u5f71\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\">\"\"\"<br \/>[4.] ToyStory(1995)<br \/>[3.] TwelveMonkeys(1995)<br \/>[5.] UsualSuspects,The(1995)<br \/>[4.] Outbreak(1995)<br \/>[5.] ShawshankRedemption,The(1994)<br \/>[3.] WhileYouWereSleeping(1995)<br \/>[5.] ForrestGump(1994)<br \/>[2.] SilenceoftheLambs,The(1991)<br \/>[4.] Alien(1979)<br \/>[5.] DieHard2(1990)<br \/>[5.] Sphere(1998)<br \/>\"\"\"<\/pre>\n\n\n<p>\u7136\u540e\u6211\u4eec\u83b7\u53d6\u4e4b\u524d\u7684\u7535\u5f71\u77e9\u9635\uff0c\u5e76\u5c06\u6211\u4eec\u6a21\u62df\u7684\u7528\u6237\u6570\u636e\u6dfb\u52a0\u5230\u77e9\u9635\u5c3e\u90e8\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\"># \u8bfb\u53d6\u7535\u5f71\u6253\u5206\u77e9\u9635\u4ee5\u53ca\u7528\u6237\u6253\u5206\u77e9\u9635<br \/>mat = loadmat('data\/ex8_movies.mat')<br \/>Y, R = mat['Y'], mat['R']<br \/># (1682, 943) (1682, 943)<br \/>print(Y.shape, R.shape)<br \/><br \/># \u5c06\u65b0\u7528\u6237\u7684\u6253\u5206\u6dfb\u52a0\u8fdb\u53bb<br \/>Y = np.concatenate((Y, my_ratings), axis=1)<br \/>R = np.concatenate((R, my_ratings != 0), axis=1)<br \/>num_movies, num_users = Y.shape<br \/># 1682 944<br \/>print(num_movies, num_users)<br \/># \u8bbe\u5b9a\u7279\u5f81\u5411\u91cf\u4e3a10\u4e2a<br \/>num_features = 10<\/pre>\n\n\n<p>\u6c42\u5e73\u5747\u5206\u7684\u51fd\u6570\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\">def normallizeRatings(Y, R):<br \/>    <em>\"\"\"<br \/><\/em><em>    \u8ba1\u7b97\u6253\u8fc7\u5206\u7684\u7535\u5f71\u7684\u5e73\u5747\u503c<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> Y:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> R:<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>Ymean = (Y.sum(axis=1) \/ R.sum(axis=1)).reshape(-1, 1)<br \/>    Ynorm = (Y - Ymean) * R<br \/>    return Ynorm, Ymean<\/pre>\n\n\n<p>\u521d\u59cb\u5316Theta\u548cX\u7684\u53c2\u6570\uff0c\u5e76\u8fdb\u884c\u68af\u5ea6\u4e0b\u964d\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\">X = np.random.random((num_movies, num_features))\nTheta = np.random.random((num_users, num_features))\nparams = serialize(X, Theta)\nl = 10\nres = opt.minimize(fun=cofiCostFunc, x0=params, args=(Y, R, num_movies, num_users, num_features, l), method='TNC',\n                   jac=cofiGradient, options={'maxiter': 100})\nret = res.x\n# [0.95054705 0.35474199 0.67897876 ... 0.23782728 0.76704132 0.79748087]\nprint(ret)<\/pre>\n\n\n<p>\u8ba1\u7b97\u9884\u6d4b\u5206\u6570\u5e76\u8f93\u51fa\u7ed3\u679c\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\">fit_X, fit_Theta = deserialize(ret, num_movies, num_users, num_features)\n# \u8ba1\u7b97\u9884\u6d4b\u5206\u6570\npred_mat = fit_X @ fit_Theta.T\n# \u9884\u6d4b\u5206\u503c+\u5e73\u5747\u503c\npred = pred_mat[:, -1] + Ymean.flatten()\npred_sorted_idx = np.argsort(pred)[::-1]\nprint(\"Top recommendations for you:\")\nfor i in range(10):\n    print('Predicting rating %0.1f for movie %s.' \\\n          % (pred[pred_sorted_idx[i]], movies[pred_sorted_idx[i]]))\n\"\"\"\nTop recommendations for you:\nPredicting rating 9.8 for movie MayaLin:AStrongClearVision(1994).\nPredicting rating 9.7 for movie Schindler'sList(1993).\nPredicting rating 9.6 for movie PatherPanchali(1955).\nPredicting rating 9.3 for movie KasparHauser(1993).\nPredicting rating 9.3 for movie Faust(1994).\nPredicting rating 9.2 for movie Trainspotting(1996).\nPredicting rating 9.2 for movie SomeFolksCallItaSlingBlade(1993).\nPredicting rating 9.2 for movie Prefontaine(1997).\nPredicting rating 9.2 for movie BeautifulThing(1996).\nPredicting rating 9.1 for movie GreatDayinHarlem,A(1994).\n\"\"\"\nprint(\"\\nOriginal ratings provided:\")\nfor i in range(len(my_ratings)):\n    if my_ratings[i] &gt; 0:\n        print('Rated %d for movie %s.' % (my_ratings[i], movies[i]))\n\"\"\"\nOriginal ratings provided:\nRated 4 for movie ToyStory(1995).\nRated 3 for movie TwelveMonkeys(1995).\nRated 5 for movie UsualSuspects,The(1995).\nRated 4 for movie Outbreak(1995).\nRated 5 for movie ShawshankRedemption,The(1994).\nRated 3 for movie WhileYouWereSleeping(1995).\nRated 5 for movie ForrestGump(1994).\nRated 2 for movie SilenceoftheLambs,The(1991).\nRated 4 for movie Alien(1979).\nRated 5 for movie DieHard2(1990).\nRated 5 for movie Sphere(1998).\n\"\"\"<\/pre>\n\n\n<p>\u6574\u7406\u540e\u7684\u4ee3\u7801\uff1a<\/p>\n\n\n<pre class=\"wp-block-preformatted\"># -*- coding:utf-8 -*-<br \/>import numpy as np<br \/>from scipy.io import loadmat<br \/>import matplotlib.pyplot as plt<br \/>import scipy.optimize as opt<br \/><br \/><br \/>def load_movies():<br \/>    <em>\"\"\"<br \/><\/em><em>    \u8bfb\u53d6\u7535\u5f71\u8bc4\u8bba<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>mat = loadmat('.\/data\/ex8_movies.mat')<br \/>    Y, R = mat['Y'], mat['R']<br \/>    num_movies, num_users = Y.shape<br \/>    return Y, R, num_movies, num_users<br \/><br \/><br \/>def load_params():<br \/>    <em>\"\"\"<br \/><\/em><em>    \u8bfb\u53d6\u7535\u5f71\u53c2\u6570<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>mat = loadmat('.\/data\/ex8_movieParams.mat')<br \/>    X = mat['X']<br \/>    Theta = mat['Theta']<br \/>    num_users = int(mat['num_users'])<br \/>    num_movies = int(mat['num_movies'])<br \/>    num_features = int(mat['num_features'])<br \/>    return X, Theta, num_movies, num_users, num_features<br \/><br \/><br \/>def load_movies_idx():<br \/>    <em>\"\"\"<br \/><\/em><em>    \u8bfb\u53d6\u7535\u5f71\u5217\u8868<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>movies = []<br \/>    with open('data\/movie_ids.txt', 'r') as f:<br \/>        for line in f:<br \/>            movies.append(''.join(line.strip().split(' ')[1:]))<br \/>    return movies<br \/><br \/><br \/>def serialize(X, Theta):<br \/>    <em>\"\"\"<br \/><\/em><em>    \u5e8f\u5217\u5316\u53c2\u6570<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> X:\u7528\u6237\u53c2\u6570\u5411\u91cf<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> Theta:\u7535\u5f71\u7279\u5f81\u5411\u91cf<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>return np.concatenate((X, Theta))<br \/><br \/><br \/>def deserialize(params, num_movies, num_users, num_features):<br \/>    <em>\"\"\"<br \/><\/em><em>    \u53cd\u5e8f\u5217\u5316<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> params: \u53c2\u6570<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_movies: \u7535\u5f71\u6570\u91cf<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_users: \u7528\u6237\u6570\u91cf<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_features: \u7279\u5f81\u6570\u91cf<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>return params[:num_movies * num_features].reshape(num_movies, num_features), params[<br \/>                                                                                 num_movies * num_features:].reshape(<br \/>        num_users, num_features)<br \/><br \/><br \/>def cofiCostFunc(params, Y, R, num_movies, num_users, num_features, l=0.0):<br \/>    <em>\"\"\"<br \/><\/em><em><br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> params:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> Y:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> R:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_movies:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_users:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_features:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> l:<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>X, Theta = deserialize(params, num_movies, num_users, num_features)<br \/>    error = 0.5 * np.square((X @ Theta.T * Y) * R).sum()<br \/>    reg_1 = 0.5 * np.square(Theta).sum()<br \/>    reg_2 = 0.5 * np.square(X).sum()<br \/>    return error + reg_1 + reg_2<br \/><br \/><br \/>def cofiGradient(params, Y, R, num_movies, num_users, num_features, l=0.0):<br \/>    <em>\"\"\"<br \/><\/em><em>    \u68af\u5ea6\u4e0b\u964d<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> params:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> Y:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> R:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_movies:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_users:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> num_features:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> l:<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>X, Theta = deserialize(params, num_movies, num_users, num_features)<br \/>    X_grad = ((X @ Theta.T - Y) * R) @ Theta + 1 * X<br \/>    Theta_grad = ((X @ Theta.T - Y) * R).T @ X + 1 * Theta<br \/>    return serialize(X_grad, Theta_grad)<br \/><br \/><br \/>def normallizeRatings(Y, R):<br \/>    <em>\"\"\"<br \/><\/em><em>    \u6c42\u5747\u503c<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> Y:<br \/><\/em><em>    <\/em><strong><em>:param<\/em><\/strong><em> R:<br \/><\/em><em>    <\/em><strong><em>:return<\/em><\/strong><em>:<br \/><\/em><em>    \"\"\"<br \/><\/em><em>    <\/em>return (Y.sum(axis=1) \/ R.sum(axis=1)).reshape(-1, 1)<br \/><br \/><br \/>if __name__ == '__main__':<br \/>    Y, R, _, _ = load_movies()<br \/>    # X, Theta, _, _, _ = load_params()<br \/>    movies_idx = load_movies_idx()<br \/>    # \u6a21\u62df\u7528\u6237<br \/>    my_ratings = np.zeros((1682, 1))<br \/>    my_ratings[0] = 4<br \/>    my_ratings[97] = 2<br \/>    my_ratings[6] = 3<br \/>    my_ratings[11] = 5<br \/>    my_ratings[53] = 4<br \/>    my_ratings[63] = 5<br \/>    my_ratings[65] = 3<br \/>    my_ratings[68] = 5<br \/>    my_ratings[182] = 4<br \/>    my_ratings[225] = 5<br \/>    my_ratings[354] = 5<br \/>    Y = np.concatenate((Y, my_ratings), axis=1)<br \/>    R = np.concatenate((R, my_ratings != 0), axis=1)<br \/>    num_movies, num_users = Y.shape<br \/>    num_features = 10<br \/>    X = np.random.random((num_movies, num_features))<br \/>    Theta = np.random.random((num_users, num_features))<br \/>    params = serialize(X, Theta)<br \/>    Ymean = normallizeRatings(Y, R)<br \/>    l = 10<br \/>    res = opt.minimize(fun=cofiCostFunc, x0=params, args=(Y, R, num_movies, num_users, num_features, l),<br \/>                       jac=cofiGradient, method='TNC', options={'maxiter': 100})<br \/>    ret = res.x<br \/>    fit_X, fit_Theta = deserialize(ret, num_movies, num_users, num_features)<br \/>    pred_mat = fit_X @ fit_Theta.T<br \/>    pred = pred_mat[:, -1] + Ymean.flatten()<br \/>    pred_sorted_idx = np.argsort(pred)[::-1]<br \/>    print(\"Top recommendations for you:\")<br \/>    for i in range(10):<br \/>        print('Predicting rating %0.1f for movie %s.' \\<br \/>              % (pred[pred_sorted_idx[i]], movies_idx[pred_sorted_idx[i]]))<br \/><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>\u5434\u6069\u8fbeMachine-Learning \u7b2c\u4e5d\u5468\uff1a\u63a8\u8350\u7cfb\u7edf\uff08Recommender system\uff09 \u63a8 [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_mi_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[6],"tags":[],"views":6007,"_links":{"self":[{"href":"http:\/\/www.sniper97.cn\/index.php\/wp-json\/wp\/v2\/posts\/2289"}],"collection":[{"href":"http:\/\/www.sniper97.cn\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.sniper97.cn\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.sniper97.cn\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.sniper97.cn\/index.php\/wp-json\/wp\/v2\/comments?post=2289"}],"version-history":[{"count":0,"href":"http:\/\/www.sniper97.cn\/index.php\/wp-json\/wp\/v2\/posts\/2289\/revisions"}],"wp:attachment":[{"href":"http:\/\/www.sniper97.cn\/index.php\/wp-json\/wp\/v2\/media?parent=2289"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.sniper97.cn\/index.php\/wp-json\/wp\/v2\/categories?post=2289"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.sniper97.cn\/index.php\/wp-json\/wp\/v2\/tags?post=2289"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}