Spaces:
Sleeping
Sleeping
| import pandas as pd | |
| import numpy as np | |
| import plotly.express as px | |
| from sklearn.decomposition import PCA | |
| from sklearn.metrics.pairwise import cosine_similarity | |
| from sentence_transformers import SentenceTransformer | |
| import warnings | |
| warnings.filterwarnings('ignore') | |
| # ========================================== | |
| # 1. KHỞI TẠO MODELS (Load sẵn khi import file) | |
| # ========================================== | |
| print("[Utils] Đang khởi tạo các mô hình...") | |
| model_sbert = SentenceTransformer('keepitreal/vietnamese-sbert') | |
| model_e5 = SentenceTransformer('intfloat/multilingual-e5-base') | |
| model_bge = SentenceTransformer('BAAI/bge-m3') | |
| print("[Utils] Đã load xong 3 models!") | |
| # ========================================== | |
| # 2. DỮ LIỆU NỀN (KNOWLEDGE BASE) | |
| # ========================================== | |
| base_sentences = [ | |
| "Tôi rất thích nghiên cứu về Trí tuệ nhân tạo.", | |
| "I love studying Artificial Intelligence.", | |
| "Con mèo đang ngủ trên ghế sofa.", | |
| "The cat is taking a nap on the couch.", | |
| "Công thức làm bánh pizza ngon nhất thế giới." | |
| ] | |
| # ========================================== | |
| # 3. HÀM XỬ LÝ LOGIC LÕI | |
| # ========================================== | |
| def process_embedding_analysis(user_text, base_text_input): | |
| """ | |
| Nhận text từ UI, tính toán vector, trả về Biểu đồ Plotly và Dataframe kết quả. | |
| """ | |
| if not user_text.strip(): | |
| return None, None, None, pd.DataFrame() | |
| base_sentences = [s.strip() for s in base_text_input.split('\n') if s.strip()] | |
| if len(base_sentences) == 0: | |
| return None, None, None, pd.DataFrame({"Lỗi": ["Vui lòng nhập ít nhất 1 câu vào Dữ liệu nền!"]}) | |
| # Tui viết một cái hàm nhỏ (helper function) bên trong để tái sử dụng code cho gọn nè | |
| def get_plot_and_sim(model, model_name, is_e5=False): | |
| sentences_to_encode = base_sentences.copy() | |
| query_to_encode = user_text | |
| # Xử lý riêng cho E5 (cái vụ gắn prefix á) | |
| if is_e5: | |
| sentences_to_encode = [f"passage: {text}" for text in base_sentences] | |
| query_to_encode = f"query: {user_text}" | |
| base_embeddings = model.encode(sentences_to_encode) | |
| user_embedding = model.encode([query_to_encode]) | |
| similarities = cosine_similarity(user_embedding, base_embeddings)[0] | |
| # Tính PCA | |
| all_texts = sentences_to_encode + [query_to_encode] | |
| all_emb = model.encode(all_texts) | |
| n_samples = len(all_texts) | |
| n_comp = min(2, n_samples) | |
| pca = PCA(n_components=n_comp) | |
| emb_2d = pca.fit_transform(all_emb) | |
| # pca = PCA(n_components=2) | |
| # emb_2d = pca.fit_transform(all_emb) | |
| if n_comp == 1: | |
| emb_2d = np.hstack((emb_2d, np.zeros((n_samples, 1)))) | |
| df_plot = pd.DataFrame({ | |
| 'X': emb_2d[:, 0], 'Y': emb_2d[:, 1], | |
| 'Text': base_sentences + [user_text], | |
| 'Loại': ["Dữ liệu nền"] * len(base_sentences) + ["Câu bạn nhập"] | |
| }) | |
| # Vẽ hình | |
| fig = px.scatter( | |
| df_plot, x='X', y='Y', color='Loại', hover_name='Text', | |
| title=f"{model_name}", | |
| color_discrete_map={"Dữ liệu nền": "#636EFA", "Câu bạn nhập": "#EF553B"} | |
| ) | |
| # Vẽ đường nối | |
| best_match_idx = similarities.argmax() | |
| fig.add_shape( | |
| type="line", | |
| x0=emb_2d[-1, 0], y0=emb_2d[-1, 1], | |
| x1=emb_2d[best_match_idx, 0], y1=emb_2d[best_match_idx, 1], | |
| line=dict(color="gray", width=2, dash="dot"), layer="below" | |
| ) | |
| # Thu nhỏ margin xíu cho 3 biểu đồ đứng cạnh nhau không bị chật | |
| fig.update_traces(marker=dict(size=10, line=dict(width=1, color='white'))) | |
| fig.update_layout(template="plotly_white", margin=dict(l=10, r=10, t=35, b=10)) | |
| return fig, similarities | |
| # Bắt đầu chạy cả 3 con AI nè | |
| fig_sbert, sim_sbert = get_plot_and_sim(model_sbert, "1. Vietnamese SBERT") | |
| fig_e5, sim_e5 = get_plot_and_sim(model_e5, "2. Microsoft E5", is_e5=True) | |
| fig_bge, sim_bge = get_plot_and_sim(model_bge, "3. BAAI BGE-M3") | |
| # Gộp điểm của 3 con vào chung 1 cái bảng cho dễ nhìn á | |
| results_df = pd.DataFrame({ | |
| "Câu trong Database": base_sentences, | |
| "SBERT (%)": [round(s * 100, 1) for s in sim_sbert], | |
| "E5 (%)": [round(s * 100, 1) for s in sim_e5], | |
| "BGE-M3 (%)": [round(s * 100, 1) for s in sim_bge] | |
| }) | |
| return fig_sbert, fig_e5, fig_bge, results_df |