-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathhears_patterns.py
More file actions
128 lines (113 loc) · 6.73 KB
/
hears_patterns.py
File metadata and controls
128 lines (113 loc) · 6.73 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
118
119
120
121
122
123
124
125
126
127
128
import re
from noun_chunk_extractor import Extractor
class HearstPatterns(object):
def __init__(self, extended=False):
self.__hearst_patterns = [
('(NP_\\w+ (, )?such as (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(such NP_\\w+ (, )?as (NP_\\w+ ?(, )?(and |or )?)+)', 'first'),
('((NP_\\w+ ?(, )?)+(and |or )?other NP_\\w+)', 'last'),
('(NP_\\w+ (, )?include (NP_\\w+ ?(, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?especially (NP_\\w+ ?(, )?(and |or )?)+)', 'first'),
]
if extended:
self.__hearst_patterns.extend([
('((NP_\\w+ ?(, )?)+(and |or )?any other NP_\\w+)', 'last'),
('((NP_\\w+ ?(, )?)+(and |or )?some other NP_\\w+)', 'last'),
('((NP_\\w+ ?(, )?)+(and |or )?be a NP_\\w+)', 'last'),
('(NP_\\w+ (, )?like (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('such (NP_\\w+ (, )?as (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('((NP_\\w+ ?(, )?)+(and |or )?like other NP_\\w+)', 'last'),
('((NP_\\w+ ?(, )?)+(and |or )?one of the NP_\\w+)', 'last'),
('((NP_\\w+ ?(, )?)+(and |or )?one of these NP_\\w+)', 'last'),
('((NP_\\w+ ?(, )?)+(and |or )?one of those NP_\\w+)', 'last'),
('example of (NP_\\w+ (, )?be (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('((NP_\\w+ ?(, )?)+(and |or )?be example of NP_\\w+)', 'last'),
('(NP_\\w+ (, )?for example (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('((NP_\\w+ ?(, )?)+(and |or )?wich be call NP_\\w+)', 'last'),
('((NP_\\w+ ?(, )?)+(and |or )?which be name NP_\\w+)', 'last'),
('(NP_\\w+ (, )?mainly (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?mostly (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?notably (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?particularly (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?principally (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?in particular (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?except (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?other than (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?e.g. (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?i.e. (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('((NP_\\w+ ?(, )?)+(and |or )?a kind of NP_\\w+)', 'last'),
('((NP_\\w+ ?(, )?)+(and |or )?kind of NP_\\w+)', 'last'),
('((NP_\\w+ ?(, )?)+(and |or )?form of NP_\\w+)', 'last'),
('((NP_\\w+ ?(, )?)+(and |or )?which look like NP_\\w+)', 'last'),
('((NP_\\w+ ?(, )?)+(and |or )?which sound like NP_\\w+)', 'last'),
('(NP_\\w+ (, )?which be similar to (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?example of this be (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?type (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('((NP_\\w+ ?(, )?)+(and |or )? NP_\\w+ type)', 'last'),
('(NP_\\w+ (, )?whether (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(compare (NP_\\w+ ?(, )?)+(and |or )?with NP_\\w+)', 'last'),
('(NP_\\w+ (, )?compare to (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('(NP_\\w+ (, )?among -PRON- (NP_\\w+ ? (, )?(and |or )?)+)', 'first'),
('((NP_\\w+ ?(, )?)+(and |or )?as NP_\\w+)', 'last'),
('(NP_\\w+ (, )? (NP_\\w+ ? (, )?(and |or )?)+ for instance)', 'first'),
('((NP_\\w+ ?(, )?)+(and |or )?sort of NP_\\w+)', 'last')
])
self.__hearst_patterns = [(re.compile(k), v) for k, v in self.__hearst_patterns]
self.noun_chunk_extractor = Extractor()
# def chunk(self, rawtext):
# doc = self.__spacy_nlp(rawtext)
# chunks = []
# chunks_index = {}
# for sentence in doc.sents:
# sentence_text = sentence.lemma_
# for chunk in sentence.noun_chunks:
# chunk_arr = []
# for token in chunk:
# # Ignore Punctuation and stopword adjectives (generally quantifiers of plurals)
# if token.is_punct or token.lemma_ in self.__adj_stopwords:
# continue
# chunk_arr.append(token.lemma_)
# chunk_lemma = " ".join(chunk_arr)
# if not chunk_arr:
# continue
# if not chunk_lemma.strip():
# continue
# replacement_value = "NP_" + "_".join(chunk_arr)
# chunks_index[replacement_value] = Chunk(chunk=chunk_lemma.lower(), chunk_root=chunk.root.lemma_.lower())
# sentence_text = sentence_text.replace(chunk_lemma, replacement_value, 1)
# chunks.append(sentence_text)
# return chunks, chunks_index
"""
This is the main entry point for this code.
It takes as input the rawtext to process and returns a list of tuples (specific-term, general-term)
where each tuple represents a hypernym pair.
"""
def find_hyponyms(self, rawtext):
hyponyms = []
np_tagged_sentences, chunks_index = self.noun_chunk_extractor.chunk(rawtext)
# np_tagged_sentences, chunks_index = self.chunk(rawtext)
for sentence in np_tagged_sentences:
# two or more NPs next to each other should be merged into a single NP, it's a chunk error
for (hearst_pattern, parser) in self.__hearst_patterns:
matches = hearst_pattern.search(sentence)
if matches:
match_str = matches.group(0)
nps = [a for a in match_str.split() if a.startswith("NP_")]
if parser == "first":
general = nps[0]
specifics = nps[1:]
else:
general = nps[-1]
specifics = nps[:-1]
for i in range(len(specifics)):
try:
hyponyms.append((self.clean_hyponym_term(specifics[i]), chunks_index[general]))
except:
pass
return hyponyms
def clean_hyponym_term(self, term):
# good point to do the stemming or lemmatization
return term.replace("NP_", "").lower()
if __name__ == '__main__':
h = HearstPatterns(extended=True)
print(h.find_hyponyms("There are some beautiful animals such as dogs and cats"))