Как я могу проверить, похоже ли ключевое слово на название фильма в моей системе рекомендаций?

#python #pandas #dataframe #recommendation-engine

Вопрос:

Я перепробовал все известные мне способы, чтобы проверить, похоже ли ключевое слово на что-то в названии моего фильма dataset.csv, но ничего не работает. Он рекомендует мне фильмы только в том случае, если название точно такое же, как в наборе данных. например: если бы я искал Человека-паука 3, то он порекомендовал бы мне фильмы, связанные с ним, но если бы я искал человека-паука 3, то он не знал бы, что я имел в виду, и показал бы ошибку.

 import pandas as pd
import openpyxl
from sklearn.metrics.pairwise import cosine_similarity
from sklearn.feature_extraction.text import CountVectorizer

df = pd.read_csv('dataset.csv')
df.head(3)
df['Movie_id'] = range(0,1000)
#print(df.head(10))
#print(df.shape)
columns = ['Actors', 'Director', 'Genre', 'Title']
#print(df[columns].head(3))
#print(df[columns].isnull().values.any())

def important(data):
    features = []
    for i in range(0, data.shape[0]):
        features.append(data['Actors'][i] ' ' data['Director'][i] ' ' data['Genre'][i] ' ' data['Title'][i])
    return features

df['features'] = important(df)

#print(df.head(3))

cm = CountVectorizer().fit_transform(df['features'])
cs = cosine_similarity(cm)
print(cs)
print(cs.shape)
title = "Spider-Man 3"#works
#title = "spider man" doesnt works
movie_id = df[df.Title == title]['Movie_id'].values[0]

scores = list(enumerate(cs[movie_id]))
sorted_Scores = sorted(scores, key = lambda x:x[1], reverse=True)
sorted_Scores = sorted_Scores[1:]
print(sorted_Scores)

a = 0
print("The 10 most recommended movie to", title, 'are:')
for item in sorted_Scores:
    movie_title = df[df.Movie_id == item[0]]['Title'].values[0]
    print(a 1, movie_title)
    a  = 1
    if a > 9:
        break

 

итак, как я могу сделать его ключевым словом, основанным на этом коде.

Комментарии:

1. Нет необходимости заново изобретать колесо, функциональность полнотекстового поиска MySQL (FTS) может быть тем, что вам нужно. Дополнительная (более четкая) ссылка здесь.

Ответ №1:

Вы можете воспользоваться библиотекой fuzzywuzzy.

 from fuzzywuzzy import process, fuzz
titles = df['Title'].unique().tolist()
fuzzy_matches = process.extract('Spider-Man 3', titles, scorer=fuzz.token_set_ratio)
 

После этого fuzzy_matches должны содержаться кортежи с похожими словами и значением того, насколько они похожи. Затем вы можете выбрать наиболее подходящее название и выполнить его поиск.
Подобный этому:

 best_fitting_title = fuzzy_matches[0][0]
movie_id = df[df.Title == best_fitting_title]['Movie_id'].values[0]
 

Я не тестировал его полностью, потому что у меня нет образцов данных, но он должен работать.

Ответ №2:

Ваша проблема здесь в том, что вы пытаетесь найти фильм по точному названию здесь:

 movie_id = df[df.Title == title]['Movie_id'].values[0]
 

Там вы ищете df.Title == title , и если есть какая-то разница в названиях, она ничего не находит.

Ваше решение состоит в том, чтобы использовать какой-то алгоритм подобия строк, чтобы найти наиболее похожий существующий заголовок на ваше ключевое слово. Вот минимальный рабочий пример использования встроенного python SequenceMatcher для поиска идентификатора фильма с наиболее похожим названием на ваше ключевое слово.

 from difflib import SequenceMatcher
from functools import partial
import pandas as pd

df = pd.DataFrame([{'Movie_id': 0, 'Title': 'Spider-Man 3'},
                   {'Movie_id': 1, 'Title': 'Iron-Man 3'}, 
                   {'Movie_id': 2, 'Title': 'Titanic'}, 
                   {'Movie_id': 3, 'Title': 'Iconic'}])

def similar(a, b):
    return SequenceMatcher(None, a, b).ratio()

title = 'ironman 3'
most_similar_index = df[['Title']].apply(lambda row: similar(row['Title'], title), axis=1).argmax()
movie_id = df.loc[most_similar_index, 'Movie_id']
 

Выход:

 print(movie_id)
1
 

Ответ №3:

Используйте fuzzywuzzy пакет:

 # Python env: pip install fuzzywuzzy
# Anaconda env: conda install fuzzywuzzy

from fuzzywuzzy import extractOne

>>> df
   Movie_id      Movies
0        11  Spider-Man
1        12    Superman
2        12      Batman

>>> title
'Spider 3'

>>> extractOne(title, df['Movies'])
('Spider-Man', 82, 0)
# (text, score, index)

>>> df.iloc[extractOne(title, df['Movies'], score_cutoff=80)[2]]['Movie_id']
11