๐Ÿ˜ข ์Šคํ„ฐ๋””๋…ธํŠธ (Machine Learning 16)

zoeยท2023๋…„ 5์›” 31์ผ
0

Recommendatation

  • ์ถ”์ฒœ์‹œ์Šคํ…œ
  • ์ฝ˜ํ…์ธ  ๊ธฐ๋ฐ˜ ํ•„ํ„ฐ๋ง ์ถ”์ฒœ ์‹œ์Šคํ…œ : ์‚ฌ์šฉ์ž๊ฐ€ ํŠน์ •ํ•œ ์•„์ดํ…œ์„ ์„ ํ˜ธํ•˜๋Š” ๊ฒฝ์šฐ, ๊ทธ ์•„์ดํ…œ๊ณผ ๋น„์Šทํ•œ ์•„์ดํ…œ์„ ์ถ”์ฒœํ•˜๋Š” ๋ฐฉ์‹
  • ์ตœ๊ทผ์ ‘ ์ด์›ƒ ํ˜‘์—… ํ•„ํ„ฐ๋ง : ์ถ•์ ๋œ ์‚ฌ์šฉ์ž ํ–‰๋™ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์•„์ง ํ‰๊ฐ€ํ•˜์ง€ ์•Š์€ ์•„์ดํ…œ์„ ์˜ˆ์ธก ํ‰๊ฐ€. ์‚ฌ์šฉ์ž ๊ธฐ๋ฐ˜ โ†’ ๋‹น์‹ ๊ณผ ๋น„์Šทํ•œ ๊ณ ๊ฐ๋“ค์ด ๋‹ค์Œ ์ƒํ’ˆ๋„ ๊ตฌ๋งคํ–ˆ์Œ

  • ์ผ๋ฐ˜์ ์œผ๋กœ๋Š” ์‚ฌ์šฉ์ž ๊ธฐ๋ฐ˜๋ณด๋‹ค๋Š” ์•„์ดํ…œ ๊ธฐ๋ฐ˜ ํ˜‘์—… ํ•„ํ„ฐ๋ง์ด ์ •ํ™•๋„๊ฐ€ ๋” ๋†’๋‹ค
    - ๋น„์Šทํ•œ ์˜ํ™”๋ฅผ ์ข‹์•„ํ•œ๋‹ค๊ณ  ์ทจํ–ฅ์ด ๋น„์Šทํ•˜๋‹ค๊ณ  ํŒ๋‹จํ•˜๊ธฐ ์–ด๋ ต๊ฑฐ๋‚˜
    - ๋งค์šฐ ์œ ๋ช…ํ•œ ์˜ํ™”๋Š” ์ทจํ–ฅ๊ณผ ๊ด€๊ณ„์—†์ด ๊ด€๋žŒํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ณ 
    - ์‚ฌ์šฉ์ž๋“ค์ด ํ‰์ ์„ ๋งค๊ธฐ์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๊ธฐ ๋•Œ๋ฌธ

  • ์ž ์žฌ ์š”์ธ ํ˜‘์—… ํ•„ํ„ฐ๋ง : ์‚ฌ์šฉ์ž - ์•„์ดํ…œ ํ‰์  ํ–‰๋ ฌ ๋ฐ์ดํ„ฐ๋ฅผ ์ด์šฉํ•ด์„œ '์ž ์žฌ์š”์ธ'์„ ๋„์ถœํ•˜๋Š” ๊ฒƒ. ์ฃผ์š”์ธ๊ณผ ์•„์ดํ…œ์— ๋Œ€ํ•œ ์ž ์žฌ์š”์ธ์— ๋Œ€ํ•ด ํ–‰๋ ฌ๋ถ„ํ•ด๋ฅผ ํ•˜๊ณ  ๋‹ค์‹œ ํ–‰๋ ฌ๊ณฑ์„ ํ†ตํ•ด ์•„์ง ํ‰์ ์„ ๋ถ€์—ฌํ•˜์ง€ ์•Š์€ ์•„์ดํ…œ์— ๋Œ€ํ•œ ์˜ˆ์ธก ํ‰์ ์„ ์ƒ์„ฑํ•˜๋Š” ๊ฒƒ



์ฝ˜ํ…์ธ  ๊ธฐ๋ฐ˜ ํ•„ํ„ฐ๋ง ์‹ค์Šต - TMDB5000 ์˜ํ™” ๋ฐ์ดํ„ฐ ์„ธํŠธ

# ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ

import pandas as pd
import numpy as np
import warnings

warnings.filterwarnings('ignore')

movies = pd.read_csv('./tmdb5000movies/tmdb_5000_movies.csv')
print(movies.shape)
movies.head()
# ๋ฐ์ดํ„ฐ ์„ ํƒ

movies_df = movies[['id', 'title', 'genres', 'vote_average', 
                    'vote_count', 'popularity', 'keywords', 'overview']]

movies_df.head()
# ๋ฐ์ดํ„ฐ ์ฃผ์˜์‚ฌํ•ญ
# genres์™€ keywords๋Š” ์ปฌ๋Ÿผ์•ˆ์— dictํ˜•์œผ๋กœ ์ €์žฅ๋จ

movies_df[['genres']][:1].values
type(movies_df['genres'][0])
movies_df['genres'][0]
# ๋ฌธ์ž์—ด๋กœ ๋œ ๋ฐ์ดํ„ฐ ๋ณ€ํ™˜

from ast import literal_eval

code = "(1, 2, {'foo':'bar'})"
code
type(code)
literal_eval(code)
type(literal_eval(code))
# genres์™€ keywords์˜ ๋‚ด์šฉ์„ list์™€ dict์œผ๋กœ ๋ณต๊ตฌ

from ast import literal_eval

movies_df['genres'] = movies_df['genres'].apply(literal_eval)
movies_df['keywords'] = movies_df['keywords'].apply(literal_eval)

movies_df.head()
# dict์˜ value ๊ฐ’์„ ํŠน์„ฑ์œผ๋กœ ์‚ฌ์šฉํ•˜๋„๋ก ๋ณ€๊ฒฝ

movies_df['genres'] = movies_df['genres'].apply(lambda x : [y['name'] for y in x])
movies_df['keywords'] = movies_df['keywords'].apply(lambda x : [y['name'] for y in x])
movies_df[['genres', 'keywords']][:2]
# genres์˜ ๊ฐ ๋‹จ์–ด๋“ค์„ ํ•˜๋‚˜์˜ ๋ฌธ์žฅ(๋„์–ด์“ฐ๊ธฐ๋กœ ๊ตฌ๋ถ„๋œ)์œผ๋กœ ๋ณ€ํ™˜

movies_df['genres_literal'] = movies_df['genres'].apply(lambda x : (' '.join(x)))
movies_df.head()
# ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜๋œ genres๋ฅผ CountVectorize ์ˆ˜ํ–‰
# countvectorize : https://wikidocs.net/33661
# ngram_range : ๋‹จ์–ด ๋ฌถ์Œ ์„ค์ •

from sklearn.feature_extraction.text import CountVectorizer

count_vect = CountVectorizer(min_df=0, ngram_range=(1, 2))
genre_mat = count_vect.fit_transform(movies_df['genres_literal'])
print(genre_mat.shape)
# ๋ฌธ์žฅ์˜ ์œ ์‚ฌ๋„ ์ธก์ •์„ ํ•˜๋Š” ๋ฐฉ๋ฒ• ์ค‘ ํ•˜๋‚˜์ธ ์ฝ”์‚ฌ์ธ ์œ ์‚ฌ๋„ ์ธก์ •์„ ์ˆ˜ํ–‰
# confusion_matrix์™€ ๋น„์Šทํ•˜๊ฒŒ ํ•ด์„ํ•˜๋ฉด ๋œ๋‹ค.

from sklearn.metrics.pairwise import cosine_similarity

genre_sim  =cosine_similarity(genre_mat, genre_mat) # ๋‘ ๋ฉ”ํŠธ๋ฆญ์Šค๋ผ๋ฆฌ similarity๋ฅผ ๊ตฌํ•จ
print(genre_sim.shape)
print(genre_sim[:2])
# genre_sim ๊ฐ์ฒด์—์„œ ๋†’์€ ๊ฐ’ ์ˆœ์œผ๋กœ ์ •๋ ฌ

genre_sim_sorted_ind = genre_sim.argsort()[:, ::-1] 
# [:, ::-1] : argsort()๊ฐ€ array ์ •๋ ฌ ๊ธฐ๋Šฅ์ด๊ณ , ascending ์ •๋ ฌ ๊ธฐ๋Šฅ์ด ์—†์–ด [:, ::-1]ํ•˜๋ฉด ์ˆœ์„œ๊ฐ€ ๋’ค์ง‘ํžŒ๋‹ค(?..)
print(genre_sim_sorted_ind[:1])
# ์ถ”์ฒœ ์˜ํ™”๋ฅผ DataFrame์œผ๋กœ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜

def find_sim_movie(df, sorted_ind, title_name, top_n = 10):
    title_movie = df[df['title'] == title_name]
    
    title_index = title_movie.index.values
    silmilar_indexes = sorted_ind[title_index, :(top_n)]
    
    print(silmilar_indexes)
    silmilar_indexes = silmilar_indexes.reshape(-1)
    
    return df.iloc[silmilar_indexes]
    
# ์˜ํ™” ๋Œ€๋ถ€์™€ ์œ ์‚ฌํ•œ ์˜ํ™”๋Š”?

similar_movies = find_sim_movie(movies_df, genre_sim_sorted_ind, 'The Godfather', 10)
similar_movies[['title', 'vote_average']]

# ๋‹ค์‹œ ๋ฐ์ดํ„ฐ ํƒ์ƒ‰
# ํ‰์ ๊ณผ ํ‰์ ์„ ๋งค๊ธด ํšŸ์ˆ˜๋ฅผ ๋ณด๋ฉด ๋ฌธ์ œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณด์ธ๋‹ค.

movies_df[['title', 'vote_average', 
           'vote_count']].sort_values('vote_average', ascending=False)[:10]
  • ์˜ํ™” ์„ ์ •์„ ์œ„ํ•œ ๊ฐ€์ค‘์น˜๋ฅผ ์„ ์ •

# ์˜ํ™” ์„ ์ •์„ ์œ„ํ•œ ๊ฐ€์ค‘์น˜ ์„ ์ •
# ์˜ํ™” ์ „์ฒด ํ‰๊ท ํ‰์ ๊ณผ ์ตœ์†Œ ํˆฌํ‘œ ํšŸ์ˆ˜๋ฅผ 60%์ง€์ ์œผ๋กœ ์ง€์ •

C = movies_df['vote_average'].mean()
m = movies_df['vote_count'].quantile(0.6)
print('C: ', round(C, 3), 'm: ', round(m, 3))
# ๊ฐ€์ค‘์น˜๊ฐ€ ๋ถ€์—ฌ๋œ ํ‰์ ์„ ๊ณ„์‚ฐํ•˜๊ธฐ ์œ„ํ•œ ํ•จ์ˆ˜

def weighted_vote_average(recode):
    v = recode['vote_count']
    R = recode['vote_average']
    
    return ((v/(v+m)) * R) + ((m/(m+v) * C))
# ๋‹ค์‹œ ๊ณ„์‚ฐ

movies_df['weighted_vote'] = movies_df.apply(weighted_vote_average, axis=1)
movies_df.head()
# ์ „์ฒด ๋ฐ์ดํ„ฐ์—์„œ ๊ฐ€์ค‘์น˜๊ฐ€ ๋ถ€์—ฌ๋œ ํ‰์  ์ˆœ์œผ๋กœ ์ •๋ ฌํ•œ ๊ฒฐ๊ณผ

movies_df[['title', 'vote_average', 
           'weighted_vote', 'vote_count']].sort_values('weighted_vote', ascending=False)[:10]
# vote_average์™€ weighted_vote๋ฅผ ๋น„๊ตํ•ด๋ณด๋ฉด ๊ฐ€์ค‘์น˜๊ฐ€ ์ ์šฉ๋˜์–ด ๊ฐ’์ด ๋ฐ”๋€Œ์–ด ์žˆ์Œ
movies_df.tail()
movies_df[movies_df['vote_count'] < 10]
# ์ „์ฒด ๋ฐ์ดํ„ฐ์—์„œ ๊ฐ€์ค‘์น˜๊ฐ€ ๋ถ€์—ฌ๋œ ํ‰์  ์ˆœ์œผ๋กœ ์ •๋ ฌ

movies_df[['title', 'vote_average', 
           'weighted_vote', 'vote_count']].sort_values('weighted_vote', ascending=False)[:10]
# ์œ ์‚ฌ ์˜ํ™”๋ฅผ ์ฐพ๋Š” ํ•จ์ˆ˜ ๋ณ€๊ฒฝ

def find_sim_movie(df, sorted_ind, title_name, top_n = 10):
    title_movie = df[df['title'] == title_name]
    title_index = title_movie.index.values
    
    silmilar_indexes = sorted_ind[title_index, :(top_n*2)]
    silmilar_indexes = silmilar_indexes.reshape(-1)
    
    silmilar_indexes = silmilar_indexes[silmilar_indexes != title_index]
    
    return df.iloc[silmilar_indexes].sort_values('weighted_vote', ascending = False)[:top_n]
# ๋Œ€๋ถ€์™€ ์œ ์‚ฌํ•œ ์˜ํ™” ์ฐพ๊ธฐ

similar_movies = find_sim_movie(movies_df, genre_sim_sorted_ind, 'The Godfather', 10)
similar_movies[['title', 'vote_average', 'weighted_vote']]


์•„์ดํ…œ ๊ธฐ๋ฐ˜ ์ตœ๊ทผ์ ‘ ์ด์›ƒ ํ˜‘์—… ํ•„ํ„ฐ๋ง

  • https://grouplens.org/datasets/movielens/latest/

  • ์˜ํ™”์˜ ํ‰์ ์„ ๋งค๊ธด ์‚ฌ์šฉ์ž์™€ ์˜ํ™” ํ‰์  ํ–‰๋ ฌ ๋“ฑ์˜ ๋ฐ์ดํ„ฐ

  • ์ด์ค‘์—์„œ 1MB์งœ๋ฆฌ small ๋ฐ์ดํ„ฐ ์ด์šฉ

# ๋ฐ์ดํ„ฐ ์ฝ๊ธฐ

import pandas as pd
import numpy as np

movies = pd.read_csv('./ml-latest-small/movies.csv')
ratings = pd.read_csv('./ml-latest-small/ratings.csv')

print(movies.shape)
print(ratings.shape)
# movie์—๋Š” ์˜ํ™”์ œ๋ชฉ, ์žฅ๋ฅด

movies.head()
# rating์—๋Š” ์˜ํ™” ํ‰์ ์ด ์‚ฌ์šฉ์ž๋ณ„๋กœ ์˜ํ™”๋ณ„๋กœ ์กด์žฌ

ratings.head()
  • raw ๋ฐ์ดํ„ฐ๋ฅผ ์ •๋ฆฌํ•ด์•ผ ํ•œ๋‹ค.

# rating raw ๋ฐ์ดํ„ฐ ์ •๋ฆฌ ํ•„์š”
# pivot_table

ratings = ratings[['userId', 'movieId', 'rating']]
ratings_matrix = ratings.pivot_table('rating', index='userId', columns='movieId')
ratings_matrix.head()
# ratings์™€ movie๋ฅผ movieID ๊ธฐ์ค€์œผ๋กœ ๊ฒฐํ•ฉ

ratings_movies = pd.merge(ratings, movies, on='movieId')
ratings_movies.head()
# ๋‹ค์‹œ pivot_table ์ด์šฉํ•˜์—ฌ ์ •๋ฆฌ

ratings_matrix = ratings_movies.pivot_table('rating', index='userId', columns='title')
ratings_matrix.head()
# nan์„ 0์œผ๋กœ ๋ณ€ํ™˜

ratings_matrix = ratings_matrix.fillna(0)
ratings_matrix.head()
# ์œ ์‚ฌ๋„ ์ธก์ •์„ ์œ„ํ•ด ํ–‰๋ ฌ์˜ transpose

ratings_matrix_T = ratings_matrix.transpose()
ratings_matrix_T.head()
# ์œ ์‚ฌ๋„ ์ธก์ • ๊ฒฐ๊ณผ

from sklearn.metrics.pairwise import cosine_similarity

item_sim = cosine_similarity(ratings_matrix_T, ratings_matrix_T)
item_sim_df = pd.DataFrame(data=item_sim, 
                           index=ratings_matrix.columns, columns=ratings_matrix.columns)
print(item_sim_df.shape)
item_sim_df.head()
# ๋Œ€๋ถ€์™€ ์œ ์‚ฌํ•œ ์˜ํ™”๋Š”?

item_sim_df['Godfather, The (1972)'].sort_values(ascending=False)[:6]
# ์ธ์…‰์…˜๊ณผ ์œ ์‚ฌํ•œ ์˜ํ™”?

item_sim_df['Inception (2010)'].sort_values(ascending=False)[1:6]


Good Books recommendations

# ๋ฐ์ดํ„ฐ ๊ฒฝ๋กœ ํ™•์ธ

import numpy as np
import pandas as pd
import os

print(os.listdir('./good book recommendation/'))
# books.csv
# ratings 1, 2, 3, 4, 5์˜ ์˜๋ฏธ โ†’ ๋ณ„์ ๋ณ„ ์‚ฌ๋žŒ๋“ค ์ข‹์•„์š” ์ˆ˜

books = pd.read_csv('./good book recommendation/books.csv', encoding='ISO-8859-1')
books.head()
# ratings.csv
# rating user_id, user_id๊ฐ€ ์ค€ rate
ratings = pd.read_csv('./good book recommendation/ratings.csv', encoding='ISO-8859-1')
ratings.head()
# book_tags.csv
# book_id์™€ tag_id

book_tags = pd.read_csv('./good book recommendation/book_tags.csv', encoding='ISO-8859-1')
book_tags.head()
# tags.csv
# tag_id์™€ tag_name

tags = pd.read_csv('./good book recommendation/tags.csv', encoding='ISO-8859-1')
tags.head()
# book_tags์™€ tags๋ฅผ merge

tags_join_DF = pd.merge(book_tags, tags, left_on='tag_id', right_on='tag_id', how='inner')
tags_join_DF.head()
# to_read.csv
# user_id๊ฐ€ ์ฝ์€ book_id
to_read = pd.read_csv('./good book recommendation/to_read.csv')
to_read.head()
# books์˜ aurthors

books['authors'][:5]
# aurthors๋กœ Tfidf ์ˆ˜ํ–‰
# Tfidf : ์ •๋ณด ๊ฒ€์ƒ‰๊ณผ ํ…์ŠคํŠธ ๋งˆ์ด๋‹์—์„œ ์ด์šฉํ•˜๋Š” ๊ฐ€์ค‘์น˜๋กœ, ์—ฌ๋Ÿฌ ๋ฌธ์„œ๋กœ ์ด๋ฃจ์–ด์ง„ ๋ฌธ์„œ๊ตฐ์ด ์žˆ์„ ๋•Œ ์–ด๋–ค ๋‹จ์–ด๊ฐ€ ํŠน์ • ๋ฌธ์„œ ๋‚ด์—์„œ ์–ผ๋งˆ๋‚˜ ์ค‘์š”ํ•œ ๊ฒƒ์ธ์ง€๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ํ†ต๊ณ„์  ์ˆ˜์น˜์ด๋‹ค.
# https://wikidocs.net/31698

from sklearn.feature_extraction.text import TfidfVectorizer

tf = TfidfVectorizer(analyzer='word', ngram_range=(1, 2), min_df=0, stop_words='english')
tfidf_matrix = tf.fit_transform(books['authors'])
tfidf_matrix
# ์œ ์‚ฌ๋„ ์ธก์ •

from sklearn.metrics.pairwise import linear_kernel

cosine_sim = linear_kernel(tfidf_matrix, tfidf_matrix)
cosine_sim
# The Hobbit์˜ index๋Š” 6

titles = books['title']
indices  =pd.Series(books.index, index=books['title'])
indices['The Hobbit']
# ์œ ์‚ฌ๋„ ๊ฐ’ ํ˜ธ์ถœ

cosine_sim[indices['The Hobbit']]
# ์œ ์‚ฌ๋„ ๊ฒฐ๊ณผ๋ฅผ ์ธ๋ฑ์Šค๋ฅผ ๊ฐ€์ง„ list ํ˜•์œผ๋กœ 

cosine_sim[indices['The Hobbit']].shape
list(enumerate(cosine_sim[indices['The Hobbit']]))
# ๊ฐ€์žฅ ์œ ์‚ฌํ•œ ์ฑ…์˜ ์ธ๋ฑ์Šค ์ฐพ๊ธฐ

sim_scores = list(enumerate(cosine_sim[indices['The Hobbit']]))
sim_scores = sorted(sim_scores, key=lambda x: x[1], reverse=True)
sim_scores[:3]
# ์ž‘๊ฐ€๋กœ ๋ณธ ์œ ์‚ฌ ์ฑ… ๊ฒ€์ƒ‰

sim_scores = sim_scores[1:11]
book_indices = [i[0] for i in sim_scores]
titles.iloc[book_indices]
# book์— tag ํฌํ•จ

books_with_tags = pd.merge(books, tags_join_DF, 
                           left_on='book_id', right_on='goodreads_book_id', how='inner')
books_with_tags.head()
# tag๋กœ Tfidf

tf1 = TfidfVectorizer(analyzer='word', ngram_range=(1, 2), min_df=0, stop_words='english')
tfidf_matrix1 = tf1.fit_transform(books_with_tags['tag_name'].head(10000))
cosine_sim1 = linear_kernel(tfidf_matrix1, tfidf_matrix1)
cosine_sim1
# ์ถ”์ฒœ ์ฑ…์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ํ•จ์ˆ˜
titles1 = books['title']
indices1 = pd.Series(books.index, index=books['title'])

def tags_recommendations(title):
    idx = indices1[title]
    sim_scores = list(enumerate(cosine_sim1[idx]))
    sim_scores = sorted(sim_scores, key=lambda x:x[1], reverse=True)
    sim_scores = sim_scores[1:11]
    book_indices = [i[0] for i in sim_scores]
    return titles.iloc[book_indices]
    
# ํƒœ๊ทธ๋กœ ์ฐพ์•„๋ณธ The Hobbit๊ณผ ์œ ์‚ฌํ•œ ์ฑ…

tags_recommendations('The Hobbit').head(20)
# ์ž„์‹œ๋กœ book id๋งˆ๋‹ค tag๋ฅผ ๋ถ™์ด๊ธฐ

temp_df = books_with_tags.groupby('book_id')['tag_name'].apply(' '.join).reset_index()
temp_df.head()
# books์— ํ•ฉ์น˜๊ธฐ

books = pd.merge(books, temp_df, left_on='book_id', right_on='book_id', how='inner')
books.head()
pd.Series(books[['authors', 'tag_name']].fillna('').values.tolist())
# ์ €์ž์ด๋ฆ„๊ณผ ํƒœ๊ทธ ํ•ฉ์น˜๊ธฐ

books['corpus'] = (pd.Series(books[['authors', 'tag_name']].fillna('').values.tolist()).str.join(' '))

books['corpus'][:3]
# Tfidf ์ˆ˜ํ–‰

tf_corpus = TfidfVectorizer(analyzer='word', ngram_range=(1, 2), min_df=0, stop_words='english')
tfidf_matrix_corpus = tf_corpus.fit_transform(books['corpus'])
cosine_sim_corpus = linear_kernel(tfidf_matrix_corpus, tfidf_matrix_corpus)

titles = books['title']
indices = pd.Series(books.index, index=books['title'])
# ์ถ”์ฒœํ•จ์ˆ˜ ๋งŒ๋“ค๊ธฐ

def corpus_recommendations(title):
    idx = indices1[title]
    sim_scores = list(enumerate(cosine_sim_corpus[idx]))
    sim_scores = sorted(sim_scores, key= lambda x:x[1], reverse=True)
    sim_scores = sim_scores[1:11]
    book_indices = [i[0] for i in sim_scores]
    return titles.iloc[book_indices]
    
# Hobbit๊ณผ ๋น„์Šทํ•œ ์ฑ…

corpus_recommendations('The Hobbit')
# Twilight๊ณผ ๋น„์Šทํ•œ ์ฑ…

corpus_recommendations('Twilight (Twilight, #1)')
# ๋กœ๋ฏธ์˜ค์™€ ์ค„๋ฆฌ์—ฃ๊ณผ ์œ ์‚ฌํ•œ ์ฑ…

corpus_recommendations('Romeo and Juliet')

๐Ÿ’ป ์ถœ์ฒ˜ : ์ œ๋กœ๋ฒ ์ด์Šค ๋ฐ์ดํ„ฐ ์ทจ์—… ์Šค์ฟจ

profile
#๋ฐ์ดํ„ฐ๋ถ„์„ #ํผํฌ๋จผ์Šค๋งˆ์ผ€ํŒ… #๋ฐ์ดํ„ฐ #๋””์ง€ํ„ธ๋งˆ์ผ€ํŒ…

0๊ฐœ์˜ ๋Œ“๊ธ€