Commit
·
543c8b7
1
Parent(s):
b5cb1eb
Update app.py
Browse files
app.py
CHANGED
@@ -1,4 +1,5 @@
|
|
1 |
import os
|
|
|
2 |
import gradio as gr
|
3 |
import wget
|
4 |
from ftlangdetect import detect
|
@@ -28,10 +29,8 @@ kw_model = {
|
|
28 |
# os.system("python -m spacy download pt_core_news_lg")
|
29 |
|
30 |
# download stop words in Portuguese
|
31 |
-
|
32 |
-
|
33 |
-
#from nltk.corpus import stopwords
|
34 |
-
#stop_words = set(stopwords.words('portuguese'))
|
35 |
|
36 |
# Part-of-Speech Tagging for Portuguese (https://melaniewalsh.github.io/Intro-Cultural-Analytics/05-Text-Analysis/Multilingual/Portuguese/03-POS-Keywords-Portuguese.html)
|
37 |
pos_pattern='<CONJ.*>*<ADP.*>*<ADV.*>*<NUM.*>*<ADJ.*>*<N.*>+'
|
@@ -40,10 +39,64 @@ pos_pattern='<CONJ.*>*<ADP.*>*<ADV.*>*<NUM.*>*<ADJ.*>*<N.*>+'
|
|
40 |
vectorizer = KeyphraseCountVectorizer(spacy_pipeline='pt_core_news_lg', stop_words=None, pos_pattern=pos_pattern, lowercase=False)
|
41 |
|
42 |
# function principal (keywords)
|
43 |
-
def get_kw_html(
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
44 |
|
45 |
# detect lang
|
46 |
-
res = detect(text=doc, low_memory=False)
|
47 |
lang = res["lang"]
|
48 |
score = res["score"]
|
49 |
|
@@ -63,68 +116,24 @@ def get_kw_html(model_id, doc, top_n, diversity):
|
|
63 |
|
64 |
else:
|
65 |
|
66 |
-
# keywords
|
67 |
-
def get_kw(kw_model=kw_model[model_id], doc=doc, top_n=top_n, diversity=diversity):
|
68 |
-
keywords = kw_model.extract_keywords(doc,
|
69 |
-
vectorizer=vectorizer,
|
70 |
-
use_mmr=True, diversity=diversity,
|
71 |
-
top_n=top_n,
|
72 |
-
)
|
73 |
-
keywords_json = {item[0]:item[1] for item in keywords}
|
74 |
-
return keywords, keywords_json
|
75 |
-
|
76 |
-
# highlight
|
77 |
-
def get_html(keywords, doc=doc):
|
78 |
-
|
79 |
-
# ordering of lists (from longest keywords to shortest ones)
|
80 |
-
list3 = [keyword[0] for keyword in keywords]
|
81 |
-
list2 = [len(item.split()) for item in list3]
|
82 |
-
list1 = list(range(len(list2)))
|
83 |
-
list2, list1 = (list(t) for t in zip(*sorted(zip(list2, list1))))
|
84 |
-
list1 = list1[::-1]
|
85 |
-
keywords_list = [list3[idx] for idx in list1]
|
86 |
-
|
87 |
-
# converting doc to html format
|
88 |
-
html_doc = doc
|
89 |
-
for idx,keyword in enumerate(keywords_list):
|
90 |
-
if sum([True if keyword in item else False for item in keywords_list[:idx]]) == 0:
|
91 |
-
if keyword not in '<span style="color: black; background-color: yellow; padding:2px">' and keyword not in '</span>':
|
92 |
-
html_doc = html_doc.replace(keyword, '<span style="color: black; background-color: yellow; padding:2px">' + keyword + '</span>')
|
93 |
-
html_doc = '<p style="font-size:150%; line-height:120%">' + html_doc + '</p>'
|
94 |
-
|
95 |
-
return html_doc
|
96 |
-
|
97 |
-
# function to clean text of document
|
98 |
-
doc = clean(doc,
|
99 |
-
fix_unicode=True, # fix various unicode errors
|
100 |
-
to_ascii=False, # transliterate to closest ASCII representation
|
101 |
-
lower=False, # lowercase text
|
102 |
-
no_line_breaks=True, # fully strip line breaks as opposed to only normalizing them
|
103 |
-
no_urls=False, # replace all URLs with a special token
|
104 |
-
no_emails=False, # replace all email addresses with a special token
|
105 |
-
no_phone_numbers=False, # replace all phone numbers with a special token
|
106 |
-
no_numbers=False, # replace all numbers with a special token
|
107 |
-
no_digits=False, # replace all digits with a special token
|
108 |
-
no_currency_symbols=False, # replace all currency symbols with a special token
|
109 |
-
no_punct=False, # remove punctuations
|
110 |
-
replace_with_punct="", # instead of removing punctuations you may replace them
|
111 |
-
replace_with_url="<URL>",
|
112 |
-
replace_with_email="<EMAIL>",
|
113 |
-
replace_with_phone_number="<PHONE>",
|
114 |
-
replace_with_number="<NUMBER>",
|
115 |
-
replace_with_digit="0",
|
116 |
-
replace_with_currency_symbol="<CUR>",
|
117 |
-
lang="pt" # set to 'de' for German special handling
|
118 |
-
)
|
119 |
-
|
120 |
# get keywords and highlighted text
|
121 |
keywords, keywords_json = get_kw()
|
122 |
html_doc = get_html(keywords)
|
123 |
-
label = f"A palavra/frase chave com a maior probabilidade é: {keywords[0]}"
|
124 |
|
125 |
return label, keywords_json, html_doc
|
126 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
127 |
title = "Extração das key palavras/frases em português"
|
|
|
128 |
description = '<p>(17/12/2022) Forneça seu próprio documento em português e o APP vai fazer a extração das palavras/frases chave com as maiores probabilidades de similardide ao texto.\
|
129 |
<br />Segundo você, qual é o melhor modelo?</p>\
|
130 |
<p>Este aplicativo usa os modelos seguintes:\
|
@@ -134,6 +143,7 @@ description = '<p>(17/12/2022) Forneça seu próprio documento em português e o
|
|
134 |
<br />- <a href="https://github.com/TimSchopf/KeyphraseVectorizers#keyphrasevectorizers">KeyphraseVectorizers</a> para definir o vetorizador que extrai palavras/frases chave com padrões de parte do texto de um documento.\
|
135 |
<br />- <a href="https://maartengr.github.io/KeyBERT/index.html">KeyBERT</a> para calcular as similaridades entre as palavras/frases chave e o texto do documento.</p>'
|
136 |
|
|
|
137 |
doc_original = """
|
138 |
As contas de pelo menos seis jornalistas norte-americanos que cobrem tecnologia foram suspensas pelo Twitter na noite desta quinta-feira (15). Os profissionais escrevem sobre o tema para diversos veículos de comunicação dos Estados Unidos, como os jornais 'The New York Times' e 'Washington Post'.
|
139 |
|
@@ -152,8 +162,9 @@ examples = [
|
|
152 |
[doc_original.strip()],
|
153 |
]
|
154 |
|
|
|
155 |
interface_0 = gr.Interface(
|
156 |
-
fn=
|
157 |
inputs=[
|
158 |
gr.Textbox(lines=15, label="Texto do documento"),
|
159 |
gr.Slider(1, 20, value=5, label="Número das palavras/frases chave a procurar (padrão: 5)"),
|
@@ -167,7 +178,7 @@ interface_0 = gr.Interface(
|
|
167 |
)
|
168 |
|
169 |
interface_1 = gr.Interface(
|
170 |
-
fn=
|
171 |
inputs=[
|
172 |
gr.Textbox(lines=15, label="Texto do documento"),
|
173 |
gr.Slider(1, 20, value=5, label="Número das palavras/frases chave a procurar (padrão: 5)"),
|
@@ -181,7 +192,7 @@ interface_1 = gr.Interface(
|
|
181 |
)
|
182 |
|
183 |
interface_2 = gr.Interface(
|
184 |
-
fn=
|
185 |
inputs=[
|
186 |
gr.Textbox(lines=15, label="Texto do documento"),
|
187 |
gr.Slider(1, 20, value=5, label="Número das palavras/frases chave a procurar (padrão: 5)"),
|
@@ -194,6 +205,7 @@ interface_2 = gr.Interface(
|
|
194 |
]
|
195 |
)
|
196 |
|
|
|
197 |
demo = gr.Parallel(interface_0, interface_1, interface_2,
|
198 |
title=title,
|
199 |
description=description,
|
|
|
1 |
import os
|
2 |
+
import subprocess
|
3 |
import gradio as gr
|
4 |
import wget
|
5 |
from ftlangdetect import detect
|
|
|
29 |
# os.system("python -m spacy download pt_core_news_lg")
|
30 |
|
31 |
# download stop words in Portuguese
|
32 |
+
output = subprocess.run(["python", "stopwords.py"], capture_output=True, text=True)
|
33 |
+
stop_words = eval(output.stdout)
|
|
|
|
|
34 |
|
35 |
# Part-of-Speech Tagging for Portuguese (https://melaniewalsh.github.io/Intro-Cultural-Analytics/05-Text-Analysis/Multilingual/Portuguese/03-POS-Keywords-Portuguese.html)
|
36 |
pos_pattern='<CONJ.*>*<ADP.*>*<ADV.*>*<NUM.*>*<ADJ.*>*<N.*>+'
|
|
|
39 |
vectorizer = KeyphraseCountVectorizer(spacy_pipeline='pt_core_news_lg', stop_words=None, pos_pattern=pos_pattern, lowercase=False)
|
40 |
|
41 |
# function principal (keywords)
|
42 |
+
def get_kw_html(doc, top_n, diversity, model_id):
|
43 |
+
|
44 |
+
# keywords
|
45 |
+
def get_kw(kw_model=kw_model[model_id], doc=doc, top_n=top_n, diversity=diversity):
|
46 |
+
keywords = kw_model.extract_keywords(doc,
|
47 |
+
vectorizer=vectorizer,
|
48 |
+
use_mmr=True, diversity=diversity,
|
49 |
+
top_n=top_n,
|
50 |
+
)
|
51 |
+
keywords_json = {item[0]:item[1] for item in keywords}
|
52 |
+
return keywords, keywords_json
|
53 |
+
|
54 |
+
# highlight
|
55 |
+
def get_html(keywords, doc=doc):
|
56 |
+
|
57 |
+
# ordering of lists (from longest keywords to shortest ones)
|
58 |
+
list3 = [keyword[0] for keyword in keywords]
|
59 |
+
list2 = [len(item.split()) for item in list3]
|
60 |
+
list1 = list(range(len(list2)))
|
61 |
+
list2, list1 = (list(t) for t in zip(*sorted(zip(list2, list1))))
|
62 |
+
list1 = list1[::-1]
|
63 |
+
keywords_list = [list3[idx] for idx in list1]
|
64 |
+
|
65 |
+
# converting doc to html format
|
66 |
+
html_doc = doc
|
67 |
+
for idx,keyword in enumerate(keywords_list):
|
68 |
+
if sum([True if keyword in item else False for item in keywords_list[:idx]]) == 0:
|
69 |
+
if keyword not in '<span style="color: black; background-color: yellow; padding:2px">' and keyword not in '</span>':
|
70 |
+
html_doc = html_doc.replace(keyword, '<span style="color: black; background-color: yellow; padding:2px">' + keyword + '</span>')
|
71 |
+
html_doc = '<p style="font-size:150%; line-height:120%">' + html_doc + '</p>'
|
72 |
+
|
73 |
+
return html_doc
|
74 |
+
|
75 |
+
# function to clean text of document
|
76 |
+
doc = clean(doc,
|
77 |
+
fix_unicode=True, # fix various unicode errors
|
78 |
+
to_ascii=False, # transliterate to closest ASCII representation
|
79 |
+
lower=False, # lowercase text
|
80 |
+
no_line_breaks=True, # fully strip line breaks as opposed to only normalizing them
|
81 |
+
no_urls=False, # replace all URLs with a special token
|
82 |
+
no_emails=False, # replace all email addresses with a special token
|
83 |
+
no_phone_numbers=False, # replace all phone numbers with a special token
|
84 |
+
no_numbers=False, # replace all numbers with a special token
|
85 |
+
no_digits=False, # replace all digits with a special token
|
86 |
+
no_currency_symbols=False, # replace all currency symbols with a special token
|
87 |
+
no_punct=False, # remove punctuations
|
88 |
+
replace_with_punct="", # instead of removing punctuations you may replace them
|
89 |
+
replace_with_url="<URL>",
|
90 |
+
replace_with_email="<EMAIL>",
|
91 |
+
replace_with_phone_number="<PHONE>",
|
92 |
+
replace_with_number="<NUMBER>",
|
93 |
+
replace_with_digit="0",
|
94 |
+
replace_with_currency_symbol="<CUR>",
|
95 |
+
lang="pt" # set to 'de' for German special handling
|
96 |
+
)
|
97 |
|
98 |
# detect lang
|
99 |
+
res = detect(text=str(doc), low_memory=False)
|
100 |
lang = res["lang"]
|
101 |
score = res["score"]
|
102 |
|
|
|
116 |
|
117 |
else:
|
118 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
119 |
# get keywords and highlighted text
|
120 |
keywords, keywords_json = get_kw()
|
121 |
html_doc = get_html(keywords)
|
122 |
+
label = f"A palavra/frase chave com a maior probabilidade é: [ {keywords[0][0]} ]"
|
123 |
|
124 |
return label, keywords_json, html_doc
|
125 |
|
126 |
+
def get_kw_html_0(doc, top_n, diversity, model_id=0):
|
127 |
+
return get_kw_html(doc, top_n, diversity, model_id)
|
128 |
+
|
129 |
+
def get_kw_html_1(doc, top_n, diversity, model_id=1):
|
130 |
+
return get_kw_html(doc, top_n, diversity, model_id)
|
131 |
+
|
132 |
+
def get_kw_html_2(doc, top_n, diversity, model_id=2):
|
133 |
+
return get_kw_html(doc, top_n, diversity, model_id)
|
134 |
+
|
135 |
title = "Extração das key palavras/frases em português"
|
136 |
+
|
137 |
description = '<p>(17/12/2022) Forneça seu próprio documento em português e o APP vai fazer a extração das palavras/frases chave com as maiores probabilidades de similardide ao texto.\
|
138 |
<br />Segundo você, qual é o melhor modelo?</p>\
|
139 |
<p>Este aplicativo usa os modelos seguintes:\
|
|
|
143 |
<br />- <a href="https://github.com/TimSchopf/KeyphraseVectorizers#keyphrasevectorizers">KeyphraseVectorizers</a> para definir o vetorizador que extrai palavras/frases chave com padrões de parte do texto de um documento.\
|
144 |
<br />- <a href="https://maartengr.github.io/KeyBERT/index.html">KeyBERT</a> para calcular as similaridades entre as palavras/frases chave e o texto do documento.</p>'
|
145 |
|
146 |
+
# examples
|
147 |
doc_original = """
|
148 |
As contas de pelo menos seis jornalistas norte-americanos que cobrem tecnologia foram suspensas pelo Twitter na noite desta quinta-feira (15). Os profissionais escrevem sobre o tema para diversos veículos de comunicação dos Estados Unidos, como os jornais 'The New York Times' e 'Washington Post'.
|
149 |
|
|
|
162 |
[doc_original.strip()],
|
163 |
]
|
164 |
|
165 |
+
# interfaces
|
166 |
interface_0 = gr.Interface(
|
167 |
+
fn=get_kw_html_0,
|
168 |
inputs=[
|
169 |
gr.Textbox(lines=15, label="Texto do documento"),
|
170 |
gr.Slider(1, 20, value=5, label="Número das palavras/frases chave a procurar (padrão: 5)"),
|
|
|
178 |
)
|
179 |
|
180 |
interface_1 = gr.Interface(
|
181 |
+
fn=get_kw_html_1,
|
182 |
inputs=[
|
183 |
gr.Textbox(lines=15, label="Texto do documento"),
|
184 |
gr.Slider(1, 20, value=5, label="Número das palavras/frases chave a procurar (padrão: 5)"),
|
|
|
192 |
)
|
193 |
|
194 |
interface_2 = gr.Interface(
|
195 |
+
fn=get_kw_html_2,
|
196 |
inputs=[
|
197 |
gr.Textbox(lines=15, label="Texto do documento"),
|
198 |
gr.Slider(1, 20, value=5, label="Número das palavras/frases chave a procurar (padrão: 5)"),
|
|
|
205 |
]
|
206 |
)
|
207 |
|
208 |
+
# app
|
209 |
demo = gr.Parallel(interface_0, interface_1, interface_2,
|
210 |
title=title,
|
211 |
description=description,
|