embeddingvector / analyze_embedding.py
mastershlfu
Fix app.py
679ad8d
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