Spaces:
Runtime error
Runtime error
Thao Pham
commited on
Commit
·
9f62184
1
Parent(s):
ffa15c5
Remove minimum frequency and add highlighted output in app.py
Browse files- app.py +30 -16
- model/keyword_extraction_utils.py +2 -31
- model/named_entities.py +0 -2
- pipeline.py +19 -28
- requirements.txt +1 -1
app.py
CHANGED
@@ -2,22 +2,40 @@ import gradio as gr
|
|
2 |
import torch
|
3 |
import os
|
4 |
|
|
|
5 |
from pipeline import KeywordExtractorPipeline
|
6 |
|
7 |
DIR_PATH = os.path.dirname(os.path.realpath(__file__))
|
8 |
|
9 |
|
10 |
-
def extract_keyword(title, text, top_n, ngram_low_range, ngram_high_range,
|
11 |
-
# title = None
|
12 |
-
# keyword_ls = kw_model.extract_keywords(title, text, ngram_range=(ngram_low_range, ngram_high_range), top_n=top_n,
|
13 |
-
# min_freq=min_freq, use_kmeans=use_kmeans)
|
14 |
inp = {"text": text, "title": title}
|
15 |
-
keyword_ls = kw_pipeline(inputs=inp, min_freq=
|
16 |
top_n=top_n, diversify_result=diversify_result)
|
17 |
result = ''
|
18 |
for kw, score in keyword_ls:
|
19 |
result += f'{kw}: {score}\n'
|
20 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
21 |
|
22 |
|
23 |
if gr.NO_RELOAD:
|
@@ -36,12 +54,14 @@ if __name__ == "__main__":
|
|
36 |
gr.Text(
|
37 |
label="Title",
|
38 |
lines=1,
|
39 |
-
value="
|
40 |
),
|
41 |
gr.Textbox(
|
42 |
label="Text",
|
43 |
lines=5,
|
44 |
-
value="
|
|
|
|
|
45 |
),
|
46 |
gr.Number(
|
47 |
label="Top N keywords",
|
@@ -56,18 +76,12 @@ if __name__ == "__main__":
|
|
56 |
label="Ngram high range",
|
57 |
value=3
|
58 |
),
|
59 |
-
gr.Number(
|
60 |
-
label="Ngram minimum frequency",
|
61 |
-
value=1
|
62 |
-
),
|
63 |
gr.Checkbox(
|
64 |
label="Diversify result"
|
65 |
)
|
66 |
],
|
67 |
-
|
68 |
-
|
69 |
-
label="Keywords Extracted",
|
70 |
-
)
|
71 |
)
|
72 |
|
73 |
demo.launch(share=True) # Share your demo with just 1 extra parameter 🚀
|
|
|
2 |
import torch
|
3 |
import os
|
4 |
|
5 |
+
from model.process_text import process_text_pipeline
|
6 |
from pipeline import KeywordExtractorPipeline
|
7 |
|
8 |
DIR_PATH = os.path.dirname(os.path.realpath(__file__))
|
9 |
|
10 |
|
11 |
+
def extract_keyword(title, text, top_n, ngram_low_range, ngram_high_range, diversify_result):
|
|
|
|
|
|
|
12 |
inp = {"text": text, "title": title}
|
13 |
+
keyword_ls = kw_pipeline(inputs=inp, min_freq=1, ngram_n=(ngram_low_range, ngram_high_range),
|
14 |
top_n=top_n, diversify_result=diversify_result)
|
15 |
result = ''
|
16 |
for kw, score in keyword_ls:
|
17 |
result += f'{kw}: {score}\n'
|
18 |
+
highlight_dict = get_highlighted_text(text, keyword_ls)
|
19 |
+
return result, highlight_dict
|
20 |
+
|
21 |
+
|
22 |
+
def get_highlighted_text(text, keyword_ls):
|
23 |
+
text = process_text_pipeline(text)
|
24 |
+
entities = []
|
25 |
+
for kw, score in keyword_ls:
|
26 |
+
|
27 |
+
kw = kw.replace('_', ' ')
|
28 |
+
kw_dict = {"entity": "KEY"}
|
29 |
+
start_idx = text.find(kw)
|
30 |
+
|
31 |
+
while start_idx != -1:
|
32 |
+
end_idx = start_idx + len(kw)
|
33 |
+
kw_dict["start"] = start_idx
|
34 |
+
kw_dict["end"] = end_idx
|
35 |
+
entities.append(kw_dict)
|
36 |
+
start_idx = text.find(kw, end_idx)
|
37 |
+
|
38 |
+
return {"text": text, "entities": entities}
|
39 |
|
40 |
|
41 |
if gr.NO_RELOAD:
|
|
|
54 |
gr.Text(
|
55 |
label="Title",
|
56 |
lines=1,
|
57 |
+
value="Truyền thuyết và hiện tại Thành Cổ Loa",
|
58 |
),
|
59 |
gr.Textbox(
|
60 |
label="Text",
|
61 |
lines=5,
|
62 |
+
value="""Nhắc đến Cổ Loa, người ta nghĩ ngay đến truyền thuyết về An Dương Vương được thần Kim Quy bày cho cách xây thành, về chiếc lẫy nỏ thần làm từ móng chân rùa thần và mối tình bi thương Mỵ Châu – Trọng Thủy. Đằng sau những câu chuyện thiên về tâm linh ấy, thế hệ con cháu còn khám phá được những giá trị khảo cổ to lớn của Cổ Loa.
|
63 |
+
Khu di tích Cổ Loa cách trung – tâm Hà Nội 17km thuộc huyện Đông Anh, Hà Nội, có diện tích bảo tồn gần 500ha được coi là địa chỉ văn hóa đặc biệt của thủ đô và cả nước. Cổ Loa có hàng loạt di chỉ khảo cổ học đã được phát hiện, phản ánh quá trình phát triển liên tục của dân tộc ta từ sơ khai qua các thời kỳ đồ đồng, đồ đá và đồ sắt mà đỉnh cao là văn hóa Đông Sơn, vẫn được coi là nền văn minh sông Hồng thời kỳ tiền sử của dân tộc Việt Nam.
|
64 |
+
Cổ Loa từng là kinh đô của nhà nước Âu Lạc thời kỳ An Dương Vương (thế kỷ III TCN) và của nước Đại Việt thời Ngô Quyền (thế kỷ X) mà thành Cổ Loa là một di tích minh chứng còn lại cho đến ngày nay. Thành Cổ Loa được các nhà khảo cổ học đánh giá là “tòa thành cổ nhất, quy mô lớn vào bậc nhất, cấu trúc cũng thuộc loại độc đáo nhất trong lịch sử xây dựng thành lũy của người Việt cổ”.""",
|
65 |
),
|
66 |
gr.Number(
|
67 |
label="Top N keywords",
|
|
|
76 |
label="Ngram high range",
|
77 |
value=3
|
78 |
),
|
|
|
|
|
|
|
|
|
79 |
gr.Checkbox(
|
80 |
label="Diversify result"
|
81 |
)
|
82 |
],
|
83 |
+
outputs=[gr.Textbox(label="Keywords Extracted"),
|
84 |
+
gr.HighlightedText(label="Highlight")]
|
|
|
|
|
85 |
)
|
86 |
|
87 |
demo.launch(share=True) # Share your demo with just 1 extra parameter 🚀
|
model/keyword_extraction_utils.py
CHANGED
@@ -118,7 +118,6 @@ def get_segmentised_doc(nlp, rdrsegmenter, title, doc):
|
|
118 |
|
119 |
if title is not None:
|
120 |
segmentised_doc = rdrsegmenter.word_segment(title) + rdrsegmenter.word_segment(doc)
|
121 |
-
print(segmentised_doc)
|
122 |
ne_ls = set(get_named_entities(nlp, doc))
|
123 |
|
124 |
segmentised_doc_ne = []
|
@@ -145,13 +144,6 @@ def compute_ngram_embeddings(tokenizer, phobert, ngram_list):
|
|
145 |
return ngram_embeddings
|
146 |
|
147 |
|
148 |
-
# def normalised_cosine_similarity(ngram_embedding, document_embedding):
|
149 |
-
# similarity_score = cosine_similarity(ngram_embedding, document_embedding)
|
150 |
-
# magnitude_ngram = np.linalg.norm(ngram_embedding)
|
151 |
-
# magnitude_doc = np.linalg.norm(document_embedding)
|
152 |
-
# return similarity_score / np.sqrt(magnitude_ngram * magnitude_doc)
|
153 |
-
|
154 |
-
|
155 |
def compute_ngram_similarity(ngram_list, ngram_embeddings, doc_embedding):
|
156 |
ngram_similarity_dict = {}
|
157 |
|
@@ -211,7 +203,7 @@ def compute_filtered_text(annotator, title, text):
|
|
211 |
if title is not None:
|
212 |
annotated = annotator.annotate_text(title + '. ' + text)
|
213 |
filtered_sentences = []
|
214 |
-
keep_tags = ['N', 'Np', 'V']
|
215 |
for key in annotated.keys():
|
216 |
sent = ' '.join([dict_['wordForm'] for dict_ in annotated[key] if dict_['posTag'] in keep_tags])
|
217 |
filtered_sentences.append(sent)
|
@@ -220,43 +212,22 @@ def compute_filtered_text(annotator, title, text):
|
|
220 |
|
221 |
def get_candidate_ngrams(segmentised_doc, filtered_segmentised_doc, ngram_n, stopwords_ls):
|
222 |
# get actual ngrams
|
223 |
-
# segmentised_doc = get_segmentised_doc(nlp, annotator, title, text)
|
224 |
actual_ngram_list = compute_ngram_list(segmentised_doc, ngram_n, stopwords_ls, subsentences=True)
|
225 |
|
226 |
# get filtered ngrams
|
227 |
-
# filtered_segmentised_doc = compute_filtered_text(annotator, title, text)
|
228 |
filtered_ngram_list = compute_ngram_list(filtered_segmentised_doc, ngram_n, stopwords_ls,
|
229 |
subsentences=False)
|
230 |
|
231 |
-
# get
|
232 |
candidate_ngram = [ngram for ngram in filtered_ngram_list if ngram in actual_ngram_list]
|
233 |
return candidate_ngram
|
234 |
|
235 |
|
236 |
-
def limit_minimum_frequency(doc_segmentised, ngram_list, min_freq=1):
|
237 |
-
ngram_dict_freq = {}
|
238 |
-
for ngram in ngram_list:
|
239 |
-
ngram_n = len(ngram.split())
|
240 |
-
count = 0
|
241 |
-
for sentence in doc_segmentised:
|
242 |
-
sent = sentence.split()
|
243 |
-
for i in range(len(sent) - ngram_n + 1):
|
244 |
-
pair = ' '.join(sent[i:i + ngram_n])
|
245 |
-
if pair == ngram:
|
246 |
-
count += 1
|
247 |
-
if count >= min_freq:
|
248 |
-
ngram_dict_freq[ngram] = count
|
249 |
-
|
250 |
-
return ngram_dict_freq
|
251 |
-
|
252 |
-
|
253 |
def remove_overlapping_ngrams(ngram_list):
|
254 |
to_remove = set()
|
255 |
for ngram1 in ngram_list:
|
256 |
for ngram2 in ngram_list:
|
257 |
if len(ngram1.split()) > len(ngram2.split()) and (ngram1.startswith(ngram2) or ngram1.endswith(ngram2)):
|
258 |
-
# print(ngram1, ngram2)
|
259 |
-
# print()
|
260 |
to_remove.add(ngram2)
|
261 |
|
262 |
for kw in to_remove:
|
|
|
118 |
|
119 |
if title is not None:
|
120 |
segmentised_doc = rdrsegmenter.word_segment(title) + rdrsegmenter.word_segment(doc)
|
|
|
121 |
ne_ls = set(get_named_entities(nlp, doc))
|
122 |
|
123 |
segmentised_doc_ne = []
|
|
|
144 |
return ngram_embeddings
|
145 |
|
146 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
147 |
def compute_ngram_similarity(ngram_list, ngram_embeddings, doc_embedding):
|
148 |
ngram_similarity_dict = {}
|
149 |
|
|
|
203 |
if title is not None:
|
204 |
annotated = annotator.annotate_text(title + '. ' + text)
|
205 |
filtered_sentences = []
|
206 |
+
keep_tags = ['N', 'Np', 'V', 'Nc']
|
207 |
for key in annotated.keys():
|
208 |
sent = ' '.join([dict_['wordForm'] for dict_ in annotated[key] if dict_['posTag'] in keep_tags])
|
209 |
filtered_sentences.append(sent)
|
|
|
212 |
|
213 |
def get_candidate_ngrams(segmentised_doc, filtered_segmentised_doc, ngram_n, stopwords_ls):
|
214 |
# get actual ngrams
|
|
|
215 |
actual_ngram_list = compute_ngram_list(segmentised_doc, ngram_n, stopwords_ls, subsentences=True)
|
216 |
|
217 |
# get filtered ngrams
|
|
|
218 |
filtered_ngram_list = compute_ngram_list(filtered_segmentised_doc, ngram_n, stopwords_ls,
|
219 |
subsentences=False)
|
220 |
|
221 |
+
# get candidate ngrams
|
222 |
candidate_ngram = [ngram for ngram in filtered_ngram_list if ngram in actual_ngram_list]
|
223 |
return candidate_ngram
|
224 |
|
225 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
226 |
def remove_overlapping_ngrams(ngram_list):
|
227 |
to_remove = set()
|
228 |
for ngram1 in ngram_list:
|
229 |
for ngram2 in ngram_list:
|
230 |
if len(ngram1.split()) > len(ngram2.split()) and (ngram1.startswith(ngram2) or ngram1.endswith(ngram2)):
|
|
|
|
|
231 |
to_remove.add(ngram2)
|
232 |
|
233 |
for kw in to_remove:
|
model/named_entities.py
CHANGED
@@ -32,8 +32,6 @@ def get_named_entities(nlp, doc):
|
|
32 |
if len(sent_ner_result) > 0:
|
33 |
ner_lists += get_ner_phrases(sent_ner_result)
|
34 |
|
35 |
-
# print(ner_lists)
|
36 |
-
|
37 |
ner_list_non_dup = []
|
38 |
for (entity, ner_type) in ner_lists:
|
39 |
if entity not in ner_list_non_dup and ner_type.startswith('I'):
|
|
|
32 |
if len(sent_ner_result) > 0:
|
33 |
ner_lists += get_ner_phrases(sent_ner_result)
|
34 |
|
|
|
|
|
35 |
ner_list_non_dup = []
|
36 |
for (entity, ner_type) in ner_lists:
|
37 |
if entity not in ner_list_non_dup and ner_type.startswith('I'):
|
pipeline.py
CHANGED
@@ -13,19 +13,13 @@ class KeywordExtractorPipeline(Pipeline):
|
|
13 |
super().__init__(model, **kwargs)
|
14 |
self.annotator = py_vncorenlp.VnCoreNLP(annotators=["wseg", "pos"],
|
15 |
save_dir=f'{dir_path}/pretrained-models/vncorenlp')
|
16 |
-
|
17 |
print("Loading PhoBERT tokenizer")
|
18 |
self.phobert_tokenizer = AutoTokenizer.from_pretrained("vinai/phobert-base-v2")
|
19 |
-
|
20 |
-
# use absolute path because torch is cached
|
21 |
-
# self.phobert = torch.load(f'{dir_path}/pretrained-models/phobert.pt')
|
22 |
-
# self.phobert.eval()
|
23 |
self.phobert = model
|
24 |
|
25 |
print("Loading NER tokenizer")
|
26 |
ner_tokenizer = AutoTokenizer.from_pretrained("NlpHUST/ner-vietnamese-electra-base")
|
27 |
-
# ner_model = torch.load(f'{dir_path}/pretrained-models/ner-vietnamese-electra-base.pt')
|
28 |
-
# ner_model.eval()
|
29 |
self.ner_pipeline = pipeline("ner", model=ner_model, tokenizer=ner_tokenizer)
|
30 |
|
31 |
stopwords_file_path = f'{dir_path}/vietnamese-stopwords-dash.txt'
|
@@ -41,7 +35,7 @@ class KeywordExtractorPipeline(Pipeline):
|
|
41 |
if possible_preprocess_kwarg in kwargs:
|
42 |
preprocess_kwargs[possible_preprocess_kwarg] = kwargs[possible_preprocess_kwarg]
|
43 |
|
44 |
-
for possible_forward_kwarg in ["ngram_n"
|
45 |
if possible_forward_kwarg in kwargs:
|
46 |
forward_kwargs[possible_forward_kwarg] = kwargs[possible_forward_kwarg]
|
47 |
|
@@ -49,8 +43,6 @@ class KeywordExtractorPipeline(Pipeline):
|
|
49 |
if possible_postprocess_kwarg in kwargs:
|
50 |
postprocess_kwargs[possible_postprocess_kwarg] = kwargs[possible_postprocess_kwarg]
|
51 |
|
52 |
-
# print(forward_kwargs)
|
53 |
-
# print(postprocess_kwargs)
|
54 |
return preprocess_kwargs, forward_kwargs, postprocess_kwargs
|
55 |
|
56 |
def preprocess(self, inputs):
|
@@ -58,24 +50,22 @@ class KeywordExtractorPipeline(Pipeline):
|
|
58 |
if inputs['title']:
|
59 |
title = process_text_pipeline(inputs['title'])
|
60 |
text = process_text_pipeline(inputs['text'])
|
61 |
-
return {"text": text, "title": title}
|
62 |
|
63 |
-
def _forward(self, model_inputs, ngram_n
|
64 |
text = model_inputs['text']
|
65 |
title = model_inputs['title']
|
66 |
-
# ngram_n = model_inputs['ngram_n']
|
67 |
-
# min_freq = model_inputs['min_freq']
|
68 |
|
69 |
# Getting segmentised document
|
70 |
ne_ls, doc_segmentised = get_segmentised_doc(self.ner_pipeline, self.annotator, title, text)
|
71 |
-
print(ne_ls)
|
72 |
filtered_doc_segmentised = compute_filtered_text(self.annotator, title, text)
|
73 |
|
74 |
doc_embedding = get_doc_embeddings(filtered_doc_segmentised, self.phobert_tokenizer, self.phobert,
|
75 |
self.stopwords)
|
76 |
|
77 |
-
ngram_list = self.generate_ngram_list(doc_segmentised, filtered_doc_segmentised, ne_ls, ngram_n
|
78 |
-
print(
|
|
|
79 |
|
80 |
ngram_embeddings = compute_ngram_embeddings(self.phobert_tokenizer, self.phobert, ngram_list)
|
81 |
|
@@ -94,7 +84,7 @@ class KeywordExtractorPipeline(Pipeline):
|
|
94 |
return diversify_result_kmeans(ngram_result, ngram_embeddings, top_n=top_n)
|
95 |
return non_diversified
|
96 |
|
97 |
-
def generate_ngram_list(self, doc_segmentised, filtered_doc_segmentised, ne_ls, ngram_n
|
98 |
ngram_low, ngram_high = ngram_n
|
99 |
|
100 |
# Adding ngram
|
@@ -103,14 +93,13 @@ class KeywordExtractorPipeline(Pipeline):
|
|
103 |
ngram_list.update(get_candidate_ngrams(doc_segmentised, filtered_doc_segmentised, n, self.stopwords))
|
104 |
|
105 |
# Adding named entities ngram list
|
106 |
-
|
|
|
107 |
|
108 |
# Removing overlapping ngrams
|
109 |
ngram_list = remove_overlapping_ngrams(ngram_list)
|
110 |
|
111 |
-
|
112 |
-
ngram_list = limit_minimum_frequency(doc_segmentised, ngram_list, min_freq=min_freq)
|
113 |
-
return ngram_list.keys()
|
114 |
|
115 |
def extract_keywords(self, doc_embedding, ngram_list, ngram_embeddings):
|
116 |
ngram_result = compute_ngram_similarity(ngram_list, ngram_embeddings, doc_embedding)
|
@@ -119,17 +108,19 @@ class KeywordExtractorPipeline(Pipeline):
|
|
119 |
|
120 |
|
121 |
if __name__ == "__main__":
|
122 |
-
|
123 |
phobert = torch.load(f'{dir_path}/pretrained-models/phobert.pt')
|
124 |
phobert.eval()
|
125 |
ner_model = torch.load(f'{dir_path}/pretrained-models/ner-vietnamese-electra-base.pt')
|
126 |
ner_model.eval()
|
127 |
kw_pipeline = KeywordExtractorPipeline(phobert, ner_model)
|
128 |
|
129 |
-
|
130 |
-
|
131 |
-
|
|
|
|
|
|
|
132 |
|
133 |
-
inp = {"text": text,"title":
|
134 |
-
kws = kw_pipeline(inputs=inp,
|
135 |
print(kws)
|
|
|
13 |
super().__init__(model, **kwargs)
|
14 |
self.annotator = py_vncorenlp.VnCoreNLP(annotators=["wseg", "pos"],
|
15 |
save_dir=f'{dir_path}/pretrained-models/vncorenlp')
|
16 |
+
|
17 |
print("Loading PhoBERT tokenizer")
|
18 |
self.phobert_tokenizer = AutoTokenizer.from_pretrained("vinai/phobert-base-v2")
|
|
|
|
|
|
|
|
|
19 |
self.phobert = model
|
20 |
|
21 |
print("Loading NER tokenizer")
|
22 |
ner_tokenizer = AutoTokenizer.from_pretrained("NlpHUST/ner-vietnamese-electra-base")
|
|
|
|
|
23 |
self.ner_pipeline = pipeline("ner", model=ner_model, tokenizer=ner_tokenizer)
|
24 |
|
25 |
stopwords_file_path = f'{dir_path}/vietnamese-stopwords-dash.txt'
|
|
|
35 |
if possible_preprocess_kwarg in kwargs:
|
36 |
preprocess_kwargs[possible_preprocess_kwarg] = kwargs[possible_preprocess_kwarg]
|
37 |
|
38 |
+
for possible_forward_kwarg in ["ngram_n"]:
|
39 |
if possible_forward_kwarg in kwargs:
|
40 |
forward_kwargs[possible_forward_kwarg] = kwargs[possible_forward_kwarg]
|
41 |
|
|
|
43 |
if possible_postprocess_kwarg in kwargs:
|
44 |
postprocess_kwargs[possible_postprocess_kwarg] = kwargs[possible_postprocess_kwarg]
|
45 |
|
|
|
|
|
46 |
return preprocess_kwargs, forward_kwargs, postprocess_kwargs
|
47 |
|
48 |
def preprocess(self, inputs):
|
|
|
50 |
if inputs['title']:
|
51 |
title = process_text_pipeline(inputs['title'])
|
52 |
text = process_text_pipeline(inputs['text'])
|
53 |
+
return {"text": text, "title": title}
|
54 |
|
55 |
+
def _forward(self, model_inputs, ngram_n):
|
56 |
text = model_inputs['text']
|
57 |
title = model_inputs['title']
|
|
|
|
|
58 |
|
59 |
# Getting segmentised document
|
60 |
ne_ls, doc_segmentised = get_segmentised_doc(self.ner_pipeline, self.annotator, title, text)
|
|
|
61 |
filtered_doc_segmentised = compute_filtered_text(self.annotator, title, text)
|
62 |
|
63 |
doc_embedding = get_doc_embeddings(filtered_doc_segmentised, self.phobert_tokenizer, self.phobert,
|
64 |
self.stopwords)
|
65 |
|
66 |
+
ngram_list = self.generate_ngram_list(doc_segmentised, filtered_doc_segmentised, ne_ls, ngram_n)
|
67 |
+
# print("Final ngram list")
|
68 |
+
# print(sorted(ngram_list))
|
69 |
|
70 |
ngram_embeddings = compute_ngram_embeddings(self.phobert_tokenizer, self.phobert, ngram_list)
|
71 |
|
|
|
84 |
return diversify_result_kmeans(ngram_result, ngram_embeddings, top_n=top_n)
|
85 |
return non_diversified
|
86 |
|
87 |
+
def generate_ngram_list(self, doc_segmentised, filtered_doc_segmentised, ne_ls, ngram_n):
|
88 |
ngram_low, ngram_high = ngram_n
|
89 |
|
90 |
# Adding ngram
|
|
|
93 |
ngram_list.update(get_candidate_ngrams(doc_segmentised, filtered_doc_segmentised, n, self.stopwords))
|
94 |
|
95 |
# Adding named entities ngram list
|
96 |
+
ne_ls_segmented = [self.annotator.word_segment(ne)[0] for ne in ne_ls]
|
97 |
+
ngram_list.update(ne_ls_segmented)
|
98 |
|
99 |
# Removing overlapping ngrams
|
100 |
ngram_list = remove_overlapping_ngrams(ngram_list)
|
101 |
|
102 |
+
return ngram_list
|
|
|
|
|
103 |
|
104 |
def extract_keywords(self, doc_embedding, ngram_list, ngram_embeddings):
|
105 |
ngram_result = compute_ngram_similarity(ngram_list, ngram_embeddings, doc_embedding)
|
|
|
108 |
|
109 |
|
110 |
if __name__ == "__main__":
|
|
|
111 |
phobert = torch.load(f'{dir_path}/pretrained-models/phobert.pt')
|
112 |
phobert.eval()
|
113 |
ner_model = torch.load(f'{dir_path}/pretrained-models/ner-vietnamese-electra-base.pt')
|
114 |
ner_model.eval()
|
115 |
kw_pipeline = KeywordExtractorPipeline(phobert, ner_model)
|
116 |
|
117 |
+
title = "Truyền thuyết và hiện tại Thành Cổ Loa"
|
118 |
+
text = """
|
119 |
+
Nhắc đến Cổ Loa, người ta nghĩ ngay đến truyền thuyết về An Dương Vương được thần Kim Quy bày cho cách xây thành, về chiếc lẫy nỏ thần làm từ móng chân rùa thần và mối tình bi thương Mỵ Châu – Trọng Thủy. Đằng sau những câu chuyện thiên về tâm linh ấy, thế hệ con cháu còn khám phá được những giá trị khảo cổ to lớn của Cổ Loa.
|
120 |
+
Khu di tích Cổ Loa cách trung – tâm Hà Nội 17km thuộc huyện Đông Anh, Hà Nội, có diện tích bảo tồn gần 500ha được coi là địa chỉ văn hóa đặc biệt của thủ đô và cả nước. Cổ Loa có hàng loạt di chỉ khảo cổ học đã được phát hiện, phản ánh quá trình phát triển liên tục của dân tộc ta từ sơ khai qua các thời kỳ đồ đồng, đồ đá và đồ sắt mà đỉnh cao là văn hóa Đông Sơn, vẫn được coi là nền văn minh sông Hồng thời kỳ tiền sử của dân tộc Việt Nam.
|
121 |
+
Cổ Loa từng là kinh đô của nhà nước Âu Lạc thời kỳ An Dương Vương (thế kỷ III TCN) và của nước Đại Việt thời Ngô Quyền (thế kỷ X) mà thành Cổ Loa là một di tích minh chứng còn lại cho đến ngày nay. Thành Cổ Loa được các nhà khảo cổ học đánh giá là “tòa thành cổ nhất, quy mô lớn vào bậc nhất, cấu trúc cũng thuộc loại độc đáo nhất trong lịch sử xây dựng thành lũy của người Việt cổ”.
|
122 |
+
"""
|
123 |
|
124 |
+
inp = {"text": text, "title": title}
|
125 |
+
kws = kw_pipeline(inputs=inp, ngram_n=(1, 3), top_n=5, diversify_result=False)
|
126 |
print(kws)
|
requirements.txt
CHANGED
@@ -4,4 +4,4 @@ gradio
|
|
4 |
scikit-learn
|
5 |
numpy
|
6 |
underthesea
|
7 |
-
py_vncorenlp
|
|
|
4 |
scikit-learn
|
5 |
numpy
|
6 |
underthesea
|
7 |
+
py_vncorenlp
|