File size: 5,700 Bytes
fb20480
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
"""

خدمة استخراج البنود من المستندات

"""

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 "متوسطة"