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 import requests from io import BytesIO 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]: cols = st.columns(2) # Создание двух столбцов для размещения информации и изображения cols[1].write("## " + books['title'][i]) cols[1].markdown("**Автор:** " + books['author'][i]) cols[1].markdown("**Аннотация:** " + books['annotation'][i]) image_url = books['image_url'][i] response = requests.get(image_url) image = Image.open(BytesIO(response.content)) cols[0].image(image) cols[1].write("---")