alizhgir commited on
Commit
6b534e9
1 Parent(s): 097cd3a

upadte 14:30 15.12

Browse files
.DS_Store CHANGED
Binary files a/.DS_Store and b/.DS_Store differ
 
.gitignore ADDED
@@ -0,0 +1 @@
 
 
1
+ .DS_Store
Main.py CHANGED
@@ -1,5 +1,13 @@
1
  import streamlit as st
 
2
 
 
 
 
 
 
 
 
3
 
4
  st.header("""
5
  Проект по рекомендациям книг различного жанра📚
@@ -10,9 +18,9 @@ st.image('images/preview_image.png', caption='Картинка сгенерир
10
 
11
  st.write("""
12
  ### Уникальный состав команды:
13
- \n- ##### Алиса Жгир 💥
14
- \n- ##### Тигран Арутюнян 💥
15
- \n- ##### Руслан Волощенко 💥
16
  """)
17
 
18
  st.info("""
@@ -23,17 +31,17 @@ st.info("""
23
 
24
  st.info("""
25
  ### Задачи:
26
- \n- ##### Построить алгоритм парсинга информации с книжного сайта
27
- \n- ##### Полученные данные очистить и сделать рабочий Dataset
28
- \n- ##### Создать RecSys, способную делать релеватные рекомендации для конкретного пользователя
29
- \n- ##### Построить Streamlit приложение для общедоступного пользования
30
  """)
31
 
32
  st.info("""
33
  ### Используемые технологии (Стек проекта):
34
  \n- ##### Python
35
  \n- ##### Языковая модель ruBERT-tiny
36
- \n- ##### Библиотеки: BeautifulSoup4, Sentence Transformers, faiss, transformers и др.
37
  \n- ##### Cosine similarity для рекомендаций
38
  \n- ##### Hugging Face & Streamlit
39
  """)
 
1
  import streamlit as st
2
+ from st_pages import Page, show_pages
3
 
4
+ show_pages(
5
+ [
6
+ Page("main.py", "Home page"),
7
+ Page('pages/Recommend_page.py', 'Recommend page'),
8
+ Page('pages/Results.py', 'Results page')
9
+ ]
10
+ )
11
 
12
  st.header("""
13
  Проект по рекомендациям книг различного жанра📚
 
18
 
19
  st.write("""
20
  ### Уникальный состав команды:
21
+ \n- ##### Алиса Жгир
22
+ \n- ##### Тигран Арутюнян
23
+ \n- ##### Руслан Волощенко
24
  """)
25
 
26
  st.info("""
 
31
 
32
  st.info("""
33
  ### Задачи:
34
+ \n- ##### Построить алгоритм парсинга информации с книжного сайта
35
+ \n- ##### Полученные данные очистить и сделать рабочий Dataset
36
+ \n- ##### Создать RecSys, способную делать релеватные рекомендации для конкретного пользователя
37
+ \n- ##### Построить Streamlit приложение для общедоступного пользования
38
  """)
39
 
40
  st.info("""
41
  ### Используемые технологии (Стек проекта):
42
  \n- ##### Python
43
  \n- ##### Языковая модель ruBERT-tiny
44
+ \n- ##### Библиотеки: BeautifulSoup4, Sentence Transformers, faiss, transformers, genim и др.
45
  \n- ##### Cosine similarity для рекомендаций
46
  \n- ##### Hugging Face & Streamlit
47
  """)
datasets/{cleaned_final_books.csv → final_dataset.csv} RENAMED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:38f44e078bf054ba110c343e91c9b5737012aa6361519740098fdf5a826fb93f
3
- size 16930385
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c228edb51b93b9c40af0751a3ad330ee70e72c4bcca247793279236e1e52883e
3
+ size 16996733
model/bert.py CHANGED
@@ -6,13 +6,21 @@ import faiss
6
  from transformers import AutoTokenizer, AutoModel
7
 
8
 
9
- weight = "cointegrated/rubert-tiny2"
10
 
11
- tokenizer = AutoTokenizer.from_pretrained(weight)
12
- model = AutoModel.from_pretrained(weight)
13
 
14
  vectors_annotation = np.load('datasets/annotation_embeddings2.npy')
15
- data_frame = pd.read_csv('datasets/cleaned_final_books.csv')
 
 
 
 
 
 
 
 
16
 
17
  MAX_LEN = 512
18
 
@@ -21,24 +29,22 @@ faiss_index = faiss.IndexFlatL2(312)
21
  faiss_index.add(vectors_annotation)
22
 
23
 
24
- def recommend(text, top_k):
25
 
26
- tokenized_text = tokenizer.encode(text, add_special_tokens=True, truncation=True, max_length=MAX_LEN)
27
  tokenized_text = torch.tensor(tokenized_text).unsqueeze(0)
28
 
29
  with torch.inference_mode():
30
  predict = model(tokenized_text)
31
 
32
- vector = predict[0][:, 0, :].squeeze().cpu().numpy()
33
 
34
- vector = np.array([vector])
35
  value_metrics, index = faiss_index.search(vector, k=top_k)
36
 
37
- recommend_books = data_frame.iloc[index.reshape(top_k,)][['category_name', 'author', 'title', 'age', 'annotation']].reset_index(drop=True)
38
- recommend_books = recommend_books.rename({'category_name': 'Жанр', 'author': 'Автор', 'title': 'Название книги', \
39
- 'age': 'Возрастное ограничение', 'annotation': 'Аннотация'}, axis=1)
40
 
41
- return recommend_books
42
 
43
 
44
 
 
6
  from transformers import AutoTokenizer, AutoModel
7
 
8
 
9
+ CHECKPOINT = "cointegrated/rubert-tiny2"
10
 
11
+ tokenizer = AutoTokenizer.from_pretrained(CHECKPOINT)
12
+ model = AutoModel.from_pretrained(CHECKPOINT)
13
 
14
  vectors_annotation = np.load('datasets/annotation_embeddings2.npy')
15
+
16
+ data_frame = pd.read_csv('datasets/final_dataset.csv')
17
+
18
+ data_frame = pd.DataFrame({
19
+ 'Cсылка на книгу': data_frame['page_url'],
20
+ 'Обложка': data_frame['image_url'],
21
+ 'Инфо': data_frame[['category_name', 'age', 'title', 'author']].agg(', '.join, axis=1),
22
+ 'Аннотация': data_frame['annotation']
23
+ })
24
 
25
  MAX_LEN = 512
26
 
 
29
  faiss_index.add(vectors_annotation)
30
 
31
 
32
+ def recommend(query: str, top_k: int) -> pd.DataFrame:
33
 
34
+ tokenized_text = tokenizer.encode(query, add_special_tokens=True, truncation=True, max_length=MAX_LEN)
35
  tokenized_text = torch.tensor(tokenized_text).unsqueeze(0)
36
 
37
  with torch.inference_mode():
38
  predict = model(tokenized_text)
39
 
40
+ vector = np.array([predict[0][:, 0, :].squeeze().cpu().numpy()])
41
 
 
42
  value_metrics, index = faiss_index.search(vector, k=top_k)
43
 
44
+ value_metrics = np.round(value_metrics.reshape(top_k, ))
45
+ recommend_books = data_frame.iloc[index.reshape(top_k, ), 1:].reset_index(drop=True)
 
46
 
47
+ return recommend_books, value_metrics
48
 
49
 
50
 
pages/Recommend_page.py CHANGED
@@ -10,7 +10,7 @@ from io import BytesIO
10
  from model.bert import recommend
11
 
12
 
13
- list_genre = ['Классическая литература', 'Современная проза', 'Отечественные детективы',
14
  'Зарубежные детективы', 'Иронические детективы', 'Отечественная фантастика', 'Зарубежная фантастика',
15
  'Отечественное фэнтези', 'Зарубежное фэнтези', 'Ужасы', 'Фантастический боевик',
16
  'Российские любовные романы', 'Зарубежные любовные романы', 'Поэзия', 'Драматургия',
@@ -23,8 +23,7 @@ st.header("""
23
  """, divider='blue')
24
 
25
  st.info("""
26
- - ##### Именно здесь вы сможете получить ТОП-рекомендаций под ваши предпочтения и желания🔝
27
- \n- ##### Вам предстоит лишь сделать краткое описание книги, которую вы хотели бы прочитать, и выбрать некоторые параметры поиска⚙️
28
  """)
29
 
30
  st.image('images/recsys_image.png', caption='Картинка сгенерирована DALL-E')
@@ -35,9 +34,7 @@ st.write("""
35
 
36
  text_users = st.text_input('**Пожалуйста, опишите ваши предпочтения по выбору книги (какой она должна быть):**')
37
 
38
- genre_book = st.selectbox('**Пожалуйста, укажите жанр книги:**', list_genre)
39
-
40
- author = st.text_input('**Пожалуйста, укажите имя автора, если для вас это важно (❗НЕОБЯЗАТЕЛЬНО):**')
41
 
42
  count_recommended = st.slider('**Пожалуйста, укажите какое количество рекомендаций Вы хотите получить:**', min_value=1, max_value=10, value=5)
43
 
@@ -46,13 +43,51 @@ start_time = time.time()
46
 
47
  if push_button:
48
 
49
- recommend_book = recommend(text_users, count_recommended)
50
 
51
- st.write(f"""
52
  #### Модель нашла лучшие рекомендации для Вас🎉 :
53
- \n- ##### Это заняло всего {round(time.time() - start_time, 3)} сек.
54
  """)
55
- st.table(recommend_book)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  time.sleep(3)
57
  with st.sidebar:
58
  st.info("""
 
10
  from model.bert import recommend
11
 
12
 
13
+ LIST_GENRE = ['Классическая литература', 'Современная проза', 'Отечественные детективы',
14
  'Зарубежные детективы', 'Иронические детективы', 'Отечественная фантастика', 'Зарубежная фантастика',
15
  'Отечественное фэнтези', 'Зарубежное фэнтези', 'Ужасы', 'Фантастический боевик',
16
  'Российские любовные романы', 'Зарубежные любовные романы', 'Поэзия', 'Драматургия',
 
23
  """, divider='blue')
24
 
25
  st.info("""
26
+ ##### Чуть ниже Вы можете сделать краткое описание книги, которую Вы хотели бы прочитать, и выбрать некоторые параметры поиска⚙️
 
27
  """)
28
 
29
  st.image('images/recsys_image.png', caption='Картинка сгенерирована DALL-E')
 
34
 
35
  text_users = st.text_input('**Пожалуйста, опишите ваши предпочтения по выбору книги (какой она должна быть):**')
36
 
37
+ genre_book = st.selectbox('**Пожалуйста, укажите жанр книги:**', options=LIST_GENRE, index=None)
 
 
38
 
39
  count_recommended = st.slider('**Пожалуйста, укажите какое количество рекомендаций Вы хотите получить:**', min_value=1, max_value=10, value=5)
40
 
 
43
 
44
  if push_button:
45
 
46
+ recommend_book, value_metrics = recommend(text_users, count_recommended)
47
 
48
+ st.write("""
49
  #### Модель нашла лучшие рекомендации для Вас🎉 :
 
50
  """)
51
+ st.info(f"""
52
+ - ##### Это заняло всего {round(time.time() - start_time, 3)} сек.
53
+ """)
54
+
55
+ col1, col2, col3, col4 = st.columns(4)
56
+
57
+ with col1:
58
+ st.write('##### Обложка')
59
+
60
+ with col2:
61
+ st.write('##### Инфо')
62
+
63
+ with col3:
64
+ st.write('##### Аннотация')
65
+
66
+ with col4:
67
+ st.write('##### Величина сходства (Евклидово расстояние)')
68
+ st.divider()
69
+
70
+ for index in range(count_recommended):
71
+ col1, col2, col3, col4 = st.columns(4)
72
+
73
+ response = requests.get(recommend_book.loc[index, 'Обложка'])
74
+
75
+ image_bytes = BytesIO(response.content)
76
+ image = Image.open(image_bytes)
77
+
78
+ with col1:
79
+ st.image(image)
80
+
81
+ with col2:
82
+ st.write(f"{recommend_book.loc[index, 'Инфо']}")
83
+
84
+ with col3:
85
+ st.write(f"{recommend_book.loc[index, 'Аннотация']}")
86
+
87
+ with col4:
88
+ st.write(f'{value_metrics[index]}')
89
+ st.divider()
90
+
91
  time.sleep(3)
92
  with st.sidebar:
93
  st.info("""
requirements.txt CHANGED
@@ -60,3 +60,4 @@ tzlocal==5.2
60
  urllib3==2.1.0
61
  validators==0.22.0
62
  zipp==3.17.0
 
 
60
  urllib3==2.1.0
61
  validators==0.22.0
62
  zipp==3.17.0
63
+ st-pages==0.4.5