PyThaiNLP Get Startedï
Code examples for basic functions in PyThaiNLP https://github.com/PyThaiNLP/pythainlp
[1]:
# # pip install required modules
# # uncomment if running from colab
# # see list of modules in `requirements` and `extras`
# # in https://github.com/PyThaiNLP/pythainlp/blob/dev/setup.py
#!pip install -q python-crfsuite
#!pip install -q torch
#!pip install -q pythainlp
#!pip install -q epitran
Import PyThaiNLPï
[2]:
import pythainlp
pythainlp.__version__
[2]:
'2.2.1'
Thai Charactersï
PyThaiNLP provides some ready-to-use Thai character set (e.g. Thai consonants, vowels, tonemarks, symbols) as a string for convenience. There are also few utility functions to test if a string is in Thai or not.
[3]:
pythainlp.thai_characters
[3]:
'āļāļāļāļāļ
āļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļ āļĄāļĒāļĢāļĨāļ§āļĻāļĐāļŠāļŦāļŽāļāļŪāļĪāļĶāļ°āļąāļēāļģāļīāļĩāļķāļ·āļļāļđāđāđāđāđāđāđ
āđāđāđāđāđāđāļŊāļšāđāđāđāđāđāđāđāđāđāđāđāđāđāđāđāđāđāļŋ'
[4]:
len(pythainlp.thai_characters)
[4]:
88
[5]:
pythainlp.thai_consonants
[5]:
'āļāļāļāļāļ
āļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļāļ āļĄāļĒāļĢāļĨāļ§āļĻāļĐāļŠāļŦāļŽāļāļŪ'
[6]:
len(pythainlp.thai_consonants)
[6]:
44
[7]:
"āđ" in pythainlp.thai_digits # check if Thai digit "4" is in the character set
[7]:
True
Checking if a string contains Thai character or not, or how manyï
[8]:
import pythainlp.util
pythainlp.util.isthai("āļ")
[8]:
True
[9]:
pythainlp.util.isthai("(āļ.āļ.)")
[9]:
False
[10]:
pythainlp.util.isthai("(āļ.āļ.)", ignore_chars=".()")
[10]:
True
counthai()
returns proportion of Thai characters in the text. It will ignore non-alphabets by default.
[11]:
pythainlp.util.countthai("āļ§āļąāļāļāļēāļāļīāļāļĒāđāļāļĩāđ 24 āļĄāļĩāļāļēāļāļĄ 2562")
[11]:
100.0
You can specify characters to be ignored, using ignore_chars=
parameter.
[12]:
pythainlp.util.countthai("āļ§āļąāļāļāļēāļāļīāļāļĒāđāļāļĩāđ 24 āļĄāļĩāļāļēāļāļĄ 2562", ignore_chars="")
[12]:
67.85714285714286
Collationï
Sorting according to Thai dictionary.
[13]:
from pythainlp.util import collate
thai_words = ["āļāđāļāļ", "āļāļĢāļ°āļāļēāļĐ", "āļāļĢāļĢāđāļāļĢ", "āđāļāđ", "āļāđāļēāđāļŦāļĄ"]
collate(thai_words)
[13]:
['āļāļĢāļĢāđāļāļĢ', 'āļāļĢāļ°āļāļēāļĐ', 'āđāļāđ', 'āļāđāļāļ', 'āļāđāļēāđāļŦāļĄ']
[14]:
collate(thai_words, reverse=True)
[14]:
['āļāđāļēāđāļŦāļĄ', 'āļāđāļāļ', 'āđāļāđ', 'āļāļĢāļ°āļāļēāļĐ', 'āļāļĢāļĢāđāļāļĢ']
Date/Time Format and Spelloutï
Date/Time Formatï
Get Thai day and month names with Thai Buddhist Era (B.E.). Use formatting directives similar to datetime.strftime()
.
[15]:
import datetime
from pythainlp.util import thai_strftime
fmt = "%Aāļāļĩāđ %-d %B āļ.āļĻ. %Y āđāļ§āļĨāļē %H:%M āļ. (%a %d-%b-%y)"
date = datetime.datetime(1976, 10, 6, 1, 40)
thai_strftime(date, fmt)
[15]:
'āļ§āļąāļāļāļļāļāļāļĩāđ 6 āļāļļāļĨāļēāļāļĄ āļ.āļĻ. 2519 āđāļ§āļĨāļē 01:40 āļ. (āļ 06-āļ.āļ.-19)'
From version 2.2, these modifiers can be applied right before the main directive:
(minus) Do not pad a numeric result string (also available in version 2.1)
_ (underscore) Pad a numeric result string with spaces
0 (zero) Pad a number result string with zeros
^ Convert alphabetic characters in result string to upper case
# Swap the case of the result string
O (letter o) Use the localeâs alternative numeric symbols (Thai digit)
[16]:
thai_strftime(date, "%d %b %y")
[16]:
'06 āļ.āļ. 19'
[17]:
thai_strftime(date, "%d %b %Y")
[17]:
'06 āļ.āļ. 2519'
Time Spelloutï
Note: ``thai_time()`` will be renamed to ``time_to_thaiword()`` in version 2.2.
[18]:
from pythainlp.util import thai_time
thai_time("00:14:29")
[18]:
'āļĻāļđāļāļĒāđāļāļēāļŽāļīāļāļēāļŠāļīāļāļŠāļĩāđāļāļēāļāļĩāļĒāļĩāđāļŠāļīāļāđāļāđāļēāļ§āļīāļāļēāļāļĩ'
The way to spellout can be chosen, using fmt
parameter. It can be 24h
, 6h
, or m6h
. Try one by yourself.
[19]:
thai_time("00:14:29", fmt="6h")
[19]:
'āđāļāļĩāđāļĒāļāļāļ·āļāļŠāļīāļāļŠāļĩāđāļāļēāļāļĩāļĒāļĩāđāļŠāļīāļāđāļāđāļēāļ§āļīāļāļēāļāļĩ'
Precision of spellout can be chosen as well. Using precision
parameter. It can be m
for minute-level, s
for second-level, or None
for only read the non-zero value.
[20]:
thai_time("00:14:29", precision="m")
[20]:
'āļĻāļđāļāļĒāđāļāļēāļŽāļīāļāļēāļŠāļīāļāļŠāļĩāđāļāļēāļāļĩ'
[21]:
print(thai_time("8:17:00", fmt="6h"))
print(thai_time("8:17:00", fmt="m6h", precision="s"))
print(thai_time("18:30:01", fmt="m6h", precision="m"))
print(thai_time("13:30:01", fmt="6h", precision="m"))
āļŠāļāļāđāļĄāļāđāļāđāļēāļŠāļīāļāđāļāđāļāļāļēāļāļĩ
āđāļāļāđāļĄāļāļŠāļīāļāđāļāđāļāļāļēāļāļĩāļĻāļđāļāļĒāđāļ§āļīāļāļēāļāļĩ
āļŦāļāđāļĄāļāļāļĢāļķāđāļ
āļāđāļēāļĒāđāļĄāļāļāļĢāļķāđāļ
We can also pass datetime
and time
objects to thai_time()
.
[22]:
import datetime
time = datetime.time(13, 14, 15)
thai_time(time)
[22]:
'āļŠāļīāļāļŠāļēāļĄāļāļēāļŽāļīāļāļēāļŠāļīāļāļŠāļĩāđāļāļēāļāļĩāļŠāļīāļāļŦāđāļēāļ§āļīāļāļēāļāļĩ'
[23]:
time = datetime.datetime(10, 11, 12, 13, 14, 15)
thai_time(time, fmt="6h", precision="m")
[23]:
'āļāđāļēāļĒāđāļĄāļāļŠāļīāļāļŠāļĩāđāļāļēāļāļĩ'
Tokenization and Segmentationï
At sentence, word, and sub-word levels.
Sentenceï
Default sentence tokenizer is âcrfcutâ. Tokenization engine can be chosen ussing engine=
parameter.
[24]:
from pythainlp import sent_tokenize
text = ("āļāļĢāļ°āļĢāļēāļāļāļąāļāļāļąāļāļīāļāļĢāļĢāļĄāļāļđāļāļāļēāļĢāļāļāļāļĢāļāļāđāļāđāļāļāļīāļāļŠāļĒāļēāļĄāļāļąāđāļ§āļāļĢāļēāļ§ āļāļļāļāļāļĻāļąāļāļĢāļēāļ āđāđāđāđ "
"āđāļāđāļāļĢāļąāļāļāļĢāļĢāļĄāļāļđāļāļāļāļąāļāļāļąāđāļ§āļāļĢāļēāļ§ āļāļķāđāļāļāļ·āļāļ§āđāļēāđāļāđāļāļĢāļąāļāļāļĢāļĢāļĄāļāļđāļāļāļāļąāļāđāļĢāļāđāļŦāđāļāļĢāļēāļāļāļēāļāļēāļāļąāļāļĢāļŠāļĒāļēāļĄ "
"āļāļĢāļ°āļāļēāļĻāđāļāđāđāļĄāļ·āđāļāļ§āļąāļāļāļĩāđ 27 āļĄāļīāļāļļāļāļēāļĒāļ āļ.āļĻ. 2475 "
"āđāļāļĒāđāļāđāļāļāļĨāļāļ§āļāļŦāļĨāļąāļāļāļēāļĢāļāļāļīāļ§āļąāļāļīāđāļĄāļ·āđāļāļ§āļąāļāļāļĩāđ 24 āļĄāļīāļāļļāļāļēāļĒāļ āļ.āļĻ. 2475 āđāļāļĒāļāļāļ°āļĢāļēāļĐāļāļĢ")
print("default (crfcut):")
print(sent_tokenize(text))
print("\nwhitespace+newline:")
print(sent_tokenize(text, engine="whitespace+newline"))
default (crfcut):
['āļāļĢāļ°āļĢāļēāļāļāļąāļāļāļąāļāļīāļāļĢāļĢāļĄāļāļđāļāļāļēāļĢāļāļāļāļĢāļāļāđāļāđāļāļāļīāļāļŠāļĒāļēāļĄāļāļąāđāļ§āļāļĢāļēāļ§ āļāļļāļāļāļĻāļąāļāļĢāļēāļ āđāđāđāđ āđāļāđāļāļĢāļąāļāļāļĢāļĢāļĄāļāļđāļāļāļāļąāļāļāļąāđāļ§āļāļĢāļēāļ§ ', 'āļāļķāđāļāļāļ·āļāļ§āđāļēāđāļāđāļāļĢāļąāļāļāļĢāļĢāļĄāļāļđāļāļāļāļąāļāđāļĢāļāđāļŦāđāļāļĢāļēāļāļāļēāļāļēāļāļąāļāļĢāļŠāļĒāļēāļĄ ', 'āļāļĢāļ°āļāļēāļĻāđāļāđāđāļĄāļ·āđāļāļ§āļąāļāļāļĩāđ 27 āļĄāļīāļāļļāļāļēāļĒāļ āļ.āļĻ. 2475 ', 'āđāļāļĒāđāļāđāļāļāļĨāļāļ§āļāļŦāļĨāļąāļāļāļēāļĢāļāļāļīāļ§āļąāļāļīāđāļĄāļ·āđāļāļ§āļąāļāļāļĩāđ 24 āļĄāļīāļāļļāļāļēāļĒāļ āļ.āļĻ. 2475 āđāļāļĒāļāļāļ°āļĢāļēāļĐāļāļĢ']
whitespace+newline:
['āļāļĢāļ°āļĢāļēāļāļāļąāļāļāļąāļāļīāļāļĢāļĢāļĄāļāļđāļāļāļēāļĢāļāļāļāļĢāļāļāđāļāđāļāļāļīāļāļŠāļĒāļēāļĄāļāļąāđāļ§āļāļĢāļēāļ§', 'āļāļļāļāļāļĻāļąāļāļĢāļēāļ', 'āđāđāđāđ', 'āđāļāđāļāļĢāļąāļāļāļĢāļĢāļĄāļāļđāļāļāļāļąāļāļāļąāđāļ§āļāļĢāļēāļ§', 'āļāļķāđāļāļāļ·āļāļ§āđāļēāđāļāđāļāļĢāļąāļāļāļĢāļĢāļĄāļāļđāļāļāļāļąāļāđāļĢāļāđāļŦāđāļāļĢāļēāļāļāļēāļāļēāļāļąāļāļĢāļŠāļĒāļēāļĄ', 'āļāļĢāļ°āļāļēāļĻāđāļāđāđāļĄāļ·āđāļāļ§āļąāļāļāļĩāđ', '27', 'āļĄāļīāļāļļāļāļēāļĒāļ', 'āļ.āļĻ.', '2475', 'āđāļāļĒāđāļāđāļāļāļĨāļāļ§āļāļŦāļĨāļąāļāļāļēāļĢāļāļāļīāļ§āļąāļāļīāđāļĄāļ·āđāļāļ§āļąāļāļāļĩāđ', '24', 'āļĄāļīāļāļļāļāļēāļĒāļ', 'āļ.āļĻ.', '2475', 'āđāļāļĒāļāļāļ°āļĢāļēāļĐāļāļĢ']
Wordï
Default word tokenizer (ânewmmâ) use maximum matching algorithm.
[25]:
from pythainlp import word_tokenize
text = "āļāđāļāļ°āļĢāļđāđāļāļ§āļēāļĄāļāļąāđāļ§āļĢāđāļēāļĒāļāļĩāđāļāļģāđāļ§āđ āđāļĨāļ°āļāļāļāļ°āđāļĄāđāļĒāļāļĄāđāļŦāđāļāļģāļāļēāļāļāļŦāļĨāļąāļāļāļ "
print("default (newmm):")
print(word_tokenize(text))
print("\nnewmm and keep_whitespace=False:")
print(word_tokenize(text, keep_whitespace=False))
default (newmm):
['āļāđ', 'āļāļ°', 'āļĢāļđāđāļāļ§āļēāļĄ', 'āļāļąāđāļ§āļĢāđāļēāļĒ', 'āļāļĩāđ', 'āļāļģ', 'āđāļ§āđ', ' ', 'āđāļĨāļ°', 'āļāļāļāļ°', 'āđāļĄāđ', 'āļĒāļāļĄāđāļŦāđ', 'āļāļģāļāļēāļāļāļŦāļĨāļąāļāļāļ', ' ']
newmm and keep_whitespace=False:
['āļāđ', 'āļāļ°', 'āļĢāļđāđāļāļ§āļēāļĄ', 'āļāļąāđāļ§āļĢāđāļēāļĒ', 'āļāļĩāđ', 'āļāļģ', 'āđāļ§āđ', 'āđāļĨāļ°', 'āļāļāļāļ°', 'āđāļĄāđ', 'āļĒāļāļĄāđāļŦāđ', 'āļāļģāļāļēāļāļāļŦāļĨāļąāļāļāļ']
Other algorithm can be chosen. We can also create a tokenizer with a custom dictionary.
[3]:
from pythainlp import word_tokenize, Tokenizer
text = "āļāļāļŦāļĄāļēāļĒāđāļĢāļāļāļēāļāļāļāļąāļāļāļĢāļąāļāļāļĢāļļāļāđāļŦāļĄāđāļāļĢāļ°āļāļēāļĻāđāļāđāđāļĨāđāļ§"
print("newmm :", word_tokenize(text)) # default engine is "newmm"
print("longest:", word_tokenize(text, engine="longest"))
words = ["āđāļĢāļāļāļēāļ"]
custom_tokenizer = Tokenizer(words)
print("newmm (custom dictionary):", custom_tokenizer.word_tokenize(text))
newmm : ['āļāļāļŦāļĄāļēāļĒāđāļĢāļāļāļēāļ', 'āļāļāļąāļ', 'āļāļĢāļąāļāļāļĢāļļāļ', 'āđāļŦāļĄāđ', 'āļāļĢāļ°āļāļēāļĻ', 'āđāļāđāđāļĨāđāļ§']
longest: ['āļāļāļŦāļĄāļēāļĒāđāļĢāļāļāļēāļ', 'āļāļāļąāļ', 'āļāļĢāļąāļāļāļĢāļļāļ', 'āđāļŦāļĄāđ', 'āļāļĢāļ°āļāļēāļĻāđāļāđ', 'āđāļĨāđāļ§']
newmm (custom dictionary): ['āļāļāļŦāļĄāļēāļĒ', 'āđāļĢāļāļāļēāļ', 'āļāļāļąāļāļāļĢāļąāļāļāļĢāļļāļāđāļŦāļĄāđāļāļĢāļ°āļāļēāļĻāđāļāđāđāļĨāđāļ§']
Default word tokenizer use a word list from pythainlp.corpus.common.thai_words()
. We can get that list, add/remove words, and create new tokenizer from the modified list.
[4]:
from pythainlp.corpus.common import thai_words
from pythainlp import Tokenizer
text = "āļāļīāļĒāļēāļĒāļ§āļīāļāļĒāļēāļĻāļēāļŠāļāļĢāđāļāļāļāđāļāđāļāļ āļāļŠāļīāļĄāļāļ"
print("default dictionary:", word_tokenize(text))
words = set(thai_words()) # thai_words() returns frozenset
words.add("āđāļāđāļāļ") # Isaac
words.add("āļāļŠāļīāļĄāļāļ") # Asimov
custom_tokenizer = Tokenizer(words)
print("custom dictionary :", custom_tokenizer.word_tokenize(text))
default dictionary: ['āļāļīāļĒāļēāļĒ', 'āļ§āļīāļāļĒāļēāļĻāļēāļŠāļāļĢāđ', 'āļāļāļ', 'āđāļāđāļāļ', ' ', 'āļāļŠāļī', 'āļĄāļ', 'āļ']
custom dictionary : ['āļāļīāļĒāļēāļĒ', 'āļ§āļīāļāļĒāļēāļĻāļēāļŠāļāļĢāđ', 'āļāļāļ', 'āđāļāđāļāļ', ' ', 'āļāļŠāļīāļĄāļāļ']
We can also, alternatively, create a dictionary trie, using pythainlp.util.Trie()
function, and pass it to a default tokenizer.
[5]:
from pythainlp.corpus.common import thai_words
from pythainlp.util import Trie
text = "ILO87 āļ§āđāļēāļāđāļ§āļĒāđāļŠāļĢāļĩāļ āļēāļāđāļāļāļēāļĢāļŠāļĄāļēāļāļĄāđāļĨāļ°āļāļēāļĢāļāļļāđāļĄāļāļĢāļāļāļŠāļīāļāļāļīāđāļāļāļēāļĢāļĢāļ§āļĄāļāļąāļ§ ILO98 āļ§āđāļēāļāđāļ§āļĒāļŠāļīāļāļāļīāđāļāļāļēāļĢāļĢāļ§āļĄāļāļąāļ§āđāļĨāļ°āļāļēāļĢāļĢāđāļ§āļĄāđāļāļĢāļāļēāļāđāļāļĢāļāļ"
print("default dictionary:", word_tokenize(text))
new_words = {"ILO87", "ILO98", "āļāļēāļĢāļĢāđāļ§āļĄāđāļāļĢāļāļēāļāđāļāļĢāļāļ", "āļŠāļīāļāļāļīāđāļāļāļēāļĢāļĢāļ§āļĄāļāļąāļ§", "āđāļŠāļĢāļĩāļ āļēāļāđāļāļāļēāļĢāļŠāļĄāļēāļāļĄ", "āđāļĢāļāļāļēāļāļŠāļąāļĄāļāļąāļāļāđ"}
words = new_words.union(thai_words())
custom_dictionary_trie = Trie(words)
print("custom dictionary :", word_tokenize(text, custom_dict=custom_dictionary_trie))
default dictionary: ['ILO', '87', ' ', 'āļ§āđāļēāļāđāļ§āļĒ', 'āđāļŠāļĢāļĩāļ āļēāļ', 'āđāļ', 'āļāļēāļĢāļŠāļĄāļēāļāļĄ', 'āđāļĨāļ°', 'āļāļēāļĢ', 'āļāļļāđāļĄāļāļĢāļāļ', 'āļŠāļīāļāļāļī', 'āđāļ', 'āļāļēāļĢ', 'āļĢāļ§āļĄāļāļąāļ§', ' ', 'ILO', '98', ' ', 'āļ§āđāļēāļāđāļ§āļĒ', 'āļŠāļīāļāļāļī', 'āđāļ', 'āļāļēāļĢ', 'āļĢāļ§āļĄāļāļąāļ§', 'āđāļĨāļ°', 'āļāļēāļĢ', 'āļĢāđāļ§āļĄ', 'āđāļāļĢāļāļē', 'āļāđāļāļĢāļāļ']
custom dictionary : ['ILO87', ' ', 'āļ§āđāļēāļāđāļ§āļĒ', 'āđāļŠāļĢāļĩāļ āļēāļāđāļāļāļēāļĢāļŠāļĄāļēāļāļĄ', 'āđāļĨāļ°', 'āļāļēāļĢ', 'āļāļļāđāļĄāļāļĢāļāļ', 'āļŠāļīāļāļāļīāđāļāļāļēāļĢāļĢāļ§āļĄāļāļąāļ§', ' ', 'ILO98', ' ', 'āļ§āđāļēāļāđāļ§āļĒ', 'āļŠāļīāļāļāļīāđāļāļāļēāļĢāļĢāļ§āļĄāļāļąāļ§', 'āđāļĨāļ°', 'āļāļēāļĢāļĢāđāļ§āļĄāđāļāļĢāļāļēāļāđāļāļĢāļāļ']
Testing different tokenization engines
[29]:
speedtest_text = """
āļāļĢāļāļĢāļāļ 14 āļāļĩ āļāļēāļāđāļ āđāļāđāļēāļ§āļąāļāļāļąāđāļ 25 āļ.āļ. 2547 āļāļđāđāļāļļāļĄāļāļļāļĄāļāļēāļĒāļāļ§āđāļē 1,370 āļāļ
āļāļđāļāđāļĒāļāļāļķāđāļāļĢāļāļĒāļĩāđāļāđāļĄāļāļĩ 22 āļŦāļĢāļ·āļ 24 āļāļąāļ āļāļāļāļāđāļāļāļāļąāļāļāļąāļāļĨāļ° 4-5 āļāļąāđāļ āđāļāļīāļāļāļēāļāļāļēāļāļŠāļāļēāļāļĩāļāļģāļĢāļ§āļāļāļēāļāđāļ āđāļāđāļāļĨ 150 āļāļīāđāļĨāđāļĄāļāļĢ
āđāļāļāļķāļāļāđāļēāļĒāļāļīāļāļāļĒāļļāļāļāļāļĢāļīāļŦāļēāļĢ āđāļāđāđāļ§āļĨāļēāļāļ§āđāļē 6 āļāļąāđāļ§āđāļĄāļ / āđāļāļāļĩāļāļāļāļĩāļāļĩāđāļāļēāļāļīāļāđāļāļāļĢāđāļāļāļĢāļąāļ āļāļāļĩāļāļāļĨāļāļāļĩāđāļāļēāļĢāļāļĢāļ°āļāļĩāļāļĢāļ°āļāļāļĄāļĒāļāļĄāļāļ§āļēāļĄ
āļāļĢāļ°āļāļĢāļ§āļāļāļĨāļēāđāļŦāļĄāļāđāļēāļĒāļāđāļēāļŠāļīāļāđāļŦāļĄāļāļāđāļāļāļĢāļ§āļĄ 42 āļĨāđāļēāļāļāļēāļāđāļŦāđāļāļąāļāļāļēāļāļīāļāļđāđāđāļŠāļĩāļĒāļŦāļēāļĒ 79 āļĢāļēāļĒ
āļāļīāļāļŦāļĩāļāđāļĨāļ°āļāļąāļāļāļ°āđāļāļāđāļŠāļĢāđāļāđāļĨāđāļ§ āļāļĩāđāļŦāļāđāļ§āļĒāđāļĨāļ·āļāļāļāļąāđāļāļāļĩāđ 32 āđāļāļ 13 āđāļāļ§āļāļŦāļąāļ§āļŦāļĄāļēāļ āđāļāļāļāļēāļāļāļ°āļāļī āļāļĢāļļāļāđāļāļāļĄāļŦāļēāļāļāļĢ
āļāļđāđāļŠāļĄāļąāļāļĢ āļŠ.āļŠ. āđāļĨāļ°āļāļąāļ§āđāļāļāļāļĢāļĢāļāļāļēāļĢāđāļĄāļ·āļāļāļāļēāļāļŦāļĨāļēāļĒāļāļĢāļĢāļāļāđāļēāļāļĄāļēāđāļāđāļēāļŠāļąāļāđāļāļāļāļēāļĢāļāļąāļāļāļ°āđāļāļāļāļĒāđāļēāļāđāļāļĨāđāļāļīāļ āđāļāļĒ
āļāļīāļāļīāļ āļąāļŠāļĢāđ āđāļāļāļīāđāļāļāļēāļāļąāļĒāļāļąāļāļāđ āļāļēāļāļāļĢāļĢāļāļāļĨāļąāļāļāļĢāļ°āļāļēāļĢāļąāļ āđāļĨāļ°āļāļĢāļīāļĐāļāđ āļ§āļąāļāļĢāļŠāļīāļāļāļļ āļāļēāļāļāļĢāļĢāļāļāļĢāļ°āļāļēāļāļīāļāļąāļāļĒāđāđāļāđāļāļ°āđāļāļ
96 āļāļ°āđāļāļāđāļāđāļēāļāļąāļ
āđāļāđāļēāļ§āļąāļāļāļēāļāļīāļāļĒāđāļāļĩāđ 21 āđāļĄāļĐāļēāļĒāļ 2019 āļāļķāđāļāđāļāđāļāļ§āļąāļāļāļĩāļŠāđāļāļāļĢāđ āļ§āļąāļāļŠāļģāļāļąāļāļāļāļāļāļēāļ§āļāļĢāļīāļŠāļāđ
āđāļāļīāļāđāļŦāļāļļāļĢāļ°āđāļāļīāļāļāđāļāđāļāļ·āđāļāļāđāļāđāļāļŠāļāđāļāļĢāļīāļŠāļāđāđāļĨāļ°āđāļĢāļāđāļĢāļĄāļāļĒāđāļēāļāļāđāļāļĒ 7 āđāļŦāđāļāđāļāļāļĢāļ°āđāļāļĻāļĻāļĢāļĩāļĨāļąāļāļāļē
āļĄāļĩāļāļđāđāđāļŠāļĩāļĒāļāļĩāļ§āļīāļāđāļĨāđāļ§āļāļĒāđāļēāļāļāđāļāļĒ 156 āļāļ āđāļĨāļ°āļāļēāļāđāļāđāļāļŦāļĨāļēāļĒāļĢāđāļāļĒāļāļ āļĒāļąāļāđāļĄāđāļĄāļĩāļāđāļāļĄāļđāļĨāļ§āđāļēāļāļđāđāļāđāļāđāļŦāļāļļāļĄāļēāļāļēāļāļāđāļēāļĒāđāļ
āļāļĩāļāļāļģāļŦāļāļāļāļąāļāļāļēāļĢāļāļĢāļ°āļāļļāļĄāļāđāļāļĢāļīāđāļĢāļīāđāļĄāļŠāļēāļĒāđāļāļāđāļĨāļ°āđāļŠāđāļāļāļēāļāđāļāļāđāļ§āļāļāļĨāļēāļĒāļŠāļąāļāļāļēāļŦāđāļāļĩāđ āļāļąāļāļāļīāđāļāļĒāļ·āļāļĒāļąāļāļ§āđāļē
āļāļ āļīāļĄāļŦāļēāđāļāļĢāļāļāļēāļĢāđāļāļ·āđāļāļĄāđāļĨāļāļāļāļāļāļĩāļāđāļĄāđāđāļāđāđāļāļĢāļ·āđāļāļāļĄāļ·āļāđāļāđāļāļīāļāļāļīāļāļĨ āđāļāđāļĒāļīāļāļāļĩāļĢāļąāļāļāļąāļāļāđāļāļ§āļīāļāļēāļĢāļāđ āđāļāđāļ āļāļĢāļ°āđāļāđāļāļāļąāļāļāļąāļāļŦāļāļĩāđāļŠāļīāļ
āđāļĨāļ°āļāļ§āļēāļĄāđāļĄāđāđāļāļĢāđāļāđāļŠ āļĢāļąāļāļāļēāļĨāļāļąāļāļāļīāđāļāļāļāļāļ§āđāļē āđāļ§āļāļĩāļāļĢāļ°āļāļļāļĄ Belt and Road Forum āđāļāļāđāļ§āļāļ§āļąāļāļāļĩāđ 25-27 āđāļĄāļĐāļēāļĒāļ
āļāļ·āļāđāļāđāļāļāļēāļāļāļēāļĢāļāļđāļāļāļĩāđāļŠāļģāļāļąāļāļāļĩāđāļŠāļļāļāļāļāļāļāļĩāļāđāļāļāļĩ 2019
"""
[30]:
# Speed test: Calling "longest" engine through word_tokenize wrapper
%time tokens = word_tokenize(speedtest_text, engine="longest")
CPU times: user 253 ms, sys: 2.27 ms, total: 256 ms
Wall time: 255 ms
[31]:
# Speed test: Calling "newmm" engine through word_tokenize wrapper
%time tokens = word_tokenize(speedtest_text, engine="newmm")
CPU times: user 3.4 ms, sys: 60 Âĩs, total: 3.46 ms
Wall time: 3.47 ms
[32]:
# Speed test: Calling "newmm" engine through word_tokenize wrapper
%time tokens = word_tokenize(speedtest_text, engine="newmm-safe")
CPU times: user 4.08 ms, sys: 88 Âĩs, total: 4.16 ms
Wall time: 4.15 ms
[33]:
#!pip install attacut
# Speed test: Calling "attacut" engine through word_tokenize wrapper
%time tokens = word_tokenize(speedtest_text, engine="attacut")
CPU times: user 833 ms, sys: 174 ms, total: 1.01 s
Wall time: 576 ms
Get all possible segmentations
[34]:
from pythainlp.tokenize.multi_cut import find_all_segment, mmcut, segment
find_all_segment("āļĄāļĩāļāļ§āļēāļĄāđāļāđāļāđāļāđāļāđāļāļĒāđāļēāļāđāļĢāļāđāļēāļ")
[34]:
['āļĄāļĩ|āļāļ§āļēāļĄ|āđāļāđāļ|āđāļ|āđāļāđ|āļāļĒāđāļēāļ|āđāļĢ|āļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄ|āđāļāđāļāđāļ|āđāļāđ|āļāļĒāđāļēāļ|āđāļĢ|āļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄ|āđāļāđāļāđāļāđāļāđ|āļāļĒāđāļēāļ|āđāļĢ|āļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄāđāļāđāļāđāļ|āđāļāđ|āļāļĒāđāļēāļ|āđāļĢ|āļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄāđāļāđāļāđāļāđāļāđ|āļāļĒāđāļēāļ|āđāļĢ|āļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄ|āđāļāđāļ|āđāļ|āđāļāđ|āļāļĒāđāļēāļāđāļĢ|āļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄ|āđāļāđāļāđāļ|āđāļāđ|āļāļĒāđāļēāļāđāļĢ|āļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄ|āđāļāđāļāđāļāđāļāđ|āļāļĒāđāļēāļāđāļĢ|āļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄāđāļāđāļāđāļ|āđāļāđ|āļāļĒāđāļēāļāđāļĢ|āļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄāđāļāđāļāđāļāđāļāđ|āļāļĒāđāļēāļāđāļĢ|āļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄ|āđāļāđāļ|āđāļ|āđāļāđ|āļāļĒāđāļēāļāđāļĢāļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄ|āđāļāđāļāđāļ|āđāļāđ|āļāļĒāđāļēāļāđāļĢāļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄ|āđāļāđāļāđāļāđāļāđ|āļāļĒāđāļēāļāđāļĢāļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄāđāļāđāļāđāļ|āđāļāđ|āļāļĒāđāļēāļāđāļĢāļāđāļēāļ|',
'āļĄāļĩ|āļāļ§āļēāļĄāđāļāđāļāđāļāđāļāđ|āļāļĒāđāļēāļāđāļĢāļāđāļēāļ|']
Subword, syllable, and Thai Character Cluster (TCC)ï
Tokenization can also be done at subword level, either syllable or Thai Character Cluster (TCC).
Syllable segmentation is using
`ssg
<https://github.com/ponrawee/ssg>`__, a CRF syllable segmenter for Thai by Ponrawee Prasertsom.TCC is smaller than syllable. For information about TCC, see Character Cluster Based Thai Information Retrieval (Theeramunkong et al. 2004).
Subword tokenizationï
Default subword tokenization engine is tcc
, which will use Thai Character Cluster (TCC) as a subword unit.
[35]:
from pythainlp import subword_tokenize
subword_tokenize("āļāļĢāļ°āđāļāļĻāđāļāļĒ") # default subword unit is TCC
[35]:
['āļ', 'āļĢāļ°', 'āđāļ', 'āļĻ', 'āđāļ', 'āļĒ']
Syllable tokenizationï
Default syllable tokenization engine is dict
, which will use newmm
word tokenization engine with a custom dictionary contains known syllables in Thai language.
[36]:
from pythainlp.tokenize import syllable_tokenize
text = "āļāļąāļāļāļļāļĨāđāļĨāļēāļ° āļāļĩāļāļāļĄāļđāļāļ āļŠāļĄāļāļāļāļ§āļĄāļĢāļļāļāđāļĢāļ"
syllable_tokenize(text) # default engine is "dict"
[36]:
['āļāļąāļ',
'āļāļļāļĨ',
'āđāļĨāļēāļ°',
' ',
'āļāļĩ',
'āļāļ',
'āļĄāļđ',
'āļāļ',
' ',
'āļŠāļĄāļāļ',
'āļāļ§āļĄ',
'āļĢāļļāļ',
'āđāļĢāļ']
External `ssg
<https://github.com/ponrawee/ssg>`__ engine call be called. Note that ssg
engine ommitted whitespaces in the output tokens.
[37]:
syllable_tokenize(text, engine="ssg") # use "ssg" for syllable
[37]:
['āļāļąāļ', 'āļāļļāļĨ', 'āđāļĨāļēāļ°', ' āļāļĩ', 'āļāļ', 'āļĄāļđ', 'āļāļ ', 'āļŠāļĄāļāļ', 'āļāļ§āļĄ', 'āļĢāļļāļ', 'āđāļĢāļ']
Low-level subword operationsï
These low-level TCC operations can be useful for some pre-processing tasks. Like checking if itâs ok to cut a string at a certain point or to find typos.
[38]:
from pythainlp.tokenize import tcc
tcc.segment("āļāļĢāļ°āđāļāļĻāđāļāļĒ")
[38]:
['āļ', 'āļĢāļ°', 'āđāļ', 'āļĻ', 'āđāļ', 'āļĒ']
[39]:
tcc.tcc_pos("āļāļĢāļ°āđāļāļĻāđāļāļĒ") # return positions
[39]:
{1, 3, 5, 6, 8, 9}
[40]:
for ch in tcc.tcc("āļāļĢāļ°āđāļāļĻāđāļāļĒ"): # TCC generator
print(ch, end='-')
āļ-āļĢāļ°-āđāļ-āļĻ-āđāļ-āļĒ-
Transliterationï
There are two types of transliteration here: romanization and transliteration.
Romanization will render Thai words in the Latin alphabet using the Royal Thai General System of Transcription (RTGS).
Two engines are supported here: a simple
royin
engine (default) and a more accuratethai2rom
engine.
Transliteration here, in PyThaiNLP context, means the sound representation of a string.
[41]:
from pythainlp.transliterate import romanize
romanize("āđāļĄāļ§") # output: 'maeo'
[41]:
'maeo'
[42]:
romanize("āļ āļēāļāļĒāļāļāļĢāđ") # output: 'phapn' (*obviously wrong)
[42]:
'phapn'
[43]:
from pythainlp.transliterate import transliterate
transliterate("āđāļĄāļ§") # output: 'mÉËw'
Update Corpus...
Corpus: thai-g2p
- Already up to date.
[43]:
'm ÉË w ˧'
[44]:
transliterate("āļ āļēāļāļĒāļāļāļĢāđ") # output: 'pĘ°aËpjanot'
[44]:
'pĘ° aË pĖ ËĨËĐ . pĘ° a ËĶËĨ . j o n ˧'
Normalizationï
normalize()
removes zero-width spaces (ZWSP and ZWNJ), duplicated spaces, repeating vowels, and dangling characters. It also reorder vowels and tone marks during the process of removing repeating vowels.
[45]:
from pythainlp.util import normalize
normalize("āđāđāļāļĨāļ") == "āđāļāļĨāļ" # āđ āđ āļ āļĨ āļ vs āđ āļ āļĨ āļ
[45]:
True
The string below contains a non-standard order of Thai characters, Sara Aa (following vowel) + Mai Ek (upper tone mark). normalize()
will reorder it to Mai Ek + Sara Aa.
[46]:
text = "āđāļāļēāđ"
normalize(text)
[46]:
'āđāļāđāļē'
This can be useful for string matching, including tokenization.
[47]:
from pythainlp import word_tokenize
text = "āđāļāđāļāļ§āļąāļāļāđāļĩ āļāļĢāđāļļāļāļāđāļĩāļāđāđāļāļēāđ"
print("tokenize immediately:")
print(word_tokenize(text))
print("\nnormalize, then tokenize:")
print(word_tokenize(normalize(text)))
tokenize immediately:
['āđāļāđāļ', 'āļ§āļąāļ', 'āļāđāļĩ', ' ', 'āļāļĢāđāļļāļāļāđāļĩ', 'āļāđ', 'āđāļāļē', 'āđ']
normalize, then tokenize:
['āđāļāđāļ', 'āļ§āļąāļāļāļĩāđ', ' ', 'āļāļĢāļļāđāļāļāļĩāđ', 'āļāđ', 'āđāļāđāļē']
The string below contains repeating vowels (multiple Sara A in a row) normalize() will keep only one of them. It can be use to reduce variations in spellings, useful for classification task.
[48]:
normalize("āđāļāļ°āļ°āļ°")
[48]:
'āđāļāļ°'
Internally, normalize()
is just a series of function calls like this:
text = remove_zw(text)
text = remove_dup_spaces(text)
text = remove_repeat_vowels(text)
text = remove_dangling(text)
If you donât like the behavior of default normalize()
, you can call those functions shown above, also remove_tonemark()
and reorder_vowels()
, individually from pythainlp.util
, to customize your own normalization.
Digit conversionï
Thai text sometimes use Thai digits. This can reduce performance for classification and searching. PyThaiNP provides few utility functions to deal with this.
[49]:
from pythainlp.util import arabic_digit_to_thai_digit, thai_digit_to_arabic_digit, digit_to_text
text = "āļāļļāļāđāļāļīāļāļāļĩāđāļĒāļļāđāļĢāļāđāļĢāļĩāļĒāļ 112 āđāđāđ"
arabic_digit_to_thai_digit(text)
[49]:
'āļāļļāļāđāļāļīāļāļāļĩāđāļĒāļļāđāļĢāļāđāļĢāļĩāļĒāļ āđāđāđ āđāđāđ'
[50]:
thai_digit_to_arabic_digit(text)
[50]:
'āļāļļāļāđāļāļīāļāļāļĩāđāļĒāļļāđāļĢāļāđāļĢāļĩāļĒāļ 112 112'
[51]:
digit_to_text(text)
[51]:
'āļāļļāļāđāļāļīāļāļāļĩāđāļĒāļļāđāļĢāļāđāļĢāļĩāļĒāļ āļŦāļāļķāđāļāļŦāļāļķāđāļāļŠāļāļ āļŦāļāļķāđāļāļŦāļāļķāđāļāļŠāļāļ'
Soundexï
âSoundex is a phonetic algorithm for indexing names by sound.â (Wikipedia). PyThaiNLP provides three kinds of Thai soundex.
[52]:
from pythainlp.soundex import lk82, metasound, udom83
# check equivalence
print(lk82("āļĢāļ") == lk82("āļĢāļ"))
print(udom83("āļ§āļĢāļĢ") == udom83("āļ§āļąāļ"))
print(metasound("āļāļ") == metasound("āļāļ "))
True
True
True
[53]:
texts = ["āļāļđāļĢāļāļ°", "āļāļđāļĢāļāļāļēāļĢ", "āļĄāļąāļ", "āļĄāļąāļ", "āļĄāļĢāļĢāļ", "āļĨāļąāļ", "āļĢāļąāļ", "āļĢāļąāļāļĐāđ", ""]
for text in texts:
print(
"{} - lk82: {} - udom83: {} - metasound: {}".format(
text, lk82(text), udom83(text), metasound(text)
)
)
āļāļđāļĢāļāļ° - lk82: āļE400 - udom83: āļ930000 - metasound: āļ550
āļāļđāļĢāļāļāļēāļĢ - lk82: āļE419 - udom83: āļ931900 - metasound: āļ551
āļĄāļąāļ - lk82: āļĄ1000 - udom83: āļĄ100000 - metasound: āļĄ100
āļĄāļąāļ - lk82: āļĄ1000 - udom83: āļĄ100000 - metasound: āļĄ100
āļĄāļĢāļĢāļ - lk82: āļĄ1000 - udom83: āļĄ310000 - metasound: āļĄ551
āļĨāļąāļ - lk82: āļĢ1000 - udom83: āļĢ100000 - metasound: āļĨ100
āļĢāļąāļ - lk82: āļĢ1000 - udom83: āļĢ100000 - metasound: āļĢ100
āļĢāļąāļāļĐāđ - lk82: āļĢ1000 - udom83: āļĢ100000 - metasound: āļĢ100
- lk82: - udom83: - metasound:
Spellcheckingï
Default spellchecker uses Peter Norvigâs algorithm together with word frequency from Thai National Corpus (TNC).
spell()
returns a list of all possible spellings.
[54]:
from pythainlp import spell
spell("āđāļŦāļĨāļ·āļĒāļĄ")
[54]:
['āđāļŦāļĨāļĩāļĒāļĄ', 'āđāļŦāļĨāļ·āļāļĄ']
correct()
returns the most likely spelling.
[55]:
from pythainlp import correct
correct("āđāļŦāļĨāļ·āļĒāļĄ")
[55]:
'āđāļŦāļĨāļĩāļĒāļĄ'
Spellchecking - Custom dictionary and word frequencyï
Custom dictionary can be provided when creating spellchecker.
When create a NorvigSpellChecker
object, you can pass a custom dictionary to custom_dict
parameter.
custom_dict
can be: - a dictionary (dict
), with words (str
) as keys and frequencies (int
) as values; or - a list, a tuple, or a set of (word, frequency) tuples; or - a list, a tuple, or a set of just words, without their frequencies â in this case 1
will be assigned to every words.
[56]:
from pythainlp.spell import NorvigSpellChecker
user_dict = [("āđāļŦāļĨāļĩāļĒāļĄ", 50), ("āđāļŦāļĨāļ·āļāļĄ", 1000), ("āđāļŦāļĨāļĩāļĒāļ§", 1000000)]
checker = NorvigSpellChecker(custom_dict=user_dict)
checker.spell("āđāļŦāļĨāļ·āļĒāļĄ")
[56]:
['āđāļŦāļĨāļ·āļāļĄ', 'āđāļŦāļĨāļĩāļĒāļĄ']
As you can see, our version of NorvigSpellChecker
gives the edit distance a priority over a word frequency.
You can use word frequencies from Thai National Corpus and Thai Textbook Corpus as well.
By default, NorvigSpellChecker
uses Thai National Corpus.
[57]:
from pythainlp.corpus import ttc # Thai Textbook Corpus
checker = NorvigSpellChecker(custom_dict=ttc.word_freqs())
checker.spell("āđāļŦāļĨāļ·āļĒāļĄ")
[57]:
['āđāļŦāļĨāļ·āļāļĄ']
[58]:
checker.correct("āđāļŦāļĨāļ·āļĒāļĄ")
[58]:
'āđāļŦāļĨāļ·āļāļĄ'
To check the current dictionary of a spellchecker:
[59]:
list(checker.dictionary())[1:10]
[59]:
[('āļāļīāļāļĩāđāļāļīāļ', 18),
('āđāļŠāđāļāļĢāļāļ', 40),
('āļāļĨāļīāļ', 6),
('āđāļāđāļ', 13),
('āļāļāļāļāļļāļ', 356),
('āļāļĢāļ°āļŠāļēāļ', 84),
('āļĢāļģāđāļĢ', 11),
('āļĢāđāļ§āļĄāļāđāļāļ', 4),
('āļāļąāļāļĄāļ°āļāļēāļĄ', 3)]
We can also apply conditions and filter function to dictionary when creating spellchecker.
[60]:
checker = NorvigSpellChecker() # use default filter (remove any word with number or non-Thai character)
len(checker.dictionary())
[60]:
39963
[61]:
checker = NorvigSpellChecker(min_freq=5, min_len=2, max_len=15)
len(checker.dictionary())
[61]:
30376
[62]:
checker_no_filter = NorvigSpellChecker(dict_filter=None) # use no filter
len(checker_no_filter.dictionary())
[62]:
66209
[63]:
def remove_yamok(word):
return False if "āđ" in word else True
checker_custom_filter = NorvigSpellChecker(dict_filter=remove_yamok) # use custom filter
len(checker_custom_filter.dictionary())
[63]:
66204
Part-of-Speech Taggingï
[64]:
from pythainlp.tag import pos_tag, pos_tag_sents
pos_tag(["āļāļēāļĢ","āđāļāļīāļāļāļēāļ"])
[64]:
[('āļāļēāļĢ', 'FIXN'), ('āđāļāļīāļāļāļēāļ', 'VACT')]
[65]:
sents = [["āļāļĢāļ°āļāļēāļĻāļŠāļģāļāļąāļāļāļēāļĒāļāļŊ", " ", "āđāļŦāđ",
" ", "'āļāļĨ.āļ.āļŠāļĢāļĢāđāļŠāļĢāļīāļ āđāļāđāļ§āļāļģāđāļāļīāļ'", " ", "āļāđāļāļāļēāļāļāļģāđāļŦāļāđāļ",
" ", "āļāļđāđāļāļĢāļāļāļļāļāļ§āļļāļāļīāļāļīāđāļĻāļĐ", "āļāļāļāļāļąāļāļāļ", " ", "āļāļĢāļ°āļāļĢāļ§āļāļāļĨāļēāđāļŦāļĄ"],
["āđāļĨāļ°", "āđāļāđāļāļāļąāđāļ", "āđāļŦāđ", "āđāļāđāļ", "'āļāļāļīāļāļāļĩāļāļĢāļĄāļāļĢāļ°āļāļēāļŠāļąāļĄāļāļąāļāļāđ'"]]
pos_tag_sents(sents)
[65]:
[[('āļāļĢāļ°āļāļēāļĻāļŠāļģāļāļąāļāļāļēāļĒāļāļŊ', 'NCMN'),
(' ', 'PUNC'),
('āđāļŦāđ', 'JSBR'),
(' ', 'PUNC'),
("'āļāļĨ.āļ.āļŠāļĢāļĢāđāļŠāļĢāļīāļ āđāļāđāļ§āļāļģāđāļāļīāļ'", 'NCMN'),
(' ', 'PUNC'),
('āļāđāļāļāļēāļāļāļģāđāļŦāļāđāļ', 'NCMN'),
(' ', 'PUNC'),
('āļāļđāđāļāļĢāļāļāļļāļāļ§āļļāļāļīāļāļīāđāļĻāļĐ', 'NCMN'),
('āļāļāļāļāļąāļāļāļ', 'NCMN'),
(' ', 'PUNC'),
('āļāļĢāļ°āļāļĢāļ§āļāļāļĨāļēāđāļŦāļĄ', 'NCMN')],
[('āđāļĨāļ°', 'JCRG'),
('āđāļāđāļāļāļąāđāļ', 'VACT'),
('āđāļŦāđ', 'JSBR'),
('āđāļāđāļ', 'VSTA'),
("'āļāļāļīāļāļāļĩāļāļĢāļĄāļāļĢāļ°āļāļēāļŠāļąāļĄāļāļąāļāļāđ'", 'NCMN')]]
Named-Entity Taggingï
The tagger use BIO scheme: - B - beginning of entity - I - inside entity - O - outside entity
[1]:
#!pip3 install pythainlp[ner]
from pythainlp.tag.thainer import ThaiNameTagger
ner = ThaiNameTagger()
ner.get_ner("24 āļĄāļī.āļĒ. 2563 āļāļāļŠāļāļāļĢāļ°āļāļāđāļ§āļĨāļē 6:00 āļ. āđāļāļīāļāļāļēāļāļāļēāļāļāļāļŠāđāļāļāļĢāļļāļāđāļāļāđāļāļĨāđāļāļāļāļāļģāđāļāļāđāļāļāļĢ āđāļāļāļąāļāļŦāļ§āļąāļāļāļģāđāļāļāđāļāļāļĢ āļāļąāđāļ§āļĢāļēāļāļē 297 āļāļēāļ")
[1]:
[('24', 'NUM', 'B-DATE'),
(' ', 'PUNCT', 'I-DATE'),
('āļĄāļī.āļĒ.', 'NOUN', 'I-DATE'),
(' ', 'PUNCT', 'O'),
('2563', 'NUM', 'O'),
(' ', 'PUNCT', 'O'),
('āļāļāļŠāļāļāļĢāļ°āļāļ', 'PART', 'O'),
('āđāļ§āļĨāļē', 'NOUN', 'O'),
(' ', 'PUNCT', 'O'),
('6:00', 'NUM', 'B-TIME'),
(' ', 'PUNCT', 'I-TIME'),
('āļ.', 'NOUN', 'I-TIME'),
(' ', 'PUNCT', 'O'),
('āđāļāļīāļāļāļēāļ', 'VERB', 'O'),
('āļāļēāļ', 'ADP', 'O'),
('āļāļāļŠāđāļ', 'NOUN', 'B-ORGANIZATION'),
('āļāļĢāļļāļāđāļāļ', 'NOUN', 'I-ORGANIZATION'),
('āđāļāļĨāđ', 'ADJ', 'O'),
('āļāļāļ', 'NOUN', 'B-LOCATION'),
('āļāļģāđāļāļāđāļāļāļĢ', 'NOUN', 'I-LOCATION'),
(' ', 'PUNCT', 'O'),
('āđāļ', 'AUX', 'O'),
('āļāļąāļāļŦāļ§āļąāļ', 'VERB', 'B-LOCATION'),
('āļāļģāđāļāļāđāļāļāļĢ', 'NOUN', 'I-LOCATION'),
(' ', 'PUNCT', 'O'),
('āļāļąāđāļ§', 'NOUN', 'O'),
('āļĢāļēāļāļē', 'NOUN', 'O'),
(' ', 'PUNCT', 'O'),
('297', 'NUM', 'B-MONEY'),
(' ', 'PUNCT', 'I-MONEY'),
('āļāļēāļ', 'NOUN', 'I-MONEY')]
Word Vectorï
[67]:
import pythainlp.word_vector
pythainlp.word_vector.similarity("āļāļ", "āļĄāļāļļāļĐāļĒāđ")
[67]:
0.2504981
[68]:
pythainlp.word_vector.doesnt_match(["āļāļ", "āļĄāļāļļāļĐāļĒāđ", "āļāļļāļāļāļĨ", "āđāļāđāļēāļŦāļāđāļēāļāļĩāđ", "āđāļāđ"])
/usr/local/lib/python3.7/site-packages/gensim/models/keyedvectors.py:877: FutureWarning: arrays to stack must be passed as a "sequence" type such as list or tuple. Support for non-sequence iterables such as generators is deprecated as of NumPy 1.16 and will raise an error in the future.
vectors = vstack(self.word_vec(word, use_norm=True) for word in used_words).astype(REAL)
[68]:
'āđāļāđ'
Number Spell Outï
[69]:
from pythainlp.util import bahttext
bahttext(1234567890123.45)
[69]:
'āļŦāļāļķāđāļāļĨāđāļēāļāļŠāļāļāđāļŠāļāļŠāļēāļĄāļŦāļĄāļ·āđāļāļŠāļĩāđāļāļąāļāļŦāđāļēāļĢāđāļāļĒāļŦāļāļŠāļīāļāđāļāđāļāļĨāđāļēāļāđāļāļāđāļŠāļāđāļāđāļēāļŦāļĄāļ·āđāļāļŦāļāļķāđāļāļĢāđāļāļĒāļĒāļĩāđāļŠāļīāļāļŠāļēāļĄāļāļēāļāļŠāļĩāđāļŠāļīāļāļŦāđāļēāļŠāļāļēāļāļāđ'
bahttext()
will round the satang part
[70]:
bahttext(1.909)
[70]:
'āļŦāļāļķāđāļāļāļēāļāđāļāđāļēāļŠāļīāļāđāļāđāļāļŠāļāļēāļāļāđ'