اصلاح سورس ها که به صورت تکی جواب دهند
This commit is contained in:
parent
6318c7ce1e
commit
c62adce4cd
|
@ -13,7 +13,6 @@ from elastic_helper import ElasticHelper
|
|||
import json
|
||||
|
||||
def get_sections():
|
||||
|
||||
# region خواندن کل سکشن ها از فایل جیسون
|
||||
# sections_path = "/home/gpu/data_11/14040423/mj_qa_section.zip"
|
||||
# eh_obj = ElasticHelper()
|
||||
|
|
119
p1_classifier.py
119
p1_classifier.py
|
@ -10,12 +10,16 @@ import datetime
|
|||
import pandas as pd
|
||||
from transformers import AutoTokenizer
|
||||
print(f'transformers version: {transformers.__version__}')
|
||||
from elastic_helper import ElasticHelper
|
||||
|
||||
date = datetime.datetime.now()
|
||||
today = f'{date.year}-{date.month}-{date.day}-{date.hour}'
|
||||
|
||||
# finetuned model for classification path
|
||||
model_checkpoint = './models/classifier/findtuned_classification_hoosh_with_path_v2__30/checkpoint-1680'
|
||||
|
||||
tokenizer = AutoTokenizer.from_pretrained(model_checkpoint)
|
||||
print(f'Classification Model Loaded: {model_checkpoint}')
|
||||
|
||||
window_size = 512
|
||||
"""
|
||||
(یعنی سایز پنجره) به این دلیل که تعداد توکن های ورودی به مدل، محدود به متغیر بالاست
|
||||
|
@ -27,13 +31,55 @@ step_size = 350#100
|
|||
Top_k = 4
|
||||
# set device = 0 => to use GPU
|
||||
classifier = pipeline("text-classification", model_checkpoint, framework="pt", device=0)
|
||||
print(f'Classification Model Loaded: {model_checkpoint}')
|
||||
|
||||
def get_class(sentences, top_k:int=4):
|
||||
def get_sections():
|
||||
"""
|
||||
دریافت کل سکشن های قانونی در مسیر مشخص شده
|
||||
"""
|
||||
sections_path = "/home/gpu/data_11/14040423/mj_qa_section.zip"
|
||||
eh_obj = ElasticHelper()
|
||||
sections = eh_obj.iterateJsonFile(sections_path, True)
|
||||
sections = convert_to_dict(sections)
|
||||
return sections
|
||||
|
||||
def convert_to_dict(sections):
|
||||
"""
|
||||
تبدیل لیست سکشن های قانون به دیکشنری
|
||||
"""
|
||||
sections_dict = {}
|
||||
for item in sections:
|
||||
id = item['id']
|
||||
source = item['source']
|
||||
sections_dict[id] = source
|
||||
|
||||
return sections_dict
|
||||
|
||||
def get_class(sentence, top_k:int=4):
|
||||
"""
|
||||
متدی برای تعیین تعدادی از بهترین کلاس های متناسب با متن ورودی
|
||||
|
||||
Args:
|
||||
sentence(str): متنی که قرار است مدل، کلاس های آن را تشخیص دهد
|
||||
top_k(int): تعداد کلاس هایی که بر اساس اولویت امتیاز، مدل باید تشخیص دهد
|
||||
|
||||
Returns:
|
||||
recognized_class(list[obj]): لیستی از آبجکت کلاس ها شامل عنوان و امتیاز هر کلاس
|
||||
"""
|
||||
# sentences = cleaning(sentences)
|
||||
out = classifier(sentences, top_k=top_k, truncation=True, max_length=window_size)
|
||||
return out
|
||||
recognized_class = classifier(sentence, top_k=top_k, truncation=True, max_length=window_size)
|
||||
return recognized_class
|
||||
|
||||
def mean_classes(input_classes):
|
||||
"""
|
||||
محاسبه کلاس بر اساس میانگین امتیازات کلاس های مختلفی که در پنجره شناور برای یک متن به دست آمده است
|
||||
|
||||
Args:
|
||||
input_classes(list[obj]): لیستی از آبجکت کلاس ها شامل عنوان کلاس و امتیاز مربوط به آن که مدل تشخیص داده است
|
||||
|
||||
Returns:
|
||||
top_class(obj): تک آبجکتی شامل عنوان و امتیاز بهترین کلاس تشخیص داده شده برای این متن
|
||||
"""
|
||||
pass
|
||||
all_classes = []
|
||||
for cclass in input_classes:
|
||||
|
@ -69,21 +115,32 @@ def mean_classes(input_classes):
|
|||
return top_n_classes
|
||||
|
||||
def get_window_classes(text):
|
||||
"""
|
||||
این متد، متن ورودی را بررسی می کند و اگر اندازه آن بیشتر از اندازه ورودی قابل قبول برای مدل بود، یک پنجره به اندازه ای که قبلا تعریف شده روی متن حرکت می دهد و برای هر حرکت، متن پنجره را کلاس بندی می کند و لیست آبجکت کلاس ها را بر می گرداند
|
||||
در صورتی که متن ورودی از اندازه مدل بزرگتر نبود، متن ورودی بدون ورود به فرایند پنجره ها کلاس بندی می شود
|
||||
|
||||
Args:
|
||||
text(str): متن ورودی که باید کلاس بندی شود
|
||||
|
||||
Returns:
|
||||
text_classes(list[obj]): لیست آبجکت ها شامل عنوان و امتیاز کلاس تشخیص داده شده برای این متن
|
||||
"""
|
||||
text_classes = []
|
||||
tokens = tokenizer(text)['input_ids'][1:-1]
|
||||
#print(len(tokens))
|
||||
|
||||
if len(tokens) > window_size:
|
||||
for i in range(0, len(tokens), step_size):#- window_size + 1
|
||||
for i in range(0, len(tokens), step_size):
|
||||
start_window_slice = tokens[0: i]
|
||||
window_slice = tokens[i: i + window_size]
|
||||
start_char = len(tokenizer.decode(start_window_slice).replace('[UNK]', ''))
|
||||
char_len = len(tokenizer.decode(window_slice).replace('[UNK]', ''))
|
||||
context_slice = text[start_char: start_char + char_len]
|
||||
tokens_len = len(tokenizer(context_slice)['input_ids'][1:-1])
|
||||
# tokens_len = len(tokenizer(context_slice)['input_ids'][1:-1])
|
||||
# print(f'i: {i},token-len: {tokens_len}', flush=True)
|
||||
results = get_class(context_slice, Top_k)
|
||||
text_classes.append(results)
|
||||
|
||||
# محاسبه بهترین کلاس ها بر اساس میانگین امتیازات کلاسهای تشخیص داده شده
|
||||
text_classes = mean_classes(text_classes)
|
||||
else:
|
||||
text_classes = get_class(text, Top_k)
|
||||
|
@ -94,7 +151,12 @@ def full_path_text_maker(full_path):
|
|||
"""
|
||||
این متد مسیر یک سکشن را می گیرد و متنی را بر اساس ترتیب بخش های آن از جزء به کل بازسازی می کند و بر می گرداند
|
||||
|
||||
full_path_text متن بازسازی شده از مسیر یک سکشن
|
||||
Args:
|
||||
full_path_text(str): متن اولیه از مسیر یک سکشن
|
||||
|
||||
Returns:
|
||||
full_path_text(str): متن بازسازی شده از مسیر یک سکشن
|
||||
|
||||
"""
|
||||
full_path_text = ""
|
||||
for i, path_item in enumerate(reversed(full_path)):
|
||||
|
@ -122,10 +184,23 @@ def single_section_classification(id, section_source):
|
|||
"best-class":{},
|
||||
"other-classes": []}
|
||||
content = section_source['content']
|
||||
# اگر نوع سکشن، عنوان یا موخره یا امضاء باشد، نیازی به فرایند کلاسبندی نیست و لیست کلاس های مربوط به این سکشن را خالی قرار می دهیم
|
||||
if content =='' or section_source['other_info']['full_path'] == 'عنوان' or section_source['other_info']['full_path'] == 'موخره' or section_source['other_info']['full_path'] == 'امضاء':
|
||||
# اگر متن سکشن خالی بود، کلاس ها را به صورت خالی برگردان
|
||||
if content =='':
|
||||
return classification_result, True, 'Classification was successful'
|
||||
|
||||
# اگر نوع سکشن، عنوان یا موخره یا امضاء باشد، نیازی به فرایند کلاسبندی نیست و لیست کلاس های مربوط به این سکشن را خالی قرار می دهیم
|
||||
filtered_keys = ['فصل','موخره','امضاء','عنوان']
|
||||
section_path = section_source['other_info']['full_path']
|
||||
if '>' in section_path:
|
||||
path_parts = section_path.split('>')
|
||||
for key in filtered_keys:
|
||||
if key in path_parts[-1]:
|
||||
return classification_result, True, 'Classification was successful'
|
||||
else:
|
||||
for key in filtered_keys:
|
||||
if key in section_path:
|
||||
return classification_result, True, 'Classification was successful'
|
||||
|
||||
qanon_title = section_source['qanon_title']
|
||||
# این متغیر ریشه سکشن اخیر تا رسیدن به قانون را مشخص می کند
|
||||
# مثلا: ماده5>تبصره یک>بند الف
|
||||
|
@ -163,6 +238,15 @@ def single_section_classification(id, section_source):
|
|||
return classification_result, True, 'Classification was successful'
|
||||
|
||||
def do_classify(sections):
|
||||
"""
|
||||
کلاسبندی مجموعه ای از سکشن های قانون به صورت یکجا در صورت نیاز
|
||||
|
||||
Args:
|
||||
sections(list[obj]): لیستی از آبجکت سکشن های قانونی که در هر آبجکت، متادیتاهای مختلف آن سکشن قرار دارد
|
||||
|
||||
Returns:
|
||||
sections(list[obj]): لیستی از آبجکت متادیتاهای سکشن های قانونی که در ورودی دریافت کرده بود که در این پردازش، متادیتای مربوط به کلاس نیز به آنها اضافه شده است
|
||||
"""
|
||||
print(f'start classification: {datetime.datetime.now()}')
|
||||
|
||||
test_counter = 1
|
||||
|
@ -190,7 +274,7 @@ def do_classify(sections):
|
|||
# qanon_title_list.append(qanon_title)
|
||||
print(f'section: {all}/{index+1}/{id}', flush=True)
|
||||
# ذخیره دیکشنری شناسه های قانون و کلاس های تخمین زده شده در فایل جیسون
|
||||
with open('./data/classification/all_sections_classes_new_140405.json', 'w', encoding='utf-8') as output_file:
|
||||
with open('./data/classification/all_sections_classes_new_1404--.json', 'w', encoding='utf-8') as output_file:
|
||||
json_data = json.dumps(new_sections_dict, indent=4, ensure_ascii=False)
|
||||
output_file.write(json_data)
|
||||
|
||||
|
@ -201,4 +285,17 @@ def do_classify(sections):
|
|||
|
||||
return sections
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
sections = get_sections()
|
||||
|
||||
# اجرای عملیات کلاس بندی
|
||||
classified_sections = do_classify(sections)
|
||||
|
||||
with open(f'classified_sections_{today}.json', 'w', encoding='utf-8') as output:
|
||||
data = json.dumps(classified_sections, ensure_ascii=False, indent=4)
|
||||
output.write(data)
|
||||
|
||||
print(f'end: {datetime.datetime.now()}')
|
||||
|
||||
print('finished ner recognization!')
|
|
@ -93,8 +93,6 @@ def find_ner_values_in_text(text, ner_values):
|
|||
'ner_score' : float(ner_score.strip()),
|
||||
#'ner_tokens' : ner_tokens,
|
||||
})
|
||||
# if law_id != 0:
|
||||
# ner_obj[len(ner_obj)-1]['ner_law_id']= law_id
|
||||
|
||||
return ner_obj
|
||||
|
||||
|
@ -214,6 +212,9 @@ def do_ner_recognize(sections):
|
|||
return sections
|
||||
|
||||
def get_sections():
|
||||
"""
|
||||
دریافت کل سکشن های قانونی در مسیر مشخص شده
|
||||
"""
|
||||
sections_path = "/home/gpu/data_11/14040423/mj_qa_section.zip"
|
||||
eh_obj = ElasticHelper()
|
||||
sections = eh_obj.iterateJsonFile(sections_path, True)
|
||||
|
@ -221,6 +222,9 @@ def get_sections():
|
|||
return sections
|
||||
|
||||
def convert_to_dict(sections):
|
||||
"""
|
||||
تبدیل لیست سکشن های قانون به دیکشنری
|
||||
"""
|
||||
sections_dict = {}
|
||||
for item in sections:
|
||||
id = item['id']
|
||||
|
@ -244,7 +248,7 @@ if __name__ == '__main__':
|
|||
|
||||
sections = do_ner_recognize(sections)
|
||||
|
||||
with open(f'./data/ner/sections_ner_{today}.json', 'w', encoding='utf-8') as output:
|
||||
with open(f'sections_ner_{today}.json', 'w', encoding='utf-8') as output:
|
||||
data = json.dumps(sections, ensure_ascii=False, indent=4)
|
||||
output.write(data)
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ from sentence_transformers import SentenceTransformer
|
|||
import json
|
||||
import datetime
|
||||
import numpy as np
|
||||
from elastic_helper import ElasticHelper
|
||||
|
||||
date = datetime.datetime.now()
|
||||
today = f'{date.year}-{date.month}-{date.day}-{date.hour}'
|
||||
|
@ -19,7 +20,32 @@ model_name = 'sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2'#89-25
|
|||
# model_name = 'HooshvareLab/bert-base-parsbert-uncased'#90-54
|
||||
model = SentenceTransformer(model_name)
|
||||
|
||||
def get_sections():
|
||||
"""
|
||||
دریافت کل سکشن های قانونی در مسیر مشخص شده
|
||||
"""
|
||||
sections_path = "/home/gpu/data_11/14040423/mj_qa_section.zip"
|
||||
eh_obj = ElasticHelper()
|
||||
sections = eh_obj.iterateJsonFile(sections_path, True)
|
||||
sections = convert_to_dict(sections)
|
||||
return sections
|
||||
|
||||
def convert_to_dict(sections):
|
||||
"""
|
||||
تبدیل لیست سکشن های قانون به دیکشنری
|
||||
"""
|
||||
sections_dict = {}
|
||||
for item in sections:
|
||||
id = item['id']
|
||||
source = item['source']
|
||||
sections_dict[id] = source
|
||||
|
||||
return sections_dict
|
||||
|
||||
def do_word_embedder(sections):
|
||||
"""
|
||||
لیستی از آبجکت سکشن های قانون را دریافت می کند و متن سکشن ها را تبدیل به بردار می کند و در نهایت لیست سکشن ها که امبدینگ هم به آنها اضافه شده را در مسیر مشخص شده در همین متد، ذخیره می کند
|
||||
"""
|
||||
for index, id in enumerate(sections):
|
||||
embeddings = single_section_embedder(sections[id]['content'])
|
||||
sections[id]['embeddings'] = embeddings.tolist()
|
||||
|
@ -50,8 +76,8 @@ def cosine_similarity(vec1, vec2):
|
|||
return dot_product / (norm_vec1 * norm_vec2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
embd1 = single_section_embedder("۲ – درصد مشارکت و سهم پرداختی کارفرما نسبت به مأخذ کسر حق بیمه به صندوقهای فعال در سطح همگانی بیمههای اجتماعی و درمانی یکسان خواهد بود.")
|
||||
embd2 = single_section_embedder("۳ – درصد مشارکت و سهم پرداختی بیمهشده نسبت به مأخذ کسر حق بیمه به صندوقهای فعال در سطح همگانی بیمههای اجتماعی و درمانی یکسان خواهد بود.")
|
||||
# embd2 = get_sentence_embeddings("تو کم گذاشتی وگرنه شکست نمی خوردی")
|
||||
similarity = cosine_similarity(embd1, embd2)
|
||||
print(f'similarity: {similarity}')
|
||||
|
||||
sections = get_sections()
|
||||
|
||||
# محاسبه امبدینگ سکشن ها و ذخیره نتایج
|
||||
do_word_embedder(sections)
|
|
@ -201,9 +201,9 @@ def do_keyword_extract(sections):
|
|||
return operation_result, sections
|
||||
|
||||
if __name__ == "__main__":
|
||||
print(f'start: {datetime.datetime.now()}')
|
||||
|
||||
sections = get_sections()
|
||||
|
||||
operation_result = do_keyword_extract(sections)
|
||||
# استخراج کلیدواژه های مربوط به متن سکشن های قانونی و ذخیره سازی
|
||||
do_keyword_extract(sections)
|
||||
|
||||
print(f'end: {datetime.datetime.now()}')
|
|
@ -5,6 +5,7 @@ import datetime
|
|||
from transformers import AutoModelForCausalLM, AutoTokenizer
|
||||
import torch
|
||||
import json
|
||||
from elastic_helper import ElasticHelper
|
||||
|
||||
date = datetime.datetime.now()
|
||||
today = f'{date.year}-{date.month}-{date.day}-{date.hour}'
|
||||
|
@ -19,6 +20,28 @@ total = 0
|
|||
|
||||
id = ''
|
||||
|
||||
def get_sections():
|
||||
"""
|
||||
دریافت کل سکشن های قانونی در مسیر مشخص شده
|
||||
"""
|
||||
sections_path = "/home/gpu/data_11/14040423/mj_qa_section.zip"
|
||||
eh_obj = ElasticHelper()
|
||||
sections = eh_obj.iterateJsonFile(sections_path, True)
|
||||
sections = convert_to_dict(sections)
|
||||
return sections
|
||||
|
||||
def convert_to_dict(sections):
|
||||
"""
|
||||
تبدیل لیست سکشن های قانون به دیکشنری
|
||||
"""
|
||||
sections_dict = {}
|
||||
for item in sections:
|
||||
id = item['id']
|
||||
source = item['source']
|
||||
sections_dict[id] = source
|
||||
|
||||
return sections_dict
|
||||
|
||||
def single_section_representation(content):
|
||||
"""
|
||||
این متد، یک متن قانونی را با جملات ساده تر بازنمایی می کند
|
||||
|
@ -100,4 +123,7 @@ def do_representation(sections):
|
|||
return operation_result, sections
|
||||
|
||||
if __name__ == "__main__":
|
||||
pass
|
||||
sections = get_sections()
|
||||
|
||||
# بازنمایی متن سکشن های قانون و ذخیره سازی
|
||||
do_representation(sections)
|
|
@ -1,6 +1,6 @@
|
|||
# اسکریپت کلاسیفیکیشن سکشنهای قانون
|
||||
|
||||
این پروژه شامل یک اسکریپت پایتون (`p1_classifier.py`) برای کلاسبندی بخشهای متنی با استفاده از یک مدل ترنسفورمر آموزشدیده است. این اسکریپت برای پیشنهاد مرتبطترین کلاسها برای هر بخش از متن طراحی شده و برای اسناد حقوقی، دستهبندی محتوا و وظایف مشابه در پردازش زبان طبیعی (NLP) کاربرد دارد.
|
||||
این فایل شامل یک اسکریپت پایتون (`p1_classifier.py`) برای کلاسبندی بخشهای متنی با استفاده از یک مدل ترنسفورمر آموزشدیده است. این اسکریپت برای پیشنهاد مرتبطترین کلاسها برای هر بخش از متن قانون طراحی شده و کاربرد دارد.
|
||||
|
||||
## پیشنیازها
|
||||
|
||||
|
@ -16,15 +16,15 @@ pip install transformers pandas
|
|||
|
||||
- اسکریپت یک مدل ترنسفورمر آموزشدیده را برای کلاسیفیکیشن متن بارگذاری میکند.
|
||||
- هر بخش از متن را پردازش میکند و در صورت طولانی بودن متن، آن را به پنجرههایی تقسیم میکند تا با اندازه ورودی مدل سازگار شود.
|
||||
- برای هر بخش، بهترین کلاسها را پیشبینی و نتایج را ذخیره میکند.
|
||||
- برای هر بخش، بهترین کلاسها را پیشبینی و نتایج را بر می گرداند.
|
||||
|
||||
## توابع اصلی
|
||||
|
||||
- `get_class(sentences, top_k=4)`: یک جمله یا متن را کلاسیفای میکند و برترین کلاسها را برمیگرداند.
|
||||
- `mean_classes(input_classes)`: نتایج کلاسبندی چند پنجره از یک متن طولانی را تجمیع میکند.
|
||||
- `get_window_classes(text)`: تقسیم متنهای طولانی به پنجره و تجمیع نتایج کلاسیفیکیشن آنها را مدیریت میکند.
|
||||
- `single_section_classification(id, section_source)`: یک بخش را کلاسبندی کرده و بهترین و سایر کلاسهای پیشنهادی را برمیگرداند.
|
||||
- `do_classify(sections)`: همه بخشها را کلاسیفای کرده و نتایج را در یک فایل JSON ذخیره میکند.
|
||||
- `get_window_classes(text)`: تقسیم متنهای طولانی به پنجره و تجمیع نتایج کلاسیفیکیشن و برگرداندن آن
|
||||
- `single_section_classification(id, section_source)`: یک متن قانونی را کلاسبندی کرده و بهترین و سایر کلاسهای پیشنهادی را برمیگرداند.
|
||||
- `do_classify(sections)`: همه بخشها را کلاسیفای کرده و نتایج را در قالب لیستی از آبجکت متادیتاهای مربوط به یک سکشن از قانون بر می گرداند.
|
||||
|
||||
## مثال استفاده
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user