-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathudpipe_preprocessing.py
More file actions
117 lines (101 loc) · 4.32 KB
/
Copy pathudpipe_preprocessing.py
File metadata and controls
117 lines (101 loc) · 4.32 KB
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
from ufal.udpipe import Model, Pipeline
import os
import re
import sys
model = Model.load('udpipe_syntagrus.model')
process_pipeline = Pipeline(model, 'tokenize', Pipeline.DEFAULT, Pipeline.DEFAULT, 'conllu')
def num_replace(word):
newtoken = 'x' * len(word)
return newtoken
def clean_token(token, misc):
"""
:param token: токен (строка)
:param misc: содержимое поля "MISC" в CONLLU (строка)
:return: очищенный токен (строка)
"""
out_token = token.strip().replace(' ', '')
if token == 'Файл' and 'SpaceAfter=No' in misc:
return None
return out_token
def clean_lemma(lemma, pos):
"""
:param lemma: лемма (строка)
:param pos: часть речи (строка)
:return: очищенная лемма (строка)
"""
out_lemma = lemma.strip().replace(' ', '').replace('_', '').lower()
if '|' in out_lemma or out_lemma.endswith('.jpg') or out_lemma.endswith('.png'):
return None
if pos != 'PUNCT':
if out_lemma.startswith('«') or out_lemma.startswith('»'):
out_lemma = ''.join(out_lemma[1:])
if out_lemma.endswith('«') or out_lemma.endswith('»'):
out_lemma = ''.join(out_lemma[:-1])
if out_lemma.endswith('!') or out_lemma.endswith('?') or out_lemma.endswith(',') \
or out_lemma.endswith('.'):
out_lemma = ''.join(out_lemma[:-1])
return out_lemma
def process(pipeline, text='Строка', keep_pos=True, keep_punct=False):
entities = {'PROPN'}
named = False
memory = []
mem_case = None
mem_number = None
tagged_propn = []
# обрабатываем текст, получаем результат в формате conllu:
processed = pipeline.process(text)
# пропускаем строки со служебной информацией:
content = [l for l in processed.split('\n') if not l.startswith('#')]
# извлекаем из обработанного текста леммы, тэги и морфологические характеристики
tagged = [w.split('\t') for w in content if w]
for t in tagged:
if len(t) != 10:
continue
(word_id, token, lemma, pos, xpos, feats, head, deprel, deps, misc) = t
token = clean_token(token, misc)
lemma = clean_lemma(lemma, pos)
if not lemma or not token:
continue
if pos in entities:
if '|' not in feats:
tagged_propn.append('%s_%s' % (lemma, pos))
continue
morph = {el.split('=')[0]: el.split('=')[1] for el in feats.split('|')}
if 'Case' not in morph or 'Number' not in morph:
tagged_propn.append('%s_%s' % (lemma, pos))
continue
if not named:
named = True
mem_case = morph['Case']
mem_number = morph['Number']
if morph['Case'] == mem_case and morph['Number'] == mem_number:
memory.append(lemma)
if 'SpacesAfter=\\n' in misc or 'SpacesAfter=\s\\n' in misc:
named = False
past_lemma = '::'.join(memory)
memory = []
tagged_propn.append(past_lemma + '_PROPN ')
else:
named = False
past_lemma = '::'.join(memory)
memory = []
tagged_propn.append(past_lemma + '_PROPN ')
tagged_propn.append('%s_%s' % (lemma, pos))
else:
if not named:
if pos == 'NUM' and token.isdigit(): # Заменяем числа на xxxxx той же длины
lemma = num_replace(token)
tagged_propn.append('%s_%s' % (lemma, pos))
else:
named = False
past_lemma = '::'.join(memory)
memory = []
tagged_propn.append(past_lemma + '_PROPN ')
tagged_propn.append('%s_%s' % (lemma, pos))
if not keep_punct:
tagged_propn = [word for word in tagged_propn if word.split('_')[1] != 'PUNCT']
if not keep_pos:
tagged_propn = [word.split('_')[0] for word in tagged_propn]
return tagged_propn
def tag_ud(text):
return process(process_pipeline, text=text)