AI ninja project [day 6] 最近邻推荐系统

参考资料:
https://medium.com/learning-machine-learning/recommending-animes-using-nearest-neighbors-61320a1a5934

这里介绍的推荐系统模型是在资料数据量不是很多时,
使用KNN演算法来进行预测,
要是资料量跟数据维度更多时,可以在Kaggle 搜寻其他人使用Netflex资料建立的推荐系统。

https://www.kaggle.com/netflix-inc/netflix-prize-data/code

那本篇资料集是使用kaggle的Anime Recommendations Database,
https://www.kaggle.com/CooperUnion/anime-recommendations-database。

引用模组

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import re
import seaborn as sns

资料及汇入pandas dataframe

anime = pd.read_csv("anime.csv")

特定类别集数通常是一集

anime.loc[(anime["genre"]=="Hentai") & (anime["episodes"]=="Unknown"),"episodes"] = "1"
anime.loc[(anime["type"]=="OVA") & (anime["episodes"]=="Unknown"),"episodes"] = "1"
anime.loc[(anime["type"] == "Movie") & (anime["episodes"] == "Unknown")] = "1"

未知集数,填上平均值
将Unknown即没有填的资料换成平均值

anime["episodes"] = anime["episodes"].map(lambda x:np.nan if x=="Unknown" else x)
anime["episodes"].fillna(anime["episodes"].median(),inplace = True)

rating特徵转浮点数,空值补平均值
members特徵转成浮点数

anime["rating"] = anime["rating"].astype(float)
anime["rating"].fillna(anime["rating"].median(),inplace = True)

anime["members"] = anime["members"].astype(float)

将genre特徵转换成onehot encoder

anime_features = pd.concat([anime["genre"].str.get_dummies(sep=","),
                            pd.get_dummies(anime[["type"]]),
                            anime[["rating"]],anime[["members"]],anime["episodes"]],axis=1)

使用MinMaxScaler 帮助标准化 加速运算速度

from sklearn.preprocessing import MinMaxScaler

min_max_scaler = MinMaxScaler()
anime_features = min_max_scaler.fit_transform(anime_features)
np.round(anime_features,decimals=2)

引入最近邻

from sklearn.neighbors import NearestNeighbors
nbrs = NearestNeighbors(n_neighbors=4, algorithm='ball_tree').fit(anime_features)
distances, indices = nbrs.kneighbors(anime_features)

indices 为一个[],第一个element 是动画自己的ID,後面的element是最相似(推荐的)的动画ID

设立function帮助查找

def get_index_from_name(name):
    return anime[anime["name"]==name].index.tolist()[0]

所有anime 的名称

all_anime_names = list(anime.name.values) 

搜寻相似的动画

def print_similar_animes(query=None,id=None):
    if id:
        for id in indices[id][1:]:
            print(anime.loc[id]["name"])
    if query:
        found_id = get_index_from_name(query)
        for id in indices[found_id][1:]:
            print(anime.loc[id]["name"])            


print_similar_animes(query="Naruto")

<<:  [Day06] CH04:我已读你的已读——认识 Scanner

>>:  鬼故事 - 我们有通过国际资安 OOO 标准

Day 11-假物件 (Fake) - 虚设常式 (Stub)-3 (核心技术-3)

看程序码说故事-3 在昨天 Day-10 把 EmailSystem 从 JJEmail 这只套件抽...

D-17 路由 ? Routing

路由的介绍 在历经昨天网页程序的基础知识的介绍之後,今天小光终於要开始进入网页程序的开发了,所以今天...

Day 15 | 元件状态:污染(被更改) Dirty

如果想在资料被「污染」也就是被更改过时,想要透过新增 Class 来做特别的显示,就可以使用 wir...

C++语言和你 SAY HELLO!!

第三天 各位点进来的朋友,你们好阿 小的不才只能做这个系列的文章,但还是希望分享给点进来的朋友,知道...

那些被忽略但很好用的 Web API / SessionStorage

狡兔有三窟,储存用户端的资料当然也要有三个。 相信大家应该都有遇过需要将资料储存在用户端的需求,像...