File size: 5,510 Bytes
6c4ffba
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
125
126
127
import json
from functools import partial
from typing import Callable, Dict
import transformers
from transformers import (
    AutoModelForTokenClassification,
    AutoTokenizer
)

from pipeline import (
    TokenClassificationPipeline
)
import pythainlp
from pprint import pprint
from itertools import chain

import gradio as gr


ner_pipeline_group = TokenClassificationPipeline(
            model=AutoModelForTokenClassification.from_pretrained(
                'airesearch/wangchanberta-base-att-spm-uncased',
                revision='finetuned@thainer-ner'
            ),
            tokenizer=AutoTokenizer.from_pretrained(
                'airesearch/wangchanberta-base-att-spm-uncased',
                revision='finetuned@thainer-ner'
            ),
            space_token='<_>',
            lowercase=True,
            group_entities=True,
            strict=False,
)

color_mapper = {
 "DATE": "#f94144",
 "EMAIL":"#f3722c",
 "LAW":"#f8961e",
 "LEN":"#f9844a",
 "LOCATION":"#f9c74f",
 "MONEY":"#ffcb77",
 "ORGANIZATION":"#f5cac3",
 "PERCENT":"#90be6d",
 "PERSON":"#bfd200",
 "PHONE":"#43aa8b",
 "TIME":"#4d908e",
 "URL":"#577590",
 "ZIP":"#90e0ef",
}


css_text = 'p{width: 700px; color: #333; border-radius: 3px; border: solid 1.5px #DDD; background-color: #FFF;\n margin: 10px;\n padding: 30px}\n'
for k,v in color_mapper.items():
    css_text += "span."+f"{k.lower()}" \
    +"{\n background-color: " \
    +f"{v}"+"50;\n color: #333;\n border-right: 4px solid " \
    +f"{v}"+";" \
    + "\n align-items: center;" \
    + "\n  margin: 0;" \
    + "\n padding: 2px 8px;" \
    + "\n border-radius: 3px;\n}\n" \
    +"span."+f"{k.lower()}"+"::after {" \
    +"\npadding: 2px 1px;" \
    +"font-size: 9.5px;" \
    +"font-weight: bold;" \
    +"font-family: Monaco;" \
    +"vertical-align: super;" \
    +"content: \"" + k.upper() + "\";" \
    +"}\n" \
    

def modifiy_segment(text, tag, start, end):
    replaced_text = text[:start] + f'<span class="{tag}">' + text[start:end] +'</span>' + text[end:]
    return replaced_text, len(f'<span class="{tag}">') + len('</span>')


def render_doc_with_label(label: Dict, doc: str):
    attribute_items = []
    for i, ne_span in enumerate(label):
        if ne_span['entity_group'] != 'O':
            attribute_name = ne_span['entity_group']
            attribute_name = attribute_name.lower()
            
            begin_char_idx = ne_span['begin_char_index']
        
            tagged_text = ne_span['word']
            end_char_idx = begin_char_idx + len(tagged_text)
        
            attribute_items.append((attribute_name, begin_char_idx, end_char_idx))
        
    attribute_items = sorted(attribute_items, key=lambda x: (x[1]))
    print(f'attribute_items: {attribute_items}')
    
    acc_n_extra_chars = 0
    modified_segment = doc
    for _selected_attribute_item in attribute_items:

        tag, start, end =  _selected_attribute_item[0],  _selected_attribute_item[1],  _selected_attribute_item[2]
        
        modified_segment, n_extra_chars = modifiy_segment(modified_segment, tag, start + acc_n_extra_chars, end + acc_n_extra_chars)
        acc_n_extra_chars += n_extra_chars
          
    return f'<style>{css_text}</style><p>{modified_segment}</p>' 

def ner_tagging(text: str):
    results = ner_pipeline_group(text)
    print(f'results:\n{results}')
    html_text =  render_doc_with_label(results, text)

    return json.dumps(results, ensure_ascii=False, indent=4), html_text


demo = gr.Interface(fn=ner_tagging,
inputs=gr.Textbox(lines=5, placeholder='Input text in Thai', label='Input text'),
examples=[
        ["ไมโครซอฟท์ได้จัดจำหน่ายบนแพลตฟอร์มไมโครซอฟท์ วินโดวส์ ในเดือนเมษายน 2020"],
        ['ชัชชาติ สิทธิพันธุ์ ผู้ว่าราชการกรุงเทพมหานคร (กทม.) คนที่ 17 เตรียมเข้ารับตำแหน่งอย่างเป็นทางการและเปิดตัวทีมงานในช่วงบ่ายวันนี้ (1 มิ.ย.) หลังรับมอบหนังสือรับรองการเป็นผู้ว่าฯ กทม. ที่สำนักงานคณะกรรมการการเลือกตั้ง (กกต.)'],
        ["สถาบันวิทยาศาสตร์ทางทะเล มหาวิทยาลัยบูรพา เปิดให้บริการมายาวนานกว่า 30 ปี ตั้งอยู่บริเวณด้านหน้า มหาวิทยาลัยบูรพา บนเนื้อที่กว่า 30 ไร่ เป็นสถานที่ท่องเที่ยว ที่จัดแสดงเพื่อให้ความรู้เกี่ยวกับวิทยาศาสตร์ทางทะเล สิ่งมีชีวิตและความเป็นอยู่ของสัตว์ทะเลชนิดต่างๆที่อาศัยอยู่ในเขตน่านน้ำของไทย"],
        
        
    ],

outputs=[gr.Textbox(), gr.HTML()])

print(f'\nINFO: transformers.__version__: {transformers.__version__}')
print(f'\nINFO: pythainlp.__version__: {pythainlp.__version__}')
demo.launch()