Spaces:
Runtime error
Runtime error
Upload 15 files
Browse files- .gitattributes +4 -0
- README.md +68 -5
- app.py +63 -0
- apps/1.png +0 -0
- apps/2.jpg +0 -0
- data/.gitattributes +1 -0
- data/desc_faiss_index_eng.index +3 -0
- data/desc_faiss_index_final.index +3 -0
- data/embeddings_eng.npy +3 -0
- data/embeddings_final.npy +3 -0
- data/eng_data.csv +3 -0
- data/final_data.csv +3 -0
- pages/1 Подбор фильмов по описанию✏️🔍.py +95 -0
- pages/2 Selection of films by description✏️🔍.py +95 -0
- pages/3 Итоги проекта🏆.py +42 -0
- requirements.txt +7 -0
.gitattributes
CHANGED
@@ -33,3 +33,7 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
33 |
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
36 |
+
data/desc_faiss_index_eng.index filter=lfs diff=lfs merge=lfs -text
|
37 |
+
data/desc_faiss_index_final.index filter=lfs diff=lfs merge=lfs -text
|
38 |
+
data/eng_data.csv filter=lfs diff=lfs merge=lfs -text
|
39 |
+
data/final_data.csv filter=lfs diff=lfs merge=lfs -text
|
README.md
CHANGED
@@ -1,12 +1,75 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
emoji:
|
4 |
-
colorFrom:
|
5 |
-
colorTo:
|
6 |
sdk: streamlit
|
7 |
-
sdk_version: 1.
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
---
|
11 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
12 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: FindMyMovie
|
3 |
+
emoji: 🔥
|
4 |
+
colorFrom: indigo
|
5 |
+
colorTo: green
|
6 |
sdk: streamlit
|
7 |
+
sdk_version: 1.29.0
|
8 |
app_file: app.py
|
9 |
pinned: false
|
10 |
---
|
11 |
|
12 |
+
# Find my movie
|
13 |
+
|
14 |
+
## Умный поиск фильмов
|
15 |
+
|
16 |
+
**Elbrus data science - проект Фазы 2**
|
17 |
+
|
18 |
+
## Наша команда:
|
19 |
+
- **[Татьяна](https://github.com/Proseccovna)**
|
20 |
+
- **[Светлана](https://github.com/Solar-Iz)**
|
21 |
+
- **[Алексей](https://github.com/Alex-Dolgikh)**
|
22 |
+
|
23 |
+
### О проекте:
|
24 |
+
|
25 |
+
- Приложение, которое рекомендует фильмы на основе их описания
|
26 |
+
|
27 |
+
- Пользователь вводит описание фильма
|
28 |
+
|
29 |
+
- Система предлаагет ему список фильмов, соотествующих данному описанию
|
30 |
+
|
31 |
+
- Фильмы предлагаются из более чем 7000, представленных на сайте kinoafisha.info
|
32 |
+
|
33 |
+
|
34 |
+
### Как пользоваться:
|
35 |
+
|
36 |
+
- Проект доступен [здесь](https://huggingface.co/spaces/HaggiVaggi/FindMyMovie)
|
37 |
+
|
38 |
+
- Просто откройте сртримлит-приложение и следуйте оставленным там инструкциям
|
39 |
+
|
40 |
+
- Обратная связь приветсвуется
|
41 |
+
|
42 |
+
|
43 |
+
# Find my movie
|
44 |
+
|
45 |
+
## Smart movie search
|
46 |
+
|
47 |
+
**Elbrus data science - Phase 2 project**
|
48 |
+
|
49 |
+
## Our team:
|
50 |
+
- **[Tatiana](https://github.com/Proseccovna)**
|
51 |
+
- **[Svetlana](https://github.com/Solar-Iz)**
|
52 |
+
- **[Alexey](https://github.com/Alex-Dolgikh)**
|
53 |
+
|
54 |
+
|
55 |
+
### About project:
|
56 |
+
|
57 |
+
- An app that recomends a movie based on its description
|
58 |
+
|
59 |
+
- The user enters a movie description
|
60 |
+
|
61 |
+
- The system recomends a list of movies that fit the description
|
62 |
+
|
63 |
+
- Movies are chosen from a set of 7000+ from kinoafisha.info website
|
64 |
+
|
65 |
+
|
66 |
+
### How to use:
|
67 |
+
|
68 |
+
- The project is deployed [here](https://huggingface.co/spaces/HaggiVaggi/FindMyMovie)
|
69 |
+
|
70 |
+
- Simply use the streamlit app in your browser and follow the instructions there
|
71 |
+
|
72 |
+
- Feel free to leave feedback
|
73 |
+
|
74 |
+
|
75 |
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
app.py
ADDED
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import torch
|
4 |
+
from transformers import AutoTokenizer, AutoModel
|
5 |
+
import faiss
|
6 |
+
import numpy as np
|
7 |
+
|
8 |
+
@st.cache_data
|
9 |
+
def load_data(url):
|
10 |
+
df = pd.read_csv(url) # 👈 Download the data
|
11 |
+
return df
|
12 |
+
|
13 |
+
df = load_data('data/final_data.csv')
|
14 |
+
|
15 |
+
st.title('Умный поиск фильмов 🔍🎦')
|
16 |
+
|
17 |
+
|
18 |
+
st.header('Выполнила команда "FindMyMovie":')
|
19 |
+
st.subheader('🎥Алексей')
|
20 |
+
st.subheader('🎬Светлана')
|
21 |
+
st.subheader('🍿Тата')
|
22 |
+
|
23 |
+
|
24 |
+
|
25 |
+
st.subheader('Наши задачи:')
|
26 |
+
st.markdown("""
|
27 |
+
<span style='font-size:18px; color:purple;'>Задача 1:</span> Спарсить информацию по 5 тыс. фильмов и обработать ее
|
28 |
+
|
29 |
+
<span style='font-size:18px; color:purple;'>Задача 2:</span> Разработать систему поиска фильма по пользовательскому запросу
|
30 |
+
""", unsafe_allow_html=True)
|
31 |
+
|
32 |
+
st.markdown(
|
33 |
+
f"<div style='border: 2px solid #800080; padding: 10px; text-align: center;'><span style='font-size: 20px; color: violet;'>Мы любезно позаимствовали данные о фильмах с \
|
34 |
+
Киноафиши, ни один участник команды при этом не пострадал 💟</span></div>",
|
35 |
+
unsafe_allow_html=True
|
36 |
+
)
|
37 |
+
|
38 |
+
st.subheader(' '*10)
|
39 |
+
|
40 |
+
|
41 |
+
st.info('🌟Сервис принимает на вход описание фильма от пользователя и возвращает заданное количество подходящих вариантов')
|
42 |
+
|
43 |
+
|
44 |
+
st.info('🌟Если не знаете, что посмотреть, нажмите кнопку "Сгенерировать" - сервис предложит вам 10 случайных фильмов из библиотеки')
|
45 |
+
|
46 |
+
|
47 |
+
# Отображаем HTML-разметку в Streamlit
|
48 |
+
if st.button("Сгенерировать 🎲"):
|
49 |
+
# Получение случайных 10 строк, включая 'image_url' и 'actors'
|
50 |
+
random_rows = df[['movie_title', 'description', 'actors', 'image_url', 'page_url']].sample(n=10).reset_index(drop=True)
|
51 |
+
random_rows.index = random_rows.index + 1
|
52 |
+
st.markdown(f"<span style='font-size:{20}px; color:violet'>{'Сегодня мы подобрали для вас следующие фильмы:'}</span>", unsafe_allow_html=True)
|
53 |
+
|
54 |
+
|
55 |
+
|
56 |
+
for i in range(5):
|
57 |
+
st.markdown(f"<span style='font-size:{20}px; color:purple'>{random_rows['movie_title'].iloc[i]}</span>", unsafe_allow_html=True)
|
58 |
+
col1, col2 = st.columns([2, 1])
|
59 |
+
col1.info(random_rows['description'].iloc[i])
|
60 |
+
col1.markdown(f"**В ролях:** {random_rows['actors'].iloc[i]}")
|
61 |
+
col1.markdown(f"**Фильм можно посмотреть [здесь]({random_rows['page_url'].iloc[i]})**")
|
62 |
+
col2.image(random_rows['image_url'].iloc[i], caption=random_rows['movie_title'].iloc[i], width=200)
|
63 |
+
|
apps/1.png
ADDED
![]() |
apps/2.jpg
ADDED
![]() |
data/.gitattributes
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
*.csv filter=lfs diff=lfs merge=lfs -text
|
data/desc_faiss_index_eng.index
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4130d7742406402173d6e0baad2820ff396e009605d05676bbcaac9b19025c2e
|
3 |
+
size 8279085
|
data/desc_faiss_index_final.index
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:c645564c7543ebf505584d4191fec57ee6649150fb7eca4c45b8936438386ac8
|
3 |
+
size 21633069
|
data/embeddings_eng.npy
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:df3274afc661f2d791ad695af2451b6d53b9bad6372167ab1f4312dd4e9bd81a
|
3 |
+
size 8279168
|
data/embeddings_final.npy
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:4d1f6eaf09c7a6cf43065869814720f3ed98f58bc0c4784e3bbdf8a80eb99cdb
|
3 |
+
size 21633152
|
data/eng_data.csv
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:d2e9692f30661c1eb29ae2b8b0c46aff6a5d968064ffcb06187136e9945e9913
|
3 |
+
size 35269233
|
data/final_data.csv
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:203f00b121ce8d38c4c0485aac14af75ce942db8c57a27e44f9ed174525463a3
|
3 |
+
size 120362756
|
pages/1 Подбор фильмов по описанию✏️🔍.py
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import torch
|
4 |
+
from transformers import AutoTokenizer, AutoModel
|
5 |
+
import faiss
|
6 |
+
import numpy as np
|
7 |
+
|
8 |
+
@st.cache_data
|
9 |
+
def load_data(url):
|
10 |
+
df = pd.read_csv(url)
|
11 |
+
return df
|
12 |
+
|
13 |
+
@st.cache_data
|
14 |
+
def embedding_and_index():
|
15 |
+
embeddings_array = np.load('data/embeddings_final.npy')
|
16 |
+
index = faiss.read_index('data/desc_faiss_index_final.index')
|
17 |
+
return embeddings_array, index
|
18 |
+
|
19 |
+
@st.cache_data
|
20 |
+
def load_model():
|
21 |
+
model = AutoModel.from_pretrained("DeepPavlov/rubert-base-cased-sentence")
|
22 |
+
return model
|
23 |
+
|
24 |
+
|
25 |
+
st.header("Подбор фильмов по описанию ✏️🔍")
|
26 |
+
|
27 |
+
# Загрузка данных
|
28 |
+
tokenizer = AutoTokenizer.from_pretrained("DeepPavlov/rubert-base-cased-sentence")
|
29 |
+
df = load_data('data/final_data.csv')
|
30 |
+
embeddings_array, index = embedding_and_index()
|
31 |
+
model = load_model()
|
32 |
+
|
33 |
+
# Пользовательский ввод
|
34 |
+
user_input = st.text_input("Введите описание фильма:", value="", help="Чем подробнее будет ваше описание, тем точнее мы сможем подобрать для вас фильм 🤗'")
|
35 |
+
genre_list = ['анимация', 'аниме', 'балет', 'биография', 'боевик', 'вестерн', 'военный', 'детектив', 'детский', 'документальный', 'драма', 'исторический', 'катастрофа', 'комедия', 'концерт', 'короткометражный', 'криминал', 'мелодрама', 'мистика', 'музыка', 'мюзикл', 'нуар', 'приключения', 'сборник', 'семейный', 'сказка', 'спорт', 'триллер', 'ужасы', 'фантастика', 'фэнтези', 'эротика']
|
36 |
+
|
37 |
+
user_select_genre = st.multiselect('Выберите жанр', genre_list)
|
38 |
+
|
39 |
+
if st.button("Искать🔍🎦"):
|
40 |
+
if user_input:
|
41 |
+
def encode_description(description, tokenizer, model):
|
42 |
+
tokens = tokenizer(description, return_tensors="pt")
|
43 |
+
with torch.no_grad():
|
44 |
+
outputs = model(**tokens)
|
45 |
+
embeddings = outputs.last_hidden_state.mean(dim=1)
|
46 |
+
return embeddings.cpu().numpy().astype('float32')
|
47 |
+
|
48 |
+
# Векторизация введенного запроса с использованием переданных tokenizer и model
|
49 |
+
input_embedding = encode_description(user_input, tokenizer, model)
|
50 |
+
|
51 |
+
# Поиск с использованием Faiss
|
52 |
+
_, sorted_indices = index.search(input_embedding.reshape(1, -1), 5)
|
53 |
+
|
54 |
+
# Используйте индексы для извлечения строк из DataFrame
|
55 |
+
recs = df.iloc[sorted_indices[0]].reset_index(drop=True)
|
56 |
+
recs.index = recs.index + 1
|
57 |
+
|
58 |
+
if user_select_genre:
|
59 |
+
genres_selected = pd.Series(user_select_genre)
|
60 |
+
genre_mask = df['genre'].str.contains('')
|
61 |
+
for i in range(len(genres_selected)):
|
62 |
+
genre_mask_i = df['genre'].str.contains(genres_selected.iloc[i])
|
63 |
+
genre_mask = genre_mask & genre_mask_i
|
64 |
+
recs = recs[genre_mask]
|
65 |
+
|
66 |
+
if not recs.empty:
|
67 |
+
# Вывод рекомендованных фильмов с изображениями
|
68 |
+
st.subheader("Рекомендованные фильмы 🎉:")
|
69 |
+
for i in range(min(5, len(recs))):
|
70 |
+
st.markdown(f"<span style='font-size:{20}px; color:purple'>{recs['movie_title'].iloc[i]}</span>", unsafe_allow_html=True)
|
71 |
+
# Создаем две колонки: одну для текста, другую для изображения
|
72 |
+
col1, col2 = st.columns([2, 1])
|
73 |
+
|
74 |
+
# В колонке отображаем название фильма, описание, роли и ссылку
|
75 |
+
col1.info(recs['description'].iloc[i])
|
76 |
+
col1.markdown(f"**В ролях:** {recs['actors'].iloc[i]}")
|
77 |
+
col1.markdown(f"**Фильм можно посмотреть [здесь]({recs['page_url'].iloc[i]})**")
|
78 |
+
|
79 |
+
# В колонке отображаем изображение
|
80 |
+
col2.image(recs['image_url'].iloc[i], caption=recs['movie_title'].iloc[i], width=200)
|
81 |
+
|
82 |
+
with st.sidebar:
|
83 |
+
st.info("""
|
84 |
+
#### Мы смогли помочь вам с выбором?
|
85 |
+
""")
|
86 |
+
feedback = st.text_input('Поделитесь с нами вашим мнением')
|
87 |
+
|
88 |
+
feedback_button = st.button("Отправить отзыв", key="feedback_button")
|
89 |
+
|
90 |
+
if feedback_button and feedback:
|
91 |
+
st.success("Спасибо, каждый день мы стараемся быть лучше для вас 💟")
|
92 |
+
elif feedback_button:
|
93 |
+
st.warning("Пожалуйста, введите отзыв перед отп��авкой.")
|
94 |
+
else:
|
95 |
+
st.subheader("Подходящих фильмов не найдено, ослабьте фильтры 😔:")
|
pages/2 Selection of films by description✏️🔍.py
ADDED
@@ -0,0 +1,95 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import pandas as pd
|
3 |
+
import torch
|
4 |
+
from transformers import BertTokenizer, BertModel
|
5 |
+
import faiss
|
6 |
+
import numpy as np
|
7 |
+
import re
|
8 |
+
import nltk
|
9 |
+
from nltk.corpus import stopwords
|
10 |
+
|
11 |
+
# Загрузка стоп-слов для английского языка
|
12 |
+
nltk.download('stopwords')
|
13 |
+
stop_words = set(stopwords.words('english'))
|
14 |
+
|
15 |
+
@st.cache_data
|
16 |
+
def load_data(url):
|
17 |
+
df = pd.read_csv(url)
|
18 |
+
return df
|
19 |
+
|
20 |
+
@st.cache_data
|
21 |
+
def embedding_and_index():
|
22 |
+
embeddings_array = np.load('data/embeddings_eng.npy')
|
23 |
+
index = faiss.read_index('data/desc_faiss_index_eng.index')
|
24 |
+
return embeddings_array, index
|
25 |
+
|
26 |
+
@st.cache_data
|
27 |
+
def load_model():
|
28 |
+
model = BertModel.from_pretrained('bert-base-uncased')
|
29 |
+
return model
|
30 |
+
|
31 |
+
def clean_text(text):
|
32 |
+
text = text.lower()
|
33 |
+
text = re.sub(r'[^\w\s]', '', text)
|
34 |
+
text = ' '.join(word for word in text.split() if word not in stop_words)
|
35 |
+
|
36 |
+
return text
|
37 |
+
|
38 |
+
st.header("Selection of films by description✏️🔍")
|
39 |
+
|
40 |
+
# Загрузка данных
|
41 |
+
tokenizer = BertTokenizer.from_pretrained('bert-base-uncased')
|
42 |
+
df = load_data('data/eng_data.csv')
|
43 |
+
embeddings_array, index = embedding_and_index()
|
44 |
+
model = load_model()
|
45 |
+
|
46 |
+
# Пользовательский ввод
|
47 |
+
user_input = st.text_input("Enter a movie description:", value="", help="The more detailed your description is, the more accurately we can choose a film for you 🤗'")
|
48 |
+
|
49 |
+
if st.button("Search🔍🎦"):
|
50 |
+
if user_input:
|
51 |
+
def encode_description(description, tokenizer, model):
|
52 |
+
tokens = tokenizer(description, return_tensors="pt")
|
53 |
+
with torch.no_grad():
|
54 |
+
outputs = model(**tokens)
|
55 |
+
embeddings = outputs.last_hidden_state.mean(dim=1)
|
56 |
+
return embeddings.cpu().numpy().astype('float32')
|
57 |
+
|
58 |
+
# Применяем очистку текста к пользовательскому вводу
|
59 |
+
cleaned_input = clean_text(user_input)
|
60 |
+
|
61 |
+
# Векторизация очищенного запроса
|
62 |
+
input_embedding = encode_description(cleaned_input, tokenizer, model)
|
63 |
+
|
64 |
+
# Поиск с использованием Faiss
|
65 |
+
_, sorted_indices = index.search(input_embedding.reshape(1, -1), 5)
|
66 |
+
|
67 |
+
# Используйте индексы для извлечения строк из DataFrame
|
68 |
+
recs = df.iloc[sorted_indices[0]].reset_index(drop=True)
|
69 |
+
recs.index = recs.index + 1
|
70 |
+
|
71 |
+
# Вывод рекомендованных фильмов с изображениями
|
72 |
+
st.subheader("Recommended movies 🎉:")
|
73 |
+
for i in range(5):
|
74 |
+
st.markdown(f"<span style='font-size:{20}px; color:purple'>{recs['movie_title'].iloc[i]}</span>", unsafe_allow_html=True)
|
75 |
+
# Создаем две колонки: одну для текста, другую для изображения
|
76 |
+
col1, col2 = st.columns([2, 1])
|
77 |
+
|
78 |
+
# В колонке отображаем название фильма, описание, роли и ссылку
|
79 |
+
col1.info(recs['description'].iloc[i])
|
80 |
+
col1.markdown(f"**You can watch the film [here]({recs['page_url'].iloc[i]})**")
|
81 |
+
|
82 |
+
# В колонке отображаем изображение
|
83 |
+
col2.image(recs['image_url'].iloc[i], caption=recs['movie_title'].iloc[i], width=200)
|
84 |
+
with st.sidebar:
|
85 |
+
st.info("""
|
86 |
+
#### Were we able to help you with the choice?
|
87 |
+
""")
|
88 |
+
feedback = st.text_input('Share with us')
|
89 |
+
|
90 |
+
feedback_button = st.button("Send feedback", key="feedback_button")
|
91 |
+
|
92 |
+
if feedback_button and feedback:
|
93 |
+
feedback_container.success("Thank you, every day we try to be better for you 💟")
|
94 |
+
elif feedback_button:
|
95 |
+
feedback_container.warning("Please enter a review before submitting")
|
pages/3 Итоги проекта🏆.py
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
|
3 |
+
st.header('Инструменты для создания проекта: ')
|
4 |
+
|
5 |
+
st.subheader('Для русской версии: ')
|
6 |
+
|
7 |
+
list_text = """
|
8 |
+
<div style='color: violet; border: 2px solid purple; padding: 10px;'>
|
9 |
+
<ul>
|
10 |
+
<li>Используемые языковые модели: rubert-base-cased-sentence, rubert-tiny2</li>
|
11 |
+
<li>Библиотека Sentence Transformers</li>
|
12 |
+
<li>Faiss (для уменьшения времени генерации подборки фильмов)</li>
|
13 |
+
<li>Сайт-жертва для парсинга - <a href="https://www.kinoafisha.info/" style='color: purple;'>Киноафиша</a></li>
|
14 |
+
</ul>
|
15 |
+
</div>
|
16 |
+
"""
|
17 |
+
|
18 |
+
# Отображение HTML-разметки в Streamlit
|
19 |
+
st.markdown(list_text, unsafe_allow_html=True)
|
20 |
+
|
21 |
+
st.subheader('Для английской версии: ')
|
22 |
+
|
23 |
+
list_text2 = """
|
24 |
+
<div style='color: pink; border: 2px solid violet; padding: 10px;'>
|
25 |
+
<ul>
|
26 |
+
<li>Используемые языковые модели: bert-base-uncased</li>
|
27 |
+
<li>Очистка текста: приведение к нижнему регистру, очистка от знаков препинания, стоп-слова</li>
|
28 |
+
<li>Библиотека Sentence Transformers</li>
|
29 |
+
<li>Faiss (для уменьшения времени генерации подборки фильмов)</li>
|
30 |
+
<li>Сайт-жертва для парсинга - <a href="https://www.themoviedb.org/" style='color: violet;'>TMDB</a></li>
|
31 |
+
</ul>
|
32 |
+
</div>
|
33 |
+
"""
|
34 |
+
|
35 |
+
st.markdown(list_text2, unsafe_allow_html=True)
|
36 |
+
|
37 |
+
|
38 |
+
st.markdown("<p style='color: pink; font-size: 28px; text-align: center;'>"
|
39 |
+
"А теперь, когда фильм успешно выбран, вооружайтесь теплым пледом и глинтвейном и бегите смотреть 🎄🍿"
|
40 |
+
"</p>", unsafe_allow_html=True)
|
41 |
+
|
42 |
+
st.image("apps/2.jpg", use_column_width=True)
|
requirements.txt
ADDED
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
transformers==4.35.2
|
2 |
+
sentence-transformers==2.2.2
|
3 |
+
torch==1.11.0
|
4 |
+
streamlit==0.86.0
|
5 |
+
pandas==1.3.3
|
6 |
+
scikit-learn==1.3.2
|
7 |
+
faiss-gpu==1.7.2
|