📋 خلاصه نتایج
این گزارش نتایج بنچمارک سه مدل مختلف برای ناشناسسازی متون فارسی را نشان میدهد. متریکهای ارزیابی شامل درستی اندیسگذاری، ثبات استفاده از شناسهها، حفظ ساختار متن و پوشش موجودیتها میباشد.
import pandas as pd import re import numpy as np import json from typing import Dict, List, Any, Tuple import gradio as gr from pathlib import Path import plotly.graph_objects as go import plotly.express as px from dataclasses import dataclass from datetime import datetime @dataclass class BenchmarkMetrics: """کلاس متریکهای بنچمارک""" model_name: str total_texts: int total_entities: int accuracy: float # درستی کلی ناشناسسازی recall: float # پوشش موجودیتها precision: float # دقت شناسایی class AnonymizationBenchmark: """کلاس اصلی بنچمارک ناشناسسازی""" def __init__(self): self.models_data = {} self.benchmark_results = {} def load_csv_files(self, chatgpt_file, grok_file, llama_file): """بارگذاری فایلهای CSV""" try: # بارگذاری فایلها chatgpt_df = pd.read_csv(chatgpt_file) grok_df = pd.read_csv(grok_file) llama_df = pd.read_csv(llama_file) # بررسی ستونها required_columns = ['original_text', 'anonymized_text'] for df_name, df in [('ChatGPT', chatgpt_df), ('Grok', grok_df), ('Llama', llama_df)]: if not all(col in df.columns for col in required_columns): raise ValueError(f"فایل {df_name} فاقد ستونهای مورد نیاز است") self.models_data = { 'ChatGPT': chatgpt_df, 'Grok': grok_df, 'Llama-3.1-8B': llama_df } return True, "فایلها با موفقیت بارگذاری شدند" except Exception as e: return False, f"خطا در بارگذاری فایلها: {str(e)}" def extract_entities_from_text(self, text: str) -> Dict[str, List[str]]: """استخراج موجودیتها از متن""" entities = { 'companies': re.findall(r'company-(\d+)', text), 'persons': re.findall(r'person-(\d+)', text), 'amounts': re.findall(r'amount-(\d+)', text), 'percents': re.findall(r'percent-(\d+)', text), 'groups': re.findall(r'group-(\d+)', text) } return entities def count_original_entities(self, text: str) -> int: """تخمین تعداد موجودیتهای قابل ناشناسسازی در متن اصلی""" # الگوهای شناسایی موجودیتها در متن فارسی patterns = [ r'[۰-۹]+(?:\.[۰-۹]+)?\s*(?:میلیارد|میلیون|هزار)?\s*(?:تومان|ریال|دلار|یورو)', # اعداد پولی r'[۰-۹]+(?:\.[۰-۹]+)?\s*درصد', # درصدها r'\b[آ-ی\s]{2,30}\b(?:\s*(?:شرکت|بانک|گروه|سازمان))', # شرکتها r'\b[آ-ی\s]{2,20}\b(?:\s*(?:مدیرعامل|رئیس|مدیر))', # اشخاص r'[۰-۹]+(?:\.[۰-۹]+)?(?:\s*(?:میلیون|میلیارد|هزار))?', # سایر اعداد ] total_entities = 0 for pattern in patterns: matches = re.findall(pattern, text) total_entities += len(matches) return max(total_entities, 1) # حداقل 1 برای جلوگیری از تقسیم بر صفر def check_indexing_correctness(self, entities: Dict[str, List[str]]) -> float: """بررسی درستی اندیسگذاری""" total_checks = 0 passed_checks = 0 for entity_type, indices in entities.items(): if not indices: continue total_checks += 1 unique_indices = sorted([int(x) for x in set(indices)]) # بررسی شروع از 1 if unique_indices[0] == 1: passed_checks += 0.5 # بررسی پیوستگی expected = list(range(1, len(unique_indices) + 1)) if unique_indices == expected: passed_checks += 0.5 return passed_checks / total_checks if total_checks > 0 else 0.0 def calculate_structure_preservation(self, original_text: str, anonymized_text: str) -> float: """محاسبه امتیاز حفظ ساختار""" # کلمات مهم که باید حفظ شوند important_words = [ 'میلیارد', 'میلیون', 'تومان', 'ریال', 'درصد', 'سود', 'زیان', 'مدیرعامل', 'شرکت', 'بانک', 'درآمد', 'سال', 'ماه' ] score = 0.0 total_checks = len(important_words) for word in important_words: if word in original_text and word in anonymized_text: score += 1.0 elif word not in original_text: total_checks -= 1 # بررسی حفظ تعداد کلمات (تقریبی) original_words = len(original_text.split()) anonymized_words = len(anonymized_text.split()) if original_words > 0: word_ratio = min(anonymized_words / original_words, 1.0) score += word_ratio * 2 total_checks += 2 return score / total_checks if total_checks > 0 else 0.0 def calculate_accuracy(self, original_text: str, anonymized_text: str) -> float: """محاسبه درستی کلی ناشناسسازی""" entities = self.extract_entities_from_text(anonymized_text) # بررسی درستی اندیسگذاری indexing_score = self.check_indexing_correctness(entities) # بررسی حفظ ساختار structure_score = self.calculate_structure_preservation(original_text, anonymized_text) # میانگین وزنی accuracy = (indexing_score * 0.6) + (structure_score * 0.4) return accuracy def calculate_recall(self, original_text: str, anonymized_text: str) -> float: """محاسبه پوشش موجودیتها (Recall)""" original_entity_count = self.count_original_entities(original_text) entities = self.extract_entities_from_text(anonymized_text) anonymized_entity_count = sum(len(set(v)) for v in entities.values()) return min(anonymized_entity_count / original_entity_count, 1.0) def calculate_precision(self, anonymized_text: str) -> float: """محاسبه دقت شناسایی (Precision)""" entities = self.extract_entities_from_text(anonymized_text) # بررسی کیفیت موجودیتهای شناسایی شده total_entities = sum(len(v) for v in entities.values()) if total_entities == 0: return 0.0 # بررسی درستی فرمت شناسهها correct_entities = 0 for entity_type, indices in entities.items(): for idx in indices: if idx.isdigit() and int(idx) > 0: correct_entities += 1 # بررسی عدم تکرار غیرضروری unique_entities = sum(len(set(v)) for v in entities.values()) consistency_bonus = unique_entities / total_entities if total_entities > 0 else 0 base_precision = correct_entities / total_entities if total_entities > 0 else 0 return (base_precision * 0.7) + (consistency_bonus * 0.3) def analyze_model(self, model_name: str, df: pd.DataFrame) -> BenchmarkMetrics: """تحلیل یک مدل""" print(f"تحلیل مدل {model_name}...") total_texts = len(df) # محاسبه متریکها برای هر متن accuracy_scores = [] recall_scores = [] precision_scores = [] total_entities = 0 for _, row in df.iterrows(): original = str(row['original_text']) anonymized = str(row['anonymized_text']) # محاسبه متریکها accuracy_scores.append(self.calculate_accuracy(original, anonymized)) recall_scores.append(self.calculate_recall(original, anonymized)) precision_scores.append(self.calculate_precision(anonymized)) # شمارش موجودیتها entities = self.extract_entities_from_text(anonymized) total_entities += sum(len(set(v)) for v in entities.values()) return BenchmarkMetrics( model_name=model_name, total_texts=total_texts, total_entities=total_entities, accuracy=round(np.mean(accuracy_scores), 3), recall=round(np.mean(recall_scores), 3), precision=round(np.mean(precision_scores), 3) ) def run_benchmark(self) -> Tuple[bool, str, str]: """اجرای بنچمارک کامل""" if not self.models_data: return False, "ابتدا فایلها را بارگذاری کنید", "" try: results = {} # تحلیل هر مدل for model_name, df in self.models_data.items(): results[model_name] = self.analyze_model(model_name, df) self.benchmark_results = results # تولید HTML html_report = self.generate_html_report() return True, "بنچمارک با موفقیت انجام شد", html_report except Exception as e: return False, f"خطا در اجرای بنچمارک: {str(e)}", "" def generate_comparison_table(self) -> str: """تولید جدول مقایسه""" if not self.benchmark_results: return "
هنوز بنچمارکی انجام نشده است
" # آمادهسازی دادهها برای جدول table_data = [] for model_name, metrics in self.benchmark_results.items(): table_data.append({ 'مدل': model_name, 'تعداد متنها': metrics.total_texts, 'کل موجودیتها': metrics.total_entities, '🎯 دقت (Accuracy)': f"{metrics.accuracy:.3f}", '📊 بازیابی (Recall)': f"{metrics.recall:.3f}", '✅ دقت شناسایی (Precision)': f"{metrics.precision:.3f}" }) # تولید HTML جدول html = """| {header} | " html += "|
|---|---|
| {value} | " else: html += f"{value} | " html += "
مقایسه عملکرد مدلهای ChatGPT، Grok و Llama-3.1-8B
این گزارش نتایج بنچمارک سه مدل مختلف برای ناشناسسازی متون فارسی را نشان میدهد. متریکهای ارزیابی شامل درستی اندیسگذاری، ثبات استفاده از شناسهها، حفظ ساختار متن و پوشش موجودیتها میباشد.
دادهای برای تحلیل یافت نشد
" # یافتن بهترین مدل در هر متریک best_accuracy = max(self.benchmark_results.keys(), key=lambda k: self.benchmark_results[k].accuracy) best_recall = max(self.benchmark_results.keys(), key=lambda k: self.benchmark_results[k].recall) best_precision = max(self.benchmark_results.keys(), key=lambda k: self.benchmark_results[k].precision) # محاسبه میانگین avg_accuracy = np.mean([m.accuracy for m in self.benchmark_results.values()]) avg_recall = np.mean([m.recall for m in self.benchmark_results.values()]) avg_precision = np.mean([m.precision for m in self.benchmark_results.values()]) analysis = f"""