Spaces:
Sleeping
Sleeping
""" | |
خدمة استخراج البنود من المستندات | |
""" | |
import re | |
import pandas as pd | |
import numpy as np | |
import nltk | |
from nltk.tokenize import sent_tokenize | |
from pathlib import Path | |
import config | |
class ItemExtractor: | |
"""استخراج البنود من المستندات""" | |
def __init__(self): | |
# تحميل موارد NLTK إذا لم تكن موجودة | |
try: | |
nltk.data.find('tokenizers/punkt') | |
except LookupError: | |
nltk.download('punkt') | |
# قائمة الكلمات المفتاحية التي تشير إلى بداية البنود | |
self.item_indicators = [ | |
'توريد', 'تركيب', 'تنفيذ', 'تصنيع', 'أعمال', 'تأمين', | |
'تقديم', 'إنشاء', 'صيانة', 'إزالة', 'نقل', 'تجهيز', | |
'فك', 'تسليم', 'تطبيق', 'تثبيت', 'تشطيب', 'تجهيز' | |
] | |
# قائمة فئات البنود | |
self.categories = { | |
'أعمال الأساسات': ['أساس', 'قاعدة', 'حفر', 'ردم', 'خرسانة', 'اسمنت', 'قواعد'], | |
'أعمال الهيكل الإنشائي': ['عمود', 'سقف', 'كمرة', 'خرسانة', 'حديد تسليح', 'بلاطة', 'هيكل'], | |
'أعمال التشطيبات': ['دهان', 'بلاط', 'سيراميك', 'رخام', 'جبس', 'زجاج', 'باب', 'نافذة', 'أرضية'], | |
'أعمال الكهرباء': ['كهرباء', 'إضاءة', 'مفتاح', 'سلك', 'لوحة', 'كابل', 'تمديد'], | |
'أعمال السباكة': ['ماء', 'صرف', 'مواسير', 'حمام', 'مغسلة', 'خزان', 'مضخة'], | |
'أعمال التكييف': ['تكييف', 'تبريد', 'تهوية', 'مكيف', 'مجرى هواء', 'فلتر'], | |
'أعمال الموقع': ['تسوية', 'تخطيط', 'أسوار', 'بوابات', 'طرق', 'رصف', 'تشجير'], | |
'المستندات': ['مخططات', 'رسومات', 'تقارير', 'شهادات', 'اختبارات'] | |
} | |
def extract_items(self, text): | |
"""استخراج البنود من النص""" | |
if not text: | |
return pd.DataFrame() | |
# تقسيم النص إلى جمل | |
sentences = sent_tokenize(text) | |
# البحث عن البنود المحتملة | |
items = [] | |
item_id = 1 | |
for sentence in sentences: | |
# تحقق مما إذا كانت الجملة تحتوي على مؤشر بند | |
if any(indicator in sentence for indicator in self.item_indicators): | |
# تحديد الفئة | |
category = self._determine_category(sentence) | |
# تحديد الأهمية | |
importance = self._determine_importance(sentence) | |
# إضافة البند إلى القائمة | |
items.append({ | |
'رقم البند': f"I{item_id:03d}", | |
'وصف البند': sentence.strip(), | |
'الفئة': category, | |
'الأهمية': importance, | |
'الثقة': round(np.random.uniform(0.75, 0.95), 2) # محاكاة ثقة التعرف | |
}) | |
item_id += 1 | |
# تحويل القائمة إلى DataFrame | |
items_df = pd.DataFrame(items) | |
# التأكد من وجود بيانات | |
if items_df.empty: | |
# إنشاء DataFrame فارغ بالأعمدة المطلوبة | |
items_df = pd.DataFrame(columns=[ | |
'رقم البند', 'وصف البند', 'الفئة', 'الأهمية', 'الثقة' | |
]) | |
return items_df | |
def _determine_category(self, text): | |
"""تحديد فئة البند بناءً على محتواه""" | |
# البحث عن الكلمات المفتاحية في النص | |
scores = {} | |
for category, keywords in self.categories.items(): | |
score = sum(1 for keyword in keywords if keyword in text.lower()) | |
scores[category] = score | |
# اختيار الفئة ذات الدرجة الأعلى | |
if max(scores.values()) > 0: | |
return max(scores.items(), key=lambda x: x[1])[0] | |
else: | |
return "أخرى" | |
def _determine_importance(self, text): | |
"""تحديد أهمية البند بناءً على محتواه""" | |
# كلمات تشير إلى أهمية عالية | |
high_importance_words = [ | |
'ضروري', 'هام', 'أساسي', 'رئيسي', 'كبير', 'مهم', | |
'حرج', 'أمان', 'سلامة', 'صحة', 'بيئة' | |
] | |
# كلمات تشير إلى أهمية منخفضة | |
low_importance_words = [ | |
'ثانوي', 'إضافي', 'تجميلي', 'مكمل', 'اختياري' | |
] | |
# حساب درجة الأهمية | |
high_score = sum(1 for word in high_importance_words if word in text.lower()) | |
low_score = sum(1 for word in low_importance_words if word in text.lower()) | |
# تحديد الأهمية بناءً على الدرجات | |
if high_score > low_score: | |
return "عالية" | |
elif low_score > high_score: | |
return "منخفضة" | |
else: | |
return "متوسطة" |