Skip to content

Commit 78f3a16

Browse files
committed
ENH: Makes the Thai library only once per library loading. Improves tokenization efficiency on lists.
1 parent b7c624c commit 78f3a16

File tree

1 file changed

+76
-65
lines changed

1 file changed

+76
-65
lines changed

pythainlp/tokenize/newmm.py

Lines changed: 76 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
# -*- coding: utf-8 -*-
2+
23
'''ตัวตัดคำภาษาไทยโดยใช้หลักการ maximal matching และ TCC
34
พัฒนาโดยคุณ Korakot Chaovavanich
45
Notebook : https://colab.research.google.com/notebook#fileId=1V1Z657_5eSWPo8rLfVRwA0A5E4vkg7SI
56
'''
6-
from __future__ import absolute_import,unicode_literals
7+
from __future__ import absolute_import, unicode_literals
78
import re
89
from collections import defaultdict
910
from heapq import heappush, heappop # for priority queue
1011
from marisa_trie import Trie
11-
from pythainlp.corpus.thaiword import get_data # ดึงข้อมูลรายการคำในภาษาไทย
12+
from pythainlp.corpus.thaiword import get_data # ดึงข้อมูลรายการคำในภาษาไทย
1213

1314

1415
# ช่วยตัดพวกภาษาอังกฤษ เป็นต้น
@@ -45,83 +46,93 @@
4546
แccc์
4647
โctะ
4748
[เ-ไ]ct
48-
""".replace('c','[ก-ฮ]').replace('t', '[่-๋]?').split()
49+
""".replace('c', '[ก-ฮ]').replace('t', '[่-๋]?').split()
50+
51+
THAI_WORDS = Trie(get_data())
52+
4953

5054
def tcc(w):
51-
p = 0
52-
pat = re.compile("|".join(pat_tcc))
53-
while p<len(w):
54-
m = pat.match(w[p:])
55-
if m:
56-
n = m.span()[1]
57-
else:
58-
n = 1
59-
yield w[p:p+n]
60-
p += n
55+
p = 0
56+
pat = re.compile("|".join(pat_tcc))
57+
while p < len(w):
58+
m = pat.match(w[p:])
59+
if m:
60+
n = m.span()[1]
61+
else:
62+
n = 1
63+
yield w[p:p + n]
64+
p += n
65+
6166

6267
def tcc_pos(text):
63-
p_set = set()
64-
p = 0
65-
for w in tcc(text):
66-
p += len(w)
67-
p_set.add(p)
68-
return p_set
69-
def serialize(words_at, p, p2):
68+
p_set = set()
69+
p = 0
70+
for w in tcc(text):
71+
p += len(w)
72+
p_set.add(p)
73+
return p_set
74+
75+
76+
def serialize(words_at, p, p2):
7077
# find path ทั้งหมด แบบ depth first
7178
for w in words_at[p]:
7279
p_ = p + len(w)
73-
if p_== p2:
80+
if p_ == p2:
7481
yield [w]
7582
elif p_ < p2:
7683
for path in serialize(words_at, p_, p2):
77-
yield [w]+path
78-
def onecut(text,data=['']):
79-
if(data!=['']):
80-
trie = Trie(data)
84+
yield [w] + path
85+
86+
87+
def onecut(text, data=['']):
88+
if(data != ['']):
89+
trie = Trie(data)
8190
else:
82-
trie = Trie(get_data())
91+
trie = THAI_WORDS
8392
words_at = defaultdict(list) # main data structure
8493
allow_pos = tcc_pos(text) # ตำแหน่งที่ตัด ต้องตรงกับ tcc
85-
94+
8695
q = [0] # min-heap queue
8796
last_p = 0 # last position for yield
8897
while q[0] < len(text):
89-
p = heappop(q)
90-
91-
for w in trie.prefixes(text[p:]):
92-
p_ = p + len(w)
93-
if p_ in allow_pos: # เลือกที่สอดคล้อง tcc
94-
words_at[p].append(w)
95-
if p_ not in q:
96-
heappush(q, p_)
97-
98-
# กรณี length 1 คือ ไม่กำกวมแล้ว ส่งผลลัพธ์ก่อนนี้คืนได้
99-
if len(q)==1:
100-
paths = serialize(words_at, last_p, q[0])
101-
for w in min(paths, key=len):
102-
yield w
103-
last_p = q[0]
104-
105-
# กรณี length 0 คือ ไม่มีใน dict
106-
if len(q)==0:
107-
m = pat_eng.match(text[p:])
108-
if m: # อังกฤษ, เลข, ว่าง
109-
i = p + m.end()
110-
else: # skip น้อยที่สุด ที่เป็นไปได้
111-
for i in range(p+1, len(text)):
112-
if i in allow_pos: # ใช้ tcc ด้วย
113-
ww = trie.prefixes(text[i:])
114-
m = pat_eng.match(text[i:])
115-
if ww or m:
116-
break
117-
else:
118-
i = len(text)
119-
w = text[p:i]
120-
words_at[p].append(w)
121-
yield w
122-
last_p = i
123-
heappush(q, i)
124-
98+
p = heappop(q)
99+
100+
for w in trie.prefixes(text[p:]):
101+
p_ = p + len(w)
102+
if p_ in allow_pos: # เลือกที่สอดคล้อง tcc
103+
words_at[p].append(w)
104+
if p_ not in q:
105+
heappush(q, p_)
106+
107+
# กรณี length 1 คือ ไม่กำกวมแล้ว ส่งผลลัพธ์ก่อนนี้คืนได้
108+
if len(q) == 1:
109+
paths = serialize(words_at, last_p, q[0])
110+
for w in min(paths, key=len):
111+
yield w
112+
last_p = q[0]
113+
114+
# กรณี length 0 คือ ไม่มีใน dict
115+
if len(q) == 0:
116+
m = pat_eng.match(text[p:])
117+
if m: # อังกฤษ, เลข, ว่าง
118+
i = p + m.end()
119+
else: # skip น้อยที่สุด ที่เป็นไปได้
120+
for i in range(p + 1, len(text)):
121+
if i in allow_pos: # ใช้ tcc ด้วย
122+
ww = trie.prefixes(text[i:])
123+
m = pat_eng.match(text[i:])
124+
if ww or m:
125+
break
126+
else:
127+
i = len(text)
128+
w = text[p:i]
129+
words_at[p].append(w)
130+
yield w
131+
last_p = i
132+
heappush(q, i)
133+
125134
# ช่วยให้ไม่ต้องพิมพ์ยาวๆ
126-
def mmcut(text,data=['']):
127-
return list(onecut(text,data=data))
135+
136+
137+
def mmcut(text, data=['']):
138+
return list(onecut(text, data=data))

0 commit comments

Comments
 (0)