File size: 3,126 Bytes
83a648d
 
 
 
c1b3993
83a648d
5bbc734
7f410f4
83a648d
 
 
 
 
 
 
 
 
99c2aa0
5bbc734
 
 
 
fb540e3
5bbc734
 
 
e79c988
 
 
 
 
 
 
 
5bbc734
 
83a648d
 
5bbc734
 
 
 
8e3efa7
5bbc734
c1b3993
7f410f4
 
c1b3993
7f410f4
 
c1b3993
7f410f4
 
c1b3993
7f410f4
 
 
c1b3993
7f410f4
 
c1b3993
 
7f410f4
 
 
 
 
 
 
c1b3993
7f410f4
c1b3993
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
import streamlit as st
import torch
import numpy as np
import pandas as pd
from PIL import Image
from transformers import AutoTokenizer, AutoModel
import re
import pickle

st.title("Книжные рекомендации")

# Загрузка модели и токенизатора
model_name = "cointegrated/rubert-tiny2"
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name, output_hidden_states=True)

# Загрузка датасета и аннотаций к книгам
books = pd.read_csv('books_6000.csv')
books.dropna(inplace=True)

books = books[books['annotation'].apply(lambda x: len(x.split()) >= 10)]
books.drop_duplicates(subset='title', keep='first', inplace=True)
books = books.reset_index(drop=True)


def data_preprocessing(text: str) -> str:
    text = re.sub(r'http\S+', " ", text)  # удаляем ссылки
    text = re.sub(r'@\w+', ' ', text)  # удаляем упоминания пользователей
    text = re.sub(r'#\w+', ' ', text)  # удаляем хэштеги
    text = re.sub(r'<.*?>', ' ', text)  # html tags
    return text


for i in ['author', 'title', 'annotation']:
    books[i] = books[i].apply(data_preprocessing)

annot = books['annotation']

# Получение эмбеддингов аннотаций каждой книги в датасете
max_len = 128

# Определение запроса пользователя
query = st.text_input("Введите запрос")

if st.button('Сгенерировать'):
    with open("book_embeddings.pkl", "rb") as f:
        book_embeddings = pickle.load(f)

    query_tokens = tokenizer.encode(query, add_special_tokens=True,
                                    truncation=True, max_length=max_len)

    query_padded = np.array(query_tokens + [0] * (max_len - len(query_tokens)))
    query_mask = np.where(query_padded != 0, 1, 0)

    # Переведем numpy массивы в тензоры PyTorch
    query_padded = torch.tensor(query_padded, dtype=torch.long)
    query_mask = torch.tensor(query_mask, dtype=torch.long)

    with torch.no_grad():
        query_embedding = model(query_padded.unsqueeze(0), query_mask.unsqueeze(0))
        query_embedding = query_embedding[0][:, 0, :]

    # Вычисление косинусного расстояния между эмбеддингом запроса и каждой аннотацией
    cosine_similarities = torch.nn.functional.cosine_similarity(
        query_embedding.squeeze(0),
        torch.stack(book_embeddings)
    )

    cosine_similarities = cosine_similarities.numpy()

    indices = np.argsort(cosine_similarities)[::-1]  # Сортировка по убыванию

    num_books_per_page = st.selectbox("Количество книг на странице:", [3, 5, 10], index=0)

    for i in indices[:num_books_per_page]:
        st.write("## " + books['title'][i])
        st.write("**Автор:**", books['author'][i])
        st.write("**Аннотация:**", books['annotation'][i])
        st.image(Image.open(books['image_url'][i]))
        st.write("---")