Skip to content

Commit 1105bd5

Browse files
committed
Merge branch 'dev' of https://github.com/wannaphongcom/pythainlp into dev
2 parents a422ac2 + c3bac7c commit 1105bd5

File tree

1 file changed

+72
-61
lines changed

1 file changed

+72
-61
lines changed

pythainlp/tokenize/newmm.py

Lines changed: 72 additions & 61 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):
5155
p = 0
5256
pat = re.compile("|".join(pat_tcc))
53-
while p<len(w):
57+
while p < len(w):
5458
m = pat.match(w[p:])
5559
if m:
5660
n = m.span()[1]
5761
else:
5862
n = 1
59-
yield w[p:p+n]
63+
yield w[p:p + n]
6064
p += n
6165

66+
6267
def tcc_pos(text):
6368
p_set = set()
6469
p = 0
6570
for w in tcc(text):
6671
p += len(w)
6772
p_set.add(p)
6873
return p_set
69-
def serialize(words_at, p, p2):
70-
# find path ทั้งหมด แบบ depth first
71-
for w in words_at[p]:
72-
p_ = p + len(w)
73-
if p_== p2:
74-
yield [w]
75-
elif p_ < p2:
76-
for path in serialize(words_at, p_, p2):
77-
yield [w]+path
78-
def onecut(text,data=['']):
79-
if(data!=['']):
80-
trie = Trie(data)
81-
else:
82-
trie = Trie(get_data())
83-
words_at = defaultdict(list) # main data structure
84-
allow_pos = tcc_pos(text) # ตำแหน่งที่ตัด ต้องตรงกับ tcc
85-
86-
q = [0] # min-heap queue
87-
last_p = 0 # last position for yield
88-
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_)
9774

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):
75+
76+
def serialize(words_at, p, p2):
77+
# find path ทั้งหมด แบบ depth first
78+
for w in words_at[p]:
79+
p_ = p + len(w)
80+
if p_ == p2:
81+
yield [w]
82+
elif p_ < p2:
83+
for path in serialize(words_at, p_, p2):
84+
yield [w] + path
85+
86+
87+
def onecut(text, data=['']):
88+
if(data != ['']):
89+
trie = Trie(data)
90+
else:
91+
trie = THAI_WORDS
92+
words_at = defaultdict(list) # main data structure
93+
allow_pos = tcc_pos(text) # ตำแหน่งที่ตัด ต้องตรงกับ tcc
94+
95+
q = [0] # min-heap queue
96+
last_p = 0 # last position for yield
97+
while q[0] < len(text):
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)
102130
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-
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)