v3 / modules /services /item_extractor.py
EGYADMIN's picture
Upload 115 files
82676b8 verified
"""
خدمة استخراج البنود من المستندات
"""
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 "متوسطة"