From 6245a123ab2ffb2f8e4a25ee2c6bc42118d9f4dc Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Sun, 4 Jun 2017 20:47:14 +0700 Subject: [PATCH 01/71] start pythainlp 1.4! MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit เริ่มต้นพัฒนา PyThaiNLP 1.4 --- README.md | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 638cd5dd5..bb88fbfa1 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Natural language processing หรือ การประมวลภาษา กำลังพัฒนา ### Version -1.3 +1.4 ### ความสามารถ - ตัดคำภาษาไทย diff --git a/setup.py b/setup.py index 0659102e4..edcc7d151 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ setup( name='pythainlp', - version='1.3', + version='1.4', description="Thai NLP in python package.", author='Wannaphong Phatthiyaphaibun', author_email='wannaphong@yahoo.com', From a196d9ac55c6309f7c189cf711fce30d2421dc57 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Sun, 4 Jun 2017 21:02:16 +0700 Subject: [PATCH 02/71] add new wordnet api --- pythainlp/corpus/wordnet.py | 44 +++++++++++++++++++++++++++++++++++-- 1 file changed, 42 insertions(+), 2 deletions(-) diff --git a/pythainlp/corpus/wordnet.py b/pythainlp/corpus/wordnet.py index 96203b5e5..c92b3c06e 100644 --- a/pythainlp/corpus/wordnet.py +++ b/pythainlp/corpus/wordnet.py @@ -1,5 +1,14 @@ # WordNet ภาษาไทย from __future__ import unicode_literals,print_function,absolute_import +import nltk +try: + nltk.data.find("corpora/omw") +except: + nltk.download('omw') +from nltk.corpus import wordnet +''' +API ตัวเก่า +''' import sqlite3 import pythainlp import os @@ -11,18 +20,49 @@ Synset = namedtuple('Synset', 'synset li') def getWords(wordid): """เป็นคำสั่ง ใช้รับคำจาก ID รับค่า str ส่งออกเป็น tuple ('Word', 'synsetid li')""" + print("แจ้งเตือน !!! API ตัวนี้จะยกเลิกการใช้งานใน PyThaiNLP 1.5") words = [] cur = conn.execute("select * from word_synset where synsetid=?", (wordid,)) row = cur.fetchone() return Word(*cur.fetchone()) def getSynset(synset): """เป็นคำสั่ง ใช้รับ Synset รับค่า str ส่งออกเป็น tuple ('Synset', 'synset li')""" + print("แจ้งเตือน !!! API ตัวนี้จะยกเลิกการใช้งานใน PyThaiNLP 1.5") cursor=conn.execute("select * from word_synset where li=?",(synset,)) row=cursor.fetchone() if row: return Synset(*row) else: return None +''' +API ตัวใหม่ เริ่มใช้ตั้งแต่ PyThaiNLP 1.4 เป็นต้นไป +''' +def synsets(word, pos=None, lang="tha"): + return wordnet.synsets(lemma=word,pos=pos,lang=lang) +def synset(name_synsets): + return wordnet.synset(name_synsets) +def all_lemma_names(pos=None, lang="tha"): + return wordnet.all_lemma_names(pos=pos, lang=lang) +def all_synsets(pos=None): + return wordnet.all_synsets(pos=pos) +def langs(): + return wordnet.langs() +def lemmas(word,pos=None,lang="tha"): + return wordnet.lemmas(word,pos=pos,lang=lang) +def lemma(name_synsets): + return wordnet.lemma(name_synsets) +def lemma_from_key(key): + return wordnet.lemma_from_key(key) +def path_similarity(synsets1,synsets2): + return wordnet.path_similarity(synsets1,synsets2) +def lch_similarity(synsets1,synsets2): + return wordnet.lch_similarity(synsets1,synsets2) +def wup_similarity(synsets1,synsets2): + return wordnet.wup_similarity(synsets1,synsets2) +def morphy(form, pos=None): + return wordnet.morphy(form, pos=None) +def custom_lemmas(tab_file, lang): + return wordnet.custom_lemmas(tab_file, lang) if __name__ == "__main__": - print(getSynset("ผลักดันกลับ")) - print(getWords("02503365-v")) \ No newline at end of file + #print(getSynset("ผลักดันกลับ")) + #print(getWords("02503365-v")) \ No newline at end of file From ddfad45dc890c69b7bfb3b39fd2a5226996e9e3b Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Sun, 4 Jun 2017 21:04:38 +0700 Subject: [PATCH 03/71] fix test --- .travis.yml | 1 - appveyor.yml | 8 -------- 2 files changed, 9 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5edc832d1..653cf3d3e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,6 @@ language: python python: - - "2.7" - "3.4" - "3.5" - "3.6" diff --git a/appveyor.yml b/appveyor.yml index 51d87df9e..1d0606287 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -10,14 +10,6 @@ environment: # a later point release. # See: http://www.appveyor.com/docs/installed-software#python - - PYTHON: "C:\\Python27" - PYTHON_VERSION: "2.7.x" # currently 2.7.9 - PYTHON_ARCH: "32" - - - PYTHON: "C:\\Python27-x64" - PYTHON_VERSION: "2.7.x" # currently 2.7.9 - PYTHON_ARCH: "64" - - PYTHON: "C:\\Python34" PYTHON_VERSION: "3.4.x" # currently 3.4.3 PYTHON_ARCH: "32" From 1941ef10aa51c0ad61f8eda4e92f5bf50930d58b Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Sun, 4 Jun 2017 22:47:08 +0700 Subject: [PATCH 04/71] add Trie in mm --- pythainlp/segment/mm.py | 3 ++- setup.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pythainlp/segment/mm.py b/pythainlp/segment/mm.py index 4eb6b65b5..cf48ae292 100644 --- a/pythainlp/segment/mm.py +++ b/pythainlp/segment/mm.py @@ -13,6 +13,7 @@ import re from .thai import newdata # load dictionary from pythainlp.corpus import stopwords # load stopwords +import marisa_trie class wordcut(object): def __init__(self, removeRepeat=True, stopDictionary="", removeSpaces=True, minLength=1, stopNumber=False, removeNonCharacter=False, caseSensitive=True, ngram=(1,1), negation=False): @@ -22,7 +23,7 @@ def __init__(self, removeRepeat=True, stopDictionary="", removeSpaces=True, minL self.stopword = False self.stopdict = stopwords.words('thai') - self.trie = d + self.trie = marisa_trie.Trie(d) self.removeRepeat = removeRepeat self.stopNumber = stopNumber self.removeSpaces = removeSpaces diff --git a/setup.py b/setup.py index edcc7d151..bdf18704a 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,8 @@ 'pyicu', 'nltk>=3.2.2', 'future>=0.16.0', - 'six' + 'six', + 'marisa_trie' ] if sys.version_info >= (3,4): requirements.append('artagger') From d654a1c21bcb79f5244e05e7ba771f057e06c6bd Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Mon, 5 Jun 2017 11:56:16 +0700 Subject: [PATCH 05/71] add docs --- ...\270\224\340\270\210\340\270\262\340\270\201 GitHub.md" | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 "docs/\340\270\247\340\270\264\340\270\230\340\270\265\340\270\225\340\270\264\340\270\224\340\270\225\340\270\261\340\271\211\340\270\207 PyThaiNLP \340\271\200\340\270\247\340\270\212\340\270\261\340\271\210\340\270\231\340\270\245\340\271\210\340\270\262\340\270\252\340\270\270\340\270\224\340\270\210\340\270\262\340\270\201 GitHub.md" diff --git "a/docs/\340\270\247\340\270\264\340\270\230\340\270\265\340\270\225\340\270\264\340\270\224\340\270\225\340\270\261\340\271\211\340\270\207 PyThaiNLP \340\271\200\340\270\247\340\270\212\340\270\261\340\271\210\340\270\231\340\270\245\340\271\210\340\270\262\340\270\252\340\270\270\340\270\224\340\270\210\340\270\262\340\270\201 GitHub.md" "b/docs/\340\270\247\340\270\264\340\270\230\340\270\265\340\270\225\340\270\264\340\270\224\340\270\225\340\270\261\340\271\211\340\270\207 PyThaiNLP \340\271\200\340\270\247\340\270\212\340\270\261\340\271\210\340\270\231\340\270\245\340\271\210\340\270\262\340\270\252\340\270\270\340\270\224\340\270\210\340\270\262\340\270\201 GitHub.md" new file mode 100644 index 000000000..2357c6ccb --- /dev/null +++ "b/docs/\340\270\247\340\270\264\340\270\230\340\270\265\340\270\225\340\270\264\340\270\224\340\270\225\340\270\261\340\271\211\340\270\207 PyThaiNLP \340\271\200\340\270\247\340\270\212\340\270\261\340\271\210\340\270\231\340\270\245\340\271\210\340\270\262\340\270\252\340\270\270\340\270\224\340\270\210\340\270\262\340\270\201 GitHub.md" @@ -0,0 +1,7 @@ +# วิธีติดตั้ง PyThaiNLP เวชั่นล่าสุดจาก GitHub + +ใช้คำสั่งนี้ในคอมมาไลน์ + +``` +pip install -U https://github.com/wannaphongcom/pythainlp/archive/pythainlp1.4.zip +``` \ No newline at end of file From fc6dab677a041df1929c24bc16c051f39cbcfba5 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Mon, 5 Jun 2017 12:20:10 +0700 Subject: [PATCH 06/71] del old api --- pythainlp/__init__.py | 2 -- pythainlp/corpus/wordnet.py | 3 --- pythainlp/postaggers/text.py | 23 ------------------- pythainlp/segment/__init__.py | 7 ------ pythainlp/tag/__init__.py | 5 ++-- .../{postaggers/__init__.py => tag/old.py} | 2 +- pythainlp/tokenize/__init__.py | 6 ++--- pythainlp/{segment => tokenize}/dict.py | 0 pythainlp/{segment => tokenize}/isthai.py | 0 pythainlp/{segment => tokenize}/mm.py | 0 pythainlp/{segment => tokenize}/pyicu.py | 4 ++-- pythainlp/{segment => tokenize}/thai.py | 0 12 files changed, 8 insertions(+), 44 deletions(-) delete mode 100644 pythainlp/postaggers/text.py delete mode 100644 pythainlp/segment/__init__.py rename pythainlp/{postaggers/__init__.py => tag/old.py} (96%) rename pythainlp/{segment => tokenize}/dict.py (100%) rename pythainlp/{segment => tokenize}/isthai.py (100%) rename pythainlp/{segment => tokenize}/mm.py (100%) rename pythainlp/{segment => tokenize}/pyicu.py (96%) rename pythainlp/{segment => tokenize}/thai.py (100%) diff --git a/pythainlp/__init__.py b/pythainlp/__init__.py index ad6103306..e6e9f6305 100644 --- a/pythainlp/__init__.py +++ b/pythainlp/__init__.py @@ -8,13 +8,11 @@ from pythainlp.sentiment import * from pythainlp.spell import * from pythainlp.romanization import * -from pythainlp.segment import * from pythainlp.tokenize import * from pythainlp.rank import * from pythainlp.change import * from pythainlp.number import * from pythainlp.date import * -from pythainlp.postaggers import * from pythainlp.tag import * from pythainlp.collation import * from pythainlp.test import * diff --git a/pythainlp/corpus/wordnet.py b/pythainlp/corpus/wordnet.py index c92b3c06e..094533ee9 100644 --- a/pythainlp/corpus/wordnet.py +++ b/pythainlp/corpus/wordnet.py @@ -63,6 +63,3 @@ def morphy(form, pos=None): return wordnet.morphy(form, pos=None) def custom_lemmas(tab_file, lang): return wordnet.custom_lemmas(tab_file, lang) -if __name__ == "__main__": - #print(getSynset("ผลักดันกลับ")) - #print(getWords("02503365-v")) \ No newline at end of file diff --git a/pythainlp/postaggers/text.py b/pythainlp/postaggers/text.py deleted file mode 100644 index d0935146c..000000000 --- a/pythainlp/postaggers/text.py +++ /dev/null @@ -1,23 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import,division,print_function,unicode_literals -from pythainlp.segment import segment -import pythainlp -import codecs -import os -import json -import six -import nltk.tag, nltk.data -templates_dir = os.path.join(os.path.dirname(pythainlp.__file__), 'corpus') -template_file = os.path.join(templates_dir, 'thaipos.json') -#default_tagger = nltk.data.load(nltk.tag._POS_TAGGER) -def data(): - with codecs.open(template_file,'r',encoding='utf-8-sig') as handle: - model = json.load(handle) - return model -data1 =data() -#Postaggers ภาษาไทย -def tag(text): - """รับค่าเป็นข้อความ ''str'' คืนค่าเป็น ''list'' เช่น [('ข้อความ', 'ชนิดคำ')]""" - text= segment(text) - tagger = nltk.tag.UnigramTagger(model=data1)# backoff=default_tagger) - return tagger.tag(text) \ No newline at end of file diff --git a/pythainlp/segment/__init__.py b/pythainlp/segment/__init__.py deleted file mode 100644 index 0de882ccc..000000000 --- a/pythainlp/segment/__init__.py +++ /dev/null @@ -1,7 +0,0 @@ -# -*- coding: utf-8 -*- -from __future__ import absolute_import,unicode_literals -#__all__ = ['pyicu', 'dict','isthai','thai'] -try: - from .pyicu import segment -except: - from .dict import segment \ No newline at end of file diff --git a/pythainlp/tag/__init__.py b/pythainlp/tag/__init__.py index fe8072339..b83ebdfab 100644 --- a/pythainlp/tag/__init__.py +++ b/pythainlp/tag/__init__.py @@ -1,7 +1,6 @@ # -*- coding: utf-8 -*- # TODO ปรับ API ให้เหมือน nltk from __future__ import absolute_import,division,print_function,unicode_literals -from pythainlp.postaggers import tag import sys def pos_tag(text,engine='old'): """ @@ -13,7 +12,7 @@ def pos_tag(text,engine='old'): * artagger เป็น RDR POS Tagger """ if engine=='old': - from pythainlp.postaggers import tag + from .old import tag elif engine=='artagger': if sys.version_info < (3,4): sys.exit('Sorry, Python < 3.4 is not supported') @@ -25,4 +24,4 @@ def tag(text1): for word in words: totag.append((word.word, word.tag)) return totag - return tag(text) \ No newline at end of file + return tag(text) diff --git a/pythainlp/postaggers/__init__.py b/pythainlp/tag/old.py similarity index 96% rename from pythainlp/postaggers/__init__.py rename to pythainlp/tag/old.py index 17e69e6ce..6a220faf6 100644 --- a/pythainlp/postaggers/__init__.py +++ b/pythainlp/tag/old.py @@ -16,4 +16,4 @@ def tag(text): """ รับค่าเป็น ''list'' คืนค่าเป็น ''list'' เช่น [('ข้อความ', 'ชนิดคำ')]""" tagger = nltk.tag.UnigramTagger(model=data())# backoff=default_tagger) - return tagger.tag(text) \ No newline at end of file + return tagger.tag(text) diff --git a/pythainlp/tokenize/__init__.py b/pythainlp/tokenize/__init__.py index 80b446515..f2dae46e1 100644 --- a/pythainlp/tokenize/__init__.py +++ b/pythainlp/tokenize/__init__.py @@ -11,9 +11,9 @@ def word_tokenize(text,engine='icu'): - mm ใช้ Maximum Matching algorithm """ if engine=='icu': - from pythainlp.segment.pyicu import segment + from .pyicu import segment elif engine=='dict': - from pythainlp.segment.dict import segment + from .dict import segment elif engine=='mm': - from pythainlp.segment.mm import segment + from .mm import segment return segment(text) \ No newline at end of file diff --git a/pythainlp/segment/dict.py b/pythainlp/tokenize/dict.py similarity index 100% rename from pythainlp/segment/dict.py rename to pythainlp/tokenize/dict.py diff --git a/pythainlp/segment/isthai.py b/pythainlp/tokenize/isthai.py similarity index 100% rename from pythainlp/segment/isthai.py rename to pythainlp/tokenize/isthai.py diff --git a/pythainlp/segment/mm.py b/pythainlp/tokenize/mm.py similarity index 100% rename from pythainlp/segment/mm.py rename to pythainlp/tokenize/mm.py diff --git a/pythainlp/segment/pyicu.py b/pythainlp/tokenize/pyicu.py similarity index 96% rename from pythainlp/segment/pyicu.py rename to pythainlp/tokenize/pyicu.py index 91539b01d..78e44619e 100644 --- a/pythainlp/segment/pyicu.py +++ b/pythainlp/tokenize/pyicu.py @@ -1,7 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import,print_function,unicode_literals from itertools import groupby -import PyICU +import icu def isEnglish(s): try: try: @@ -29,7 +29,7 @@ def isThai(chr): return False def segment(txt): """รับค่า ''str'' คืนค่าออกมาเป็น ''list'' ที่ได้มาจากการตัดคำโดย ICU""" - bd = PyICU.BreakIterator.createWordInstance(PyICU.Locale("th")) + bd = icu.BreakIterator.createWordInstance(icu.Locale("th")) bd.setText(txt.replace(' ', '')) breaks = list(bd) result=[txt[x[0]:x[1]] for x in zip([0]+breaks, breaks)] diff --git a/pythainlp/segment/thai.py b/pythainlp/tokenize/thai.py similarity index 100% rename from pythainlp/segment/thai.py rename to pythainlp/tokenize/thai.py From 6e5a63ed694f9c9f5e166cc64a152f0d39337ff5 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Mon, 5 Jun 2017 19:19:27 +0700 Subject: [PATCH 07/71] fix error in hunspell --- pythainlp/spell/hunspell.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pythainlp/spell/hunspell.py b/pythainlp/spell/hunspell.py index 49b8438da..e451a3e86 100644 --- a/pythainlp/spell/hunspell.py +++ b/pythainlp/spell/hunspell.py @@ -30,7 +30,7 @@ def spell(word,lang='th_TH'): getoutput = getoutput.split(",") del get return getoutput - except: + except subprocess.CalledProcessError: print('plase install hunspell') return None if __name__ == "__main__": From d2f79f7d648448576df629c9333d4d110a10134a Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Mon, 5 Jun 2017 23:02:11 +0700 Subject: [PATCH 08/71] fix pyicu --- pythainlp/tokenize/mm.py | 1 - pythainlp/tokenize/pyicu.py | 5 ++++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/pythainlp/tokenize/mm.py b/pythainlp/tokenize/mm.py index cf48ae292..0c6d9b3b0 100644 --- a/pythainlp/tokenize/mm.py +++ b/pythainlp/tokenize/mm.py @@ -82,7 +82,6 @@ def searchTrie(self, word): for data in self.trie.keys(word[0:longest]): if(len(data) > longest): if data in word[0:len(data)]: - wordLength = 0 longest = len(data) maxData = data diff --git a/pythainlp/tokenize/pyicu.py b/pythainlp/tokenize/pyicu.py index 78e44619e..956ce2cdf 100644 --- a/pythainlp/tokenize/pyicu.py +++ b/pythainlp/tokenize/pyicu.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import,print_function,unicode_literals from itertools import groupby +import re import icu def isEnglish(s): try: @@ -30,7 +31,8 @@ def isThai(chr): def segment(txt): """รับค่า ''str'' คืนค่าออกมาเป็น ''list'' ที่ได้มาจากการตัดคำโดย ICU""" bd = icu.BreakIterator.createWordInstance(icu.Locale("th")) - bd.setText(txt.replace(' ', '')) + pattern = re.compile(r'\s+') + bd.setText(re.sub(pattern, '', txt)) breaks = list(bd) result=[txt[x[0]:x[1]] for x in zip([0]+breaks, breaks)] result1=[] @@ -62,3 +64,4 @@ def segment(txt): print(segment('ทดสอบระบบตัดคำด้วยไอซียู')) print(segment('ผมชอบพูดไทยคำ English')) print(segment('ผมชอบพูดไทยคำEnglishคำ')) + print(segment('ผมชอบพูดไทยคำEnglish540 บาท')) From 7d58eca336189c151dc137a3c719d778217a451d Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Mon, 12 Jun 2017 13:43:19 +0700 Subject: [PATCH 09/71] add data to stopwords --- pythainlp/corpus/make-stopword.py | 53 ++++ pythainlp/corpus/stopwords-th-old.txt | 111 +++++++ pythainlp/corpus/stopwords-th.txt | 423 ++++++++++++++++++++++++++ pythainlp/corpus/stopwords-th1.txt | 116 +++++++ pythainlp/corpus/stopwords-th2.txt | 114 +++++++ pythainlp/corpus/stopwords-th3.txt | 322 ++++++++++++++++++++ pythainlp/corpus/stopwords.py | 21 +- pythainlp/tokenize/mm.py | 6 +- pythainlp/tokenize/pyicu.py | 6 +- setup.py | 7 +- 10 files changed, 1171 insertions(+), 8 deletions(-) create mode 100755 pythainlp/corpus/make-stopword.py create mode 100644 pythainlp/corpus/stopwords-th-old.txt create mode 100644 pythainlp/corpus/stopwords-th.txt create mode 100644 pythainlp/corpus/stopwords-th1.txt create mode 100644 pythainlp/corpus/stopwords-th2.txt create mode 100644 pythainlp/corpus/stopwords-th3.txt diff --git a/pythainlp/corpus/make-stopword.py b/pythainlp/corpus/make-stopword.py new file mode 100755 index 000000000..2bf0739b7 --- /dev/null +++ b/pythainlp/corpus/make-stopword.py @@ -0,0 +1,53 @@ +''' +โปรแกรมรวบรวมคำศัพท์เพื่อสร้าง dict +=================== +เขียนโดย นาย วรรณพงษ์ ภัททิยไพบูลย์ + +29/5/2560 +22:45 น. +''' +import codecs +def data(template_file): + ''' + เปิดไฟล์แล้วอ่านทีละบรรทัดส่งออกเป็น list + ''' + with codecs.open(template_file, 'r',encoding='utf-8-sig') as f: + lines = f.read().splitlines() + f.close() + return lines +def list1list(list1,list2): + ''' + ทำการเปรียบเทียบ 2 list + ''' + i=0 + list2=list2 + list1=list1 + while i= 3584 and cVal <= 3711): + return True''' + if detect(chr)=='th': return True return False except: @@ -65,3 +68,4 @@ def segment(txt): print(segment('ผมชอบพูดไทยคำ English')) print(segment('ผมชอบพูดไทยคำEnglishคำ')) print(segment('ผมชอบพูดไทยคำEnglish540 บาท')) + print(segment('ประหยัด ไฟเบอห้า')) diff --git a/setup.py b/setup.py index bdf18704a..1bf65a7da 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,8 @@ 'nltk>=3.2.2', 'future>=0.16.0', 'six', - 'marisa_trie' + 'marisa_trie', + 'langdetect' ] if sys.version_info >= (3,4): requirements.append('artagger') @@ -26,7 +27,7 @@ url='https://github.com/wannaphongcom/pythainlp', packages=find_packages(), test_suite='pythainlp.test', - package_data={'pythainlp.corpus':['thaipos.json','thaiword.txt','LICENSE_THA_WN','tha-wn.db','new-thaidict.txt','negation.txt'],'pythainlp.sentiment':['vocabulary.data','sentiment.data']}, + package_data={'pythainlp.corpus':['stopwords-th.txt','thaipos.json','thaiword.txt','LICENSE_THA_WN','tha-wn.db','new-thaidict.txt','negation.txt'],'pythainlp.sentiment':['vocabulary.data','sentiment.data']}, include_package_data=True, install_requires=requirements, license='Apache Software License 2.0', @@ -39,4 +40,4 @@ 'Natural Language :: Thai', 'Topic :: Text Processing :: Linguistic', 'Programming Language :: Python :: Implementation'], -) \ No newline at end of file +) From 84ef9825ebed541087741ccecacfe00fd4d5b3ea Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Mon, 12 Jun 2017 13:47:20 +0700 Subject: [PATCH 10/71] fix stopwords --- pythainlp/corpus/stopwords-th.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/pythainlp/corpus/stopwords-th.txt b/pythainlp/corpus/stopwords-th.txt index 1c5904298..5e2cb6405 100644 --- a/pythainlp/corpus/stopwords-th.txt +++ b/pythainlp/corpus/stopwords-th.txt @@ -114,9 +114,8 @@ เขา เคย ไม่ -้ง อยาก -ทั้งนี้ ้ง +ทั้งนี้ เกิน เกินๆ เกี่ยวกัน From 23336803c5360ed306ef04bf3de7cb5210e0f9aa Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Mon, 12 Jun 2017 22:25:28 +0700 Subject: [PATCH 11/71] add new data to stopwords --- pythainlp/corpus/make-stopword.py | 3 +- pythainlp/corpus/stopwords-th.txt | 692 +++++++++++++++++++++- pythainlp/corpus/stopwords-th2.txt | 2 +- pythainlp/corpus/stopwords-th4.txt | 887 +++++++++++++++++++++++++++++ 4 files changed, 1581 insertions(+), 3 deletions(-) create mode 100644 pythainlp/corpus/stopwords-th4.txt diff --git a/pythainlp/corpus/make-stopword.py b/pythainlp/corpus/make-stopword.py index 2bf0739b7..20ef0b137 100755 --- a/pythainlp/corpus/make-stopword.py +++ b/pythainlp/corpus/make-stopword.py @@ -44,7 +44,8 @@ def savetofile(file,data1,mode='w+'): filelist = [ "stopwords-th1.txt", "stopwords-th2.txt", -"stopwords-th3.txt" +"stopwords-th3.txt", +"stopwords-th4.txt" ] # รายการไฟล์ทั้งหมด for namefile in filelist: print(namefile) diff --git a/pythainlp/corpus/stopwords-th.txt b/pythainlp/corpus/stopwords-th.txt index 5e2cb6405..8fe9bebb5 100644 --- a/pythainlp/corpus/stopwords-th.txt +++ b/pythainlp/corpus/stopwords-th.txt @@ -114,8 +114,8 @@ เขา เคย ไม่ +้ง อยาก -ทั้งนี้ เกิน เกินๆ เกี่ยวกัน @@ -420,3 +420,693 @@ อยางนั้น อยางนี้ อยางโนน +ก็คือ +ก็แค่ +ก็จะ +ก็ดี +ก็ได้ +ก็ต่อเมื่อ +ก็ตาม +ก็ตามแต่ +ก็ตามที +ก็แล้วแต่ +กระทั่ง +กระทำ +กระนั้น +กระผม +กลับ +กล่าวคือ +กลุ่ม +กลุ่มก้อน +กลุ่มๆ +กว้าง +กว้างขวาง +กว้างๆ +ก่อนหน้า +ก่อนหน้านี้ +ก่อนๆ +กันดีกว่า +กันดีไหม +กันเถอะ +กันนะ +กันและกัน +กันไหม +กันเอง +กำลัง +กำลังจะ +กำหนด +กู +เก็บ +เกิด +เกี่ยวข้อง +แก่ +แก้ไข +ใกล้ +ใกล้ๆ +ข้า +ข้าง +ข้างเคียง +ข้างต้น +ข้างบน +ข้างล่าง +ข้างๆ +ขาด +ข้าพเจ้า +ข้าฯ +เข้าใจ +เขียน +คงจะ +คงอยู่ +ครบ +ครบครัน +ครบถ้วน +ครั้งกระนั้น +ครั้งก่อน +ครั้งครา +ครั้งคราว +ครั้งใด +ครั้งที่ +ครั้งนั้น +ครั้งนี้ +ครั้งละ +ครั้งหนึ่ง +ครั้งหลัง +ครั้งหลังสุด +ครั้งไหน +ครั้งๆ +ครัน +ครับ +ครา +คราใด +คราที่ +ครานั้น +ครานี้ +คราหนึ่ง +คราไหน +คราว +คราวก่อน +คราวใด +คราวที่ +คราวนั้น +คราวนี้ +คราวโน้น +คราวละ +คราวหน้า +คราวหนึ่ง +คราวหลัง +คราวไหน +คราวๆ +คล้าย +คล้ายกัน +คล้ายกันกับ +คล้ายกับ +คล้ายกับว่า +คล้ายว่า +ควร +ค่อน +ค่อนข้าง +ค่อนข้างจะ +ค่อยไปทาง +ค่อนมาทาง +ค่อย +ค่อยๆ +คะ +ค่ะ +คำ +คิด +คิดว่า +คุณ +คุณๆ +เคยๆ +แค่ +แค่จะ +แค่นั้น +แค่นี้ +แค่เพียง +แค่ว่า +แค่ไหน +ใคร่ +ใคร่จะ +ง่าย +ง่ายๆ +จนกว่า +จนแม้ +จนแม้น +จังๆ +จวบกับ +จวบจน +จ้ะ +จ๊ะ +จะได้ +จัง +จัดการ +จัดงาน +จัดแจง +จัดตั้ง +จัดทำ +จัดหา +จัดให้ +จับ +จ้า +จ๋า +จากนั้น +จากนี้ +จากนี้ไป +จำ +จำเป็น +จำพวก +จึงจะ +จึงเป็น +จู่ๆ +ฉะนั้น +ฉะนี้ +ฉัน +เฉกเช่น +เฉย +เฉยๆ +ไฉน +ช่วงก่อน +ช่วงต่อไป +ช่วงถัดไป +ช่วงท้าย +ช่วงที่ +ช่วงนั้น +ช่วงนี้ +ช่วงระหว่าง +ช่วงแรก +ช่วงหน้า +ช่วงหลัง +ช่วงๆ +ช่วย +ช้า +ช้านาน +ชาว +ช้าๆ +เช่นก่อน +เช่นกัน +เช่นเคย +เช่นดัง +เช่นดังก่อน +เช่นดังเก่า +เช่นดังที่ +เช่นดังว่า +เช่นเดียวกัน +เช่นเดียวกับ +เช่นใด +เช่นที่ +เช่นที่เคย +เช่นที่ว่า +เช่นนั้น +เช่นนั้นเอง +เช่นนี้ +เช่นเมื่อ +เช่นไร +เชื่อ +เชื่อถือ +เชื่อมั่น +เชื่อว่า +ใช่ +ใช่ไหม +ใช้ +ซะ +ซะก่อน +ซะจน +ซะจนกระทั่ง +ซะจนถึง +ซึ่งได้แก่ +ด้วยกัน +ด้วยเช่นกัน +ด้วยที่ +ด้วยเพราะ +ด้วยว่า +ด้วยเหตุที่ +ด้วยเหตุนั้น +ด้วยเหตุนี้ +ด้วยเหตุเพราะ +ด้วยเหตุว่า +ด้วยเหมือนกัน +ดังกล่าว +ดังกับว่า +ดั่งกับว่า +ดังเก่า +ดั่งเก่า +ดั่งเคย +ต่างก็ +ต่างหาก +ตามด้วย +ตามแต่ +ตามที่ +ตามๆ +เต็มไปด้วย +เต็มไปหมด +เต็มๆ +แต่ก็ +แต่ก่อน +แต่จะ +แต่เดิม +แต่ต้อง +แต่ถ้า +แต่ทว่า +แต่ที่ +แต่นั้น +แต่เพียง +แต่เมื่อ +แต่ไร +แต่ละ +แต่ว่า +แต่ไหน +แต่อย่างใด +โต +โตๆ +ใต้ +ถ้าจะ +ถ้าหาก +ถึงแก่ +ถึงแม้ +ถึงแม้จะ +ถึงแม้ว่า +ถึงอย่างไร +ถือว่า +ถูกต้อง +ทว่า +ทั้งนั้นด้วย +ทั้งปวง +ทั้งเป็น +ทั้งมวล +ทั้งสิ้น +ทั้งหมด +ทั้งหลาย +ทั้งๆ +ทัน +ทันใดนั้น +ทันที +ทันทีทันใด +ทั่ว +ท +าไม +าไร +าให้ +าๆ +ที +ที่จริง +ที่ซึ่ง +ทีเดียว +ทีใด +ที่ใด +ที่ได้ +ทีเถอะ +ที่แท้ +ที่แท้จริง +ที่นั้น +ที่นี้ +ทีไร +ทีละ +ที่ละ +ที่แล้ว +ที่ว่า +ที่แห่งนั้น +ที่ไหน +ทีๆ +ที่ๆ +ทุกคน +ทุกครั้ง +ทุกครา +ทุกคราว +ทุกชิ้น +ทุกตัว +ทุกทาง +ทุกที +ทุกที่ +ทุกเมื่อ +ทุกวัน +ทุกวันนี้ +ทุกสิ่ง +ทุกหน +ทุกแห่ง +ทุกอย่าง +ทุกอัน +ทุกๆ +เท่า +เท่ากัน +เท่ากับ +เท่าใด +เท่าที่ +เท่านั้น +เท่านี้ +เท่าไร +เท่าไหร่ +แท้ +แท้จริง +เธอ +นอกจากว่า +น้อย +น้อยกว่า +น้อยๆ +น่ะ +นั้นไว +นับแต่นี้ +นาง +นางสาว +น่าจะ +นาน +นานๆ +นาย +นำ +นำพา +นำมา +นิด +นิดหน่อย +นิดๆ +นี่ +นี่ไง +นี่นา +นี่แน่ะ +นี่แหละ +นี้แหล่ +นี่เอง +นี้เอง +นู่น +นู้น +เน้น +เนี่ย +เนี่ยเอง +ในช่วง +ในที่ +ในเมื่อ +ในระหว่าง +บน +บอก +บอกแล้ว +บอกว่า +บ่อย +บ่อยกว่า +บ่อยครั้ง +บ่อยๆ +บัดดล +บัดเดี๋ยวนี้ +บัดนั้น +บัดนี้ +บ้าง +บางกว่า +บางขณะ +บางครั้ง +บางครา +บางคราว +บางที +บางที่ +บางแห่ง +บางๆ +ปฏิบัติ +ประกอบ +ประการ +ประการฉะนี้ +ประการใด +ประการหนึ่ง +ประมาณ +ประสบ +ปรับ +ปรากฏ +ปรากฏว่า +ปัจจุบัน +ปิด +เป็นด้วย +เป็นดัง +เป็นต้น +เป็นแต่ +เป็นเพื่อ +เป็นอัน +เป็นอันมาก +เป็นอาทิ +ผ่านๆ +ผู้ +ผู้ใด +เผื่อ +เผื่อจะ +เผื่อที่ +เผื่อว่า +ฝ่าย +ฝ่ายใด +พบว่า +พยายาม +พร้อมกัน +พร้อมกับ +พร้อมด้วย +พร้อมทั้ง +พร้อมที่ +พร้อมเพียง +พวก +พวกกัน +พวกกู +พวกแก +พวกเขา +พวกคุณ +พวกฉัน +พวกท่าน +พวกที่ +พวกเธอ +พวกนั้น +พวกนี้ +พวกนู้น +พวกโน้น +พวกมัน +พวกมึง +พอ +พอกัน +พอควร +พอจะ +พอดี +พอตัว +พอที +พอที่ +พอเพียง +พอแล้ว +พอสม +พอสมควร +พอเหมาะ +พอๆ +พา +พึง +พึ่ง +พื้นๆ +พูด +เพราะฉะนั้น +เพราะว่า +เพิ่ง +เพิ่งจะ +เพิ่ม +เพิ่มเติม +เพียง +เพียงแค่ +เพียงใด +เพียงแต่ +เพียงพอ +เพียงเพราะ +เพื่อว่า +เพื่อให้ +ภายใต้ +มองว่า +มั๊ย +มากกว่า +มากมาย +มิ +มิฉะนั้น +มิใช่ +มิได้ +มีแต่ +มึง +มุ่ง +มุ่งเน้น +มุ่งหมาย +เมื่อก่อน +เมื่อครั้ง +เมื่อครั้งก่อน +เมื่อคราวก่อน +เมื่อคราวที่ +เมื่อคราว +เมื่อคืน +เมื่อเช้า +เมื่อใด +เมื่อนั้น +เมื่อนี้ +เมื่อเย็น +เมื่อไร +เมื่อวันวาน +เมื่อวาน +เมื่อไหร่ +แม้ +แม้กระทั่ง +แม้แต่ +แม้นว่า +แม้ว่า +ไม่ค่อย +ไม่ค่อยจะ +ไม่ค่อยเป็น +ไม่ใช่ +ไม่เป็นไร +ไม่ว่า +ยก +ยกให้ +ยอม +ยอมรับ +ย่อม +ย่อย +ยังคง +ยังงั้น +ยังงี้ +ยังโง้น +ยังไง +ยังจะ +ยังแต่ +ยาก +ยาว +ยาวนาน +ยิ่ง +ยิ่งกว่า +ยิ่งขึ้น +ยิ่งขึ้นไป +ยิ่งจน +ยิ่งจะ +ยิ่งนัก +ยิ่งเมื่อ +ยิ่งแล้ว +ยิ่งใหญ่ +ร่วมกัน +รวมด้วย +ร่วมด้วย +รือว่า +เร็ว +เร็วๆ +เราๆ +เรียก +เรียบ +เรื่อย +เรื่อยๆ +ไร +ล้วน +ล้วนจน +ล้วนแต่ +ละ +ล่าสุด +เล็ก +เล็กน้อย +เล็กๆ +เล่าว่า +แล้วกัน +แล้วแต่ +แล้วเสร็จ +วันใด +วันนั้น +วันนี้ +วันไหน +สบาย +สมัย +สมัยก่อน +สมัยนั้น +สมัยนี้ +สมัยโน้น +ส่วนเกิน +ส่วนด้อย +ส่วนดี +ส่วนใด +ส่วนที่ +ส่วนน้อย +ส่วนนั้น +ส่วนมาก +ส่วนใหญ่ +สั้น +สั้นๆ +สามารถ +สำคัญ +สิ่ง +สิ่งใด +สิ่งนั้น +สิ่งนี้ +สิ่งไหน +สิ้น +เสร็จแล้ว +เสียด้วย +เสียแล้ว +แสดง +แสดงว่า +หน +หนอ +หนอย +หน่อย +หมด +หมดกัน +หมดสิ้น +หรือไง +หรือเปล่า +หรือไม่ +หรือยัง +หรือไร +หากแม้ +หากแม้น +หากแม้นว่า +หากว่า +หาความ +หาใช่ +หารือ +เหตุ +เหตุผล +เหตุนั้น +เหตุนี้ +เหตุไร +เห็นแก่ +เห็นควร +เห็นจะ +เห็นว่า +เหลือ +เหลือเกิน +เหล่า +เหล่านั้น +เหล่านี้ +แห่งใด +แห่งนั้น +แห่งนี้ +แห่งโน้น +แห่งไหน +แหละ +ให้แก่ +ใหญ่ +ใหญ่โต +อย่างเช่น +อย่างดี +อย่างเดียว +อย่างใด +อย่างที่ +อย่างน้อย +อย่างนั้น +อย่างนี้ +อย่างโน้น +อย่างมาก +อย่างยิ่ง +อย่างไร +อย่างไรก็ +อย่างไรก็ได้ +อย่างไรเสีย +อย่างละ +อย่างหนึ่ง +อย่างไหน +อย่างๆ +อัน +อันจะ +อันใด +อันได้แก่ +อันที่ +อันที่จริง +อันที่จะ +อันเนื่องมาจาก +อันละ +อันไหน +อันๆ +อาจจะ +อาจเป็น +อาจเป็นด้วย +อื่น +อื่นๆ +เอ็ง +เอา +ฯ +ฯล +ฯลฯ diff --git a/pythainlp/corpus/stopwords-th2.txt b/pythainlp/corpus/stopwords-th2.txt index 8ce6167f5..434ddacac 100644 --- a/pythainlp/corpus/stopwords-th2.txt +++ b/pythainlp/corpus/stopwords-th2.txt @@ -77,7 +77,7 @@ ทําให้ ทํา ทาง -ทั้งนี้ ้ง +ทั้งนี้ ถ้า ถูก ถึง diff --git a/pythainlp/corpus/stopwords-th4.txt b/pythainlp/corpus/stopwords-th4.txt new file mode 100644 index 000000000..2424dac00 --- /dev/null +++ b/pythainlp/corpus/stopwords-th4.txt @@ -0,0 +1,887 @@ +ก็ +ก็คือ +ก็แค่ +ก็จะ +ก็ดี +ก็ได้ +ก็ต่อเมื่อ +ก็ตาม +ก็ตามแต่ +ก็ตามที +ก็แล้วแต่ +กระทั่ง +กระทำ +กระนั้น +กระผม +กลับ +กล่าว +กล่าวคือ +กลุ่ม +กลุ่มก้อน +กลุ่มๆ +กว่า +กว้าง +กว้างขวาง +กว้างๆ +ก่อน +ก่อนหน้า +ก่อนหน้านี้ +ก่อนๆ +กัน +กันดีกว่า +กันดีไหม +กันเถอะ +กันนะ +กันและกัน +กันไหม +กันเอง +กับ +การ +กำลัง +กำลังจะ +กำหนด +กู +เก็บ +เกิด +เกิน +เกินๆ +เกี่ยวกัน +เกี่ยวกับ +เกี่ยวข้อง +เกี่ยวเนื่อง +เกี่ยวๆ +เกือบ +เกือบจะ +เกือบๆ +แก +แก่ +แก้ไข +ใกล้ +ใกล้ๆ +ไกล +ไกลๆ +ขณะ +ขณะเดียวกัน +ขณะใด +ขณะใดๆ +ขณะที่ +ขณะนั้น +ขณะนี้ +ขณะหนึ่ง +ขวาง +ขวางๆ +ขอ +ของ +ขั้น +ข้า +ข้าง +ข้างเคียง +ข้างต้น +ข้างบน +ข้างล่าง +ข้างๆ +ขาด +ข้าพเจ้า +ข้าฯ +ขึ้น +เขา +เข้า +เข้าใจ +เขียน +คง +คงจะ +คงอยู่ +ครบ +ครบครัน +ครบถ้วน +ครั้ง +ครั้งกระนั้น +ครั้งก่อน +ครั้งครา +ครั้งคราว +ครั้งใด +ครั้งที่ +ครั้งนั้น +ครั้งนี้ +ครั้งละ +ครั้งหนึ่ง +ครั้งหลัง +ครั้งหลังสุด +ครั้งไหน +ครั้งๆ +ครัน +ครับ +ครา +คราใด +คราที่ +ครานั้น +ครานี้ +คราหนึ่ง +คราไหน +คราว +คราวก่อน +คราวใด +คราวที่ +คราวนั้น +คราวนี้ +คราวโน้น +คราวละ +คราวหน้า +คราวหนึ่ง +คราวหลัง +คราวไหน +คราวๆ +คล้าย +คล้ายกัน +คล้ายกันกับ +คล้ายกับ +คล้ายกับว่า +คล้ายว่า +ควร +ความ +ค่อน +ค่อนข้าง +ค่อนข้างจะ +ค่อยไปทาง +ค่อนมาทาง +ค่อย +ค่อยๆ +คะ +ค่ะ +คำ +คิด +คิดว่า +คือ +คุณ +คุณๆ +เคย +เคยๆ +แค่ +แค่จะ +แค่นั้น +แค่นี้ +แค่เพียง +แค่ว่า +แค่ไหน +ใคร +ใคร่ +ใคร่จะ +ง่าย +ง่ายๆ +ไง +จง +จด +จนกระทั่ง +จนกว่า +จนขณะนี้ +จนตลอด +จนถึง +จนทั่ว +จนบัดนี้ +จนเมื่อ +จนแม้ +จนแม้น +จรด +จรดกับ +จริง +จริงจัง +จริงๆ +จริงๆ +จังๆ +จวน +จวนจะ +จวนเจียน +จวบ +จวบกับ +จวบจน +จะ +จ้ะ +จ๊ะ +จะได้ +จัง +จังๆ +จัด +จัดการ +จัดงาน +จัดแจง +จัดตั้ง +จัดทำ +จัดหา +จัดให้ +จับ +จ้า +จ๋า +จาก +จากนั้น +จากนี้ +จากนี้ไป +จำ +จำเป็น +จำพวก +จึง +จึงจะ +จึงเป็น +จู่ๆ +ฉะนั้น +ฉะนี้ +ฉัน +เฉกเช่น +เฉพาะ +เฉย +เฉยๆ +ไฉน +ช่วง +ช่วงก่อน +ช่วงต่อไป +ช่วงถัดไป +ช่วงท้าย +ช่วงที่ +ช่วงนั้น +ช่วงนี้ +ช่วงระหว่าง +ช่วงแรก +ช่วงหน้า +ช่วงหลัง +ช่วงๆ +ช่วย +ช้า +ช้านาน +ชาว +ช้าๆ +เช่น +เช่นก่อน +เช่นกัน +เช่นเคย +เช่นดัง +เช่นดังก่อน +เช่นดังเก่า +เช่นดังที่ +เช่นดังว่า +เช่นเดียวกัน +เช่นเดียวกับ +เช่นใด +เช่นที่ +เช่นที่เคย +เช่นที่ว่า +เช่นนั้น +เช่นนั้นเอง +เช่นนี้ +เช่นเมื่อ +เช่นไร +เชื่อ +เชื่อถือ +เชื่อมั่น +เชื่อว่า +ใช่ +ใช่ไหม +ใช้ +ซะ +ซะก่อน +ซะจน +ซะจนกระทั่ง +ซะจนถึง +ซึ่ง +ซึ่งก็ +ซึ่งก็คือ +ซึ่งกัน +ซึ่งกันและกัน +ซึ่งได้แก่ +ซึ่งๆ +ณ +ด้วย +ด้วยกัน +ด้วยเช่นกัน +ด้วยที่ +ด้วยเพราะ +ด้วยว่า +ด้วยเหตุที่ +ด้วยเหตุนั้น +ด้วยเหตุนี้ +ด้วยเหตุเพราะ +ด้วยเหตุว่า +ด้วยเหมือนกัน +ดัง +ดั่ง +ดังกล่าว +ดังกับ +ดั่งกับ +ดังกับว่า +ดั่งกับว่า +ดังเก่า +ดั่งเก่า +ดังเคย +ดั่งเคย +ต่าง +ต่างก็ +ต่างหาก +ต่างๆ +ตาม +ตามด้วย +ตามแต่ +ตามที่ +ตามๆ +เต็มไปด้วย +เต็มไปหมด +เต็มๆ +แต่ +แต่ก็ +แต่ก่อน +แต่จะ +แต่เดิม +แต่ต้อง +แต่ถ้า +แต่ทว่า +แต่ที่ +แต่นั้น +แต่เพียง +แต่เมื่อ +แต่ไร +แต่ละ +แต่ว่า +แต่ไหน +แต่อย่างใด +โต +โตๆ +ใต้ +ถ้า +ถ้าจะ +ถ้าหาก +ถึง +ถึงแก่ +ถึงจะ +ถึงบัดนั้น +ถึงบัดนี้ +ถึงเมื่อ +ถึงเมื่อใด +ถึงเมื่อไร +ถึงแม้ +ถึงแม้จะ +ถึงแม้ว่า +ถึงอย่างไร +ถือ +ถือว่า +ถูก +ถูกต้อง +ถูกๆ +เถอะ +เถิด +ทรง +ทว่า +ทั้ง +ทั้งคน +ทั้งตัว +ทั้งที่ +ทั้งนั้น +ทั้งนั้นด้วย +ทั้งนั้นเพราะ +ทั้งนี้ +ทั้งปวง +ทั้งเป็น +ทั้งมวล +ทั้งสิ้น +ทั้งหมด +ทั้งหลาย +ทั้งๆ +ทั้งๆ +ที่ +ทัน +ทันใดนั้น +ทันที +ทันทีทันใด +ทั่ว +ท +าไม +ท +าไร +ท +าให้ +ท +าๆ +ที +ที่ +ที่จริง +ที่ซึ่ง +ทีเดียว +ทีใด +ที่ใด +ที่ได้ +ทีเถอะ +ที่แท้ +ที่แท้จริง +ที่นั้น +ที่นี้ +ทีไร +ทีละ +ที่ละ +ที่แล้ว +ที่ว่า +ที่สุด +ที่แห่งนั้น +ที่ไหน +ทีๆ +ที่ๆ +ทุก +ทุกคน +ทุกครั้ง +ทุกครา +ทุกคราว +ทุกชิ้น +ทุกตัว +ทุกทาง +ทุกที +ทุกที่ +ทุกเมื่อ +ทุกวัน +ทุกวันนี้ +ทุกสิ่ง +ทุกหน +ทุกแห่ง +ทุกอย่าง +ทุกอัน +ทุกๆ +เท่า +เท่ากัน +เท่ากับ +เท่าใด +เท่าที่ +เท่านั้น +เท่านี้ +เท่าไร +เท่าไหร่ +แท้ +แท้จริง +เธอ +นอก +นอกจาก +นอกจากที่ +นอกจากนั้น +นอกจากนี้ +นอกจากว่า +นอกนั้น +นอกเหนือ +น้อย +น้อยกว่า +น้อยๆ +นะ +น่ะ +นัก +นั่น +นั้นไว +นับจากนั้น +นับจากนี้ +นับแต่นี้ +น่า +นาง +นางสาว +น่าจะ +นาน +นานๆ +นาย +นำ +นำพา +นำมา +นิด +นิดหน่อย +นิดๆ +นี่ +นี้ +นี่ไง +นี่นา +นี่แน่ะ +นี่แหละ +นี้แหล่ +นี่เอง +นี้เอง +นู่น +นู้น +เน้น +เนี่ย +เนี่ยเอง +ใน +ในช่วง +ในที่ +ในเมื่อ +ในระหว่าง +บน +บอก +บอกแล้ว +บอกว่า +บ่อย +บ่อยกว่า +บ่อยครั้ง +บ่อยๆ +บัดดล +บัดเดี๋ยวนี้ +บัดนั้น +บัดนี้ +บาง +บ้าง +บางกว่า +บางขณะ +บางครั้ง +บางครา +บางคราว +บางที +บางที่ +บางแห่ง +บางๆ +แบบ +ปฏิบัติ +ประกอบ +ประการ +ประการฉะนี้ +ประการใด +ประการหนึ่ง +ประมาณ +ประสบ +ปรับ +ปรากฏ +ปรากฏว่า +ปัจจุบัน +ปิด +เป็น +เป็นด้วย +เป็นดัง +เป็นต้น +เป็นแต่ +เป็นเพื่อ +เป็นอัน +เป็นอันมาก +เป็นอาทิ +เปลี่ยน +เปลี่ยนแปลง +ไป +ผ่าน +ผ่านๆ +ผิด +ผิดๆ +ผู้ +ผู้ใด +เผื่อ +เผื่อจะ +เผื่อที่ +เผื่อว่า +ฝ่าย +ฝ่ายใด +พบ +พบว่า +พยายาม +พร้อม +พร้อมกัน +พร้อมกับ +พร้อมด้วย +พร้อมทั้ง +พร้อมที่ +พร้อมเพียง +พวก +พวกกัน +พวกกู +พวกแก +พวกเขา +พวกคุณ +พวกฉัน +พวกท่าน +พวกที่ +พวกเธอ +พวกนั้น +พวกนี้ +พวกนู้น +พวกโน้น +พวกมัน +พวกมึง +พอ +พอกัน +พอควร +พอจะ +พอดี +พอตัว +พอที +พอที่ +พอเพียง +พอแล้ว +พอสม +พอสมควร +พอเหมาะ +พอๆ +พา +พึง +พึ่ง +พื้นๆ +พูด +เพราะ +เพราะฉะนั้น +เพราะว่า +เพิ่ง +เพิ่งจะ +เพิ่ม +เพิ่มเติม +เพียง +เพียงแค่ +เพียงใด +เพียงแต่ +เพียงพอ +เพียงเพราะ +เพียงเพื่อ +เพียงไหน +เพื่อ +เพื่อที่ +เพื่อว่า +เพื่อให้ +ภาค +ภาย +ภายใต้ +ภายนอก +ภายหลัง +มอง +มองว่า +มัก +มักจะ +มัน +มั๊ย +มา +มาก +มากกว่า +มากมาย +มิ +มิฉะนั้น +มิใช่ +มิได้ +มี +มีแต่ +มึง +มุ่ง +มุ่งเน้น +มุ่งหมาย +เมื่อ +เมื่อก่อน +เมื่อครั้ง +เมื่อครั้งก่อน +เมื่อคราวก่อน +เมื่อคราวที่ +เมื่อคราว +เมื่อคืน +เมื่อเช้า +เมื่อใด +เมื่อนั้น +เมื่อนี้ +เมื่อเย็น +เมื่อไร +เมื่อวันวาน +เมื่อวาน +เมื่อไหร่ +แม้ +แม้กระทั่ง +แม้แต่ +แม้นว่า +แม้ว่า +ไม่ +ไม่ค่อย +ไม่ค่อยจะ +ไม่ค่อยเป็น +ไม่ใช่ +ไม่เป็นไร +ไม่ว่า +ยก +ยกให้ +ยอม +ยอมรับ +ย่อม +ย่อย +ยัง +ยังคง +ยังงั้น +ยังงี้ +ยังโง้น +ยังไง +ยังจะ +ยังแต่ +ยาก +ยาว +ยาวนาน +ยิ่ง +ยิ่งกว่า +ยิ่งขึ้น +ยิ่งขึ้นไป +ยิ่งจน +ยิ่งจะ +ยิ่งนัก +ยิ่งเมื่อ +ยิ่งแล้ว +ยิ่งใหญ่ +เยอะ +เยอะแยะ +แยะ +รวด +รวดเร็ว +รวม +ร่วม +รวมกัน +ร่วมกัน +รวมด้วย +ร่วมด้วย +รวมถึง +รวมทั้ง +ระยะ +ระหว่าง +รับ +รึ +รือ +รือว่า +เร็ว +เร็วๆ +เรา +เราๆ +เริ่ม +เรียก +เรียบ +เรื่อย +เรื่อยๆ +ไร +ล้วน +ล้วนจน +ล้วนแต่ +ละ +ล่าสุด +เล็ก +เล็กน้อย +เล็กๆ +เลย +เล่าว่า +แล้ว +แล้วกัน +แล้วแต่ +แล้วเสร็จ +วันใด +วันนั้น +วันนี้ +วันไหน +สบาย +สมัย +สมัยก่อน +สมัยนั้น +สมัยนี้ +สมัยโน้น +ส่วน +ส่วนเกิน +ส่วนด้อย +ส่วนดี +ส่วนใด +ส่วนที่ +ส่วนน้อย +ส่วนนั้น +ส่วนมาก +ส่วนใหญ่ +สั้น +สั้นๆ +สามารถ +สำคัญ +สิ่ง +สิ่งใด +สิ่งนั้น +สิ่งนี้ +สิ่งไหน +สิ้น +สุด +เสร็จ +เสร็จแล้ว +เสียจน +เสียด้วย +เสียนี่ +เสียแล้ว +แสดง +แสดงว่า +หน +หนอ +หนอย +หน่อย +หมด +หมดกัน +หมดสิ้น +หรือไง +หรือเปล่า +หรือไม่ +หรือยัง +หรือไร +หลังจาก +หาก +หากแม้ +หากแม้น +หากแม้นว่า +หากว่า +หาความ +หาใช่ +หารือ +เหตุ +เหตุผล +เหตุนั้น +เหตุนี้ +เหตุไร +เห็นแก่ +เห็นควร +เห็นจะ +เห็นว่า +เหลือ +เหลือเกิน +เหล่า +เหล่านั้น +เหล่านี้ +แห่ง +แห่งใด +แห่งนั้น +แห่งนี้ +แห่งโน้น +แห่งไหน +แหละ +ให้ +ให้แก่ +ใหญ่ +ใหญ่โต +ไหน +ไหนๆ +อดีต +อนึ่ง +อยาก +อย่าง +อย่างเช่น +อย่างดี +อย่างเดียว +อย่างใด +อย่างที่ +อย่างน้อย +อย่างนั้น +อย่างนี้ +อย่างโน้น +อย่างมาก +อย่างยิ่ง +อย่างไร +อย่างไรก็ +อย่างไรก็ได้ +อย่างไรเสีย +อย่างละ +อย่างหนึ่ง +อย่างไหน +อย่างๆ +อัน +อันจะ +อันใด +อันได้แก่ +อันที่ +อันที่จริง +อันที่จะ +อันเนื่องมาจาก +อันละ +อันไหน +อันๆ +อาจ +อาจจะ +อาจเป็น +อาจเป็นด้วย +อีก +อื่น +อื่นๆ +เอง +เอ็ง +เอา +ฯ +ฯล +ฯลฯ \ No newline at end of file From 3904f31015a87bd017f7ec49e1e027a4d396727a Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 13 Jun 2017 20:41:10 +0700 Subject: [PATCH 12/71] fix mm --- pythainlp/tokenize/mm.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pythainlp/tokenize/mm.py b/pythainlp/tokenize/mm.py index a9ee4bedc..ebe765be4 100644 --- a/pythainlp/tokenize/mm.py +++ b/pythainlp/tokenize/mm.py @@ -45,7 +45,7 @@ def determine(self, word): return False if self.removeNonCharacter: - match = re.search(u"[0-9A-Za-z\u0E00-\u0E7F]+", word) + match = re.search(u"[0-9A-Za-z\u0E00-\u0E7F]+", word,re.U) if not match: return False @@ -58,7 +58,7 @@ def searchTrie(self, word): self.onNegation = False # check latin words - match = re.search(u"[A-Za-z\d]*", word) + match = re.search(u"[A-Za-z\d]*", word,re.U) if match.group(0): if not self.caseSensitive: return match.group(0).lower() @@ -66,7 +66,7 @@ def searchTrie(self, word): return match.group(0) # check number - match = re.search(u"[\d]*", word) + match = re.search(u"[\d]*", word,re.U) if match.group(0): return match.group(0) @@ -89,7 +89,7 @@ def searchTrie(self, word): if maxData: try: # Special check for case like ๆ - if word[len(maxData)] == u'ๆ': + if word[len(maxData)] == 'ๆ': return word[0:(len(maxData) + 1)] else: return maxData @@ -150,7 +150,7 @@ def segment(self, c): lastresult = [] for x in range(self.ngram[0], self.ngram[1]+1): for r in self.find_ngrams(result, x): - match = re.search(u"[A-Za-z\d]+", ''.join(r)) + match = re.search(u"[A-Za-z\d]+", ''.join(r),re.U) if not match: lastresult.append(''.join(r)) else: From b56ecccd5cb5e9d9b8a1382e969ab7403e4bd6c3 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 13 Jun 2017 21:56:55 +0700 Subject: [PATCH 13/71] fix bug https://github.com/wannaphongcom/pythainlp/issues/24 --- pythainlp/tokenize/mm.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pythainlp/tokenize/mm.py b/pythainlp/tokenize/mm.py index ebe765be4..763fecd6b 100644 --- a/pythainlp/tokenize/mm.py +++ b/pythainlp/tokenize/mm.py @@ -13,7 +13,7 @@ import re from .thai import data # load dictionary from pythainlp.corpus import stopwords # load stopwords -import marisa_trie +#import marisa_trie class wordcut(object): def __init__(self, removeRepeat=True, stopDictionary="", removeSpaces=True, minLength=1, stopNumber=False, removeNonCharacter=False, caseSensitive=True, ngram=(1,1), negation=False): @@ -23,7 +23,7 @@ def __init__(self, removeRepeat=True, stopDictionary="", removeSpaces=True, minL self.stopword = False self.stopdict = stopwords.words('thai') - self.trie = marisa_trie.Trie(d) + self.trie = d self.removeRepeat = removeRepeat self.stopNumber = stopNumber self.removeSpaces = removeSpaces @@ -160,5 +160,5 @@ def segment(self, c): lastresult.append(' '.join(r)) return lastresult def segment(text): - pt = wordcut(stopNumber=False, removeNonCharacter=True, caseSensitive=False, negation=True, removeRepeat=True) + pt = wordcut(stopNumber=False, removeNonCharacter=True, caseSensitive=False,removeRepeat=True) return pt.segment(text) From 7389a5738ecb9cda010c10712ab3d8ede30f9318 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 13 Jun 2017 21:59:11 +0700 Subject: [PATCH 14/71] del old file --- CONTRIBUTING.rst | 114 ----------------------------------------------- appveyor.yml | 89 ------------------------------------ mkdocs.yml | 8 ---- 3 files changed, 211 deletions(-) delete mode 100644 CONTRIBUTING.rst delete mode 100644 appveyor.yml delete mode 100644 mkdocs.yml diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index 5ecdb094c..000000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,114 +0,0 @@ -.. highlight:: shell - -============ -Contributing -============ - -Contributions are welcome, and they are greatly appreciated! Every -little bit helps, and credit will always be given. - -You can contribute in many ways: - -Types of Contributions ----------------------- - -Report Bugs -~~~~~~~~~~~ - -Report bugs at https://github.com/wannaphongcom/pythainlp/issues. - -If you are reporting a bug, please include: - -* Your operating system name and version. -* Any details about your local setup that might be helpful in troubleshooting. -* Detailed steps to reproduce the bug. - -Fix Bugs -~~~~~~~~ - -Look through the GitHub issues for bugs. Anything tagged with "bug" -and "help wanted" is open to whoever wants to implement it. - -Implement Features -~~~~~~~~~~~~~~~~~~ - -Look through the GitHub issues for features. Anything tagged with "enhancement" -and "help wanted" is open to whoever wants to implement it. - -Write Documentation -~~~~~~~~~~~~~~~~~~~ - -PyThai-NLP could always use more documentation, whether as part of the -official PyThai-NLP docs, in docstrings, or even on the web in blog posts, -articles, and such. - -Submit Feedback -~~~~~~~~~~~~~~~ - -The best way to send feedback is to file an issue at https://github.com/wannaphongcom/pythainlp/issues. - -If you are proposing a feature: - -* Explain in detail how it would work. -* Keep the scope as narrow as possible, to make it easier to implement. -* Remember that this is a volunteer-driven project, and that contributions - are welcome :) - -Get Started! ------------- - -Ready to contribute? Here's how to set up `pythainlp` for local development. - -1. Fork the `pythainlp` repo on GitHub. -2. Clone your fork locally:: - - $ git clone git@github.com:your_name_here/pythainlp.git - -3. Install your local copy into a virtualenv. Assuming you have virtualenvwrapper installed, this is how you set up your fork for local development:: - - $ mkvirtualenv pythainlp - $ cd pythainlp/ - $ python setup.py develop - -4. Create a branch for local development:: - - $ git checkout -b name-of-your-bugfix-or-feature - - Now you can make your changes locally. - -5. When you're done making changes, check that your changes pass flake8 and the tests, including testing other Python versions with tox:: - - $ flake8 pythainlp tests - $ python setup.py test or py.test - $ tox - - To get flake8 and tox, just pip install them into your virtualenv. - -6. Commit your changes and push your branch to GitHub:: - - $ git add . - $ git commit -m "Your detailed description of your changes." - $ git push origin name-of-your-bugfix-or-feature - -7. Submit a pull request through the GitHub website. - -Pull Request Guidelines ------------------------ - -Before you submit a pull request, check that it meets these guidelines: - -1. The pull request should include tests. -2. If the pull request adds functionality, the docs should be updated. Put - your new functionality into a function with a docstring, and add the - feature to the list in README.rst. -3. The pull request should work for Python 2.6, 2.7, 3.3, 3.4 and 3.5, and for PyPy. Check - https://travis-ci.org/wannaphongcom/pythainlp/pull_requests - and make sure that the tests pass for all supported Python versions. - -Tips ----- - -To run a subset of tests:: - - - $ python -m unittest tests.test_pythainlp diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 1d0606287..000000000 --- a/appveyor.yml +++ /dev/null @@ -1,89 +0,0 @@ -environment: - global: - # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the - # /E:ON and /V:ON options are not enabled in the batch script intepreter - # See: http://stackoverflow.com/a/13751649/163740 - CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_env.cmd" - - matrix: - # Pre-installed Python versions, which Appveyor may upgrade to - # a later point release. - # See: http://www.appveyor.com/docs/installed-software#python - - - PYTHON: "C:\\Python34" - PYTHON_VERSION: "3.4.x" # currently 3.4.3 - PYTHON_ARCH: "32" - - - PYTHON: "C:\\Python34-x64" - PYTHON_VERSION: "3.4.x" # currently 3.4.3 - PYTHON_ARCH: "64" - - - PYTHON: "C:\\Python35" - PYTHON_VERSION: "3.5.x" # currently 3.4.3 - PYTHON_ARCH: "32" - - - PYTHON: "C:\\Python35-x64" - PYTHON_VERSION: "3.5.x" # currently 3.4.3 - PYTHON_ARCH: "64" - -install: - # If there is a newer build queued for the same PR, cancel this one. - # The AppVeyor 'rollout builds' option is supposed to serve the same - # purpose but it is problematic because it tends to cancel builds pushed - # directly to master instead of just PR builds (or the converse). - # credits: JuliaLang developers. - - ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod ` - https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | ` - Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { ` - throw "There are newer queued builds for this pull request, failing early." } - - ECHO "Filesystem root:" - - ps: "ls \"C:/\"" - - - ECHO "Installed SDKs:" - - ps: "ls \"C:/Program Files/Microsoft SDKs/Windows\"" - - # Install Python (from the official .msi of http://python.org) and pip when - # not already installed. - - ps: if (-not(Test-Path($env:PYTHON))) { & appveyor\install.ps1 } - - # Prepend newly installed Python to the PATH of this build (this cannot be - # done from inside the powershell script as it would require to restart - # the parent CMD process). - - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%" - - # Check that we have the expected version and architecture for Python - - "python --version" - - "python -c \"import struct; print(struct.calcsize('P') * 8)\"" - - # Upgrade to the latest version of pip to avoid it displaying warnings - # about it being out of date. - - "pip install --disable-pip-version-check --user --upgrade pip" - - # Install the build dependencies of the project. If some dependencies contain - # compiled extensions and are not provided as pre-built wheel packages, - # pip will build them from source using the MSVC compiler matching the - # target Python version and architecture - - "%CMD_IN_ENV% pip install -r dev-requirements.txt" - -build_script: - # Build the compiled extension - - "%CMD_IN_ENV% python setup.py build" - -test_script: - # Run the project tests - - "%CMD_IN_ENV% python setup.py nosetests" - -after_test: - # If tests are successful, create binary packages for the project. - - "%CMD_IN_ENV% python setup.py bdist_wheel" - - "%CMD_IN_ENV% python setup.py bdist_wininst" - - "%CMD_IN_ENV% python setup.py bdist_msi" - - ps: "ls dist" - -artifacts: - # Archive the generated packages in the ci.appveyor.com build report. - - path: dist\* - -#on_success: -# - TODO: upload the content of dist/*.whl to a public wheelhouse -# diff --git a/mkdocs.yml b/mkdocs.yml deleted file mode 100644 index 2e032ab23..000000000 --- a/mkdocs.yml +++ /dev/null @@ -1,8 +0,0 @@ -site_name: PyThaiNLP -theme: readthedocs -pages: -- Home: index.md -- Install: install.md -- Docs: docs.md -- License: license.md -- About: about.md \ No newline at end of file From 5320308289d10869ab9879dcf665fa3e117f8bb9 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 13 Jun 2017 22:07:33 +0700 Subject: [PATCH 15/71] fix mm --- pythainlp/tokenize/mm.py | 90 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 89 insertions(+), 1 deletion(-) diff --git a/pythainlp/tokenize/mm.py b/pythainlp/tokenize/mm.py index 763fecd6b..1e79f2cf9 100644 --- a/pythainlp/tokenize/mm.py +++ b/pythainlp/tokenize/mm.py @@ -159,6 +159,94 @@ def segment(self, c): else: lastresult.append(' '.join(r)) return lastresult +def mergelistlen(listdata,lennum): + i=0 + listlen=len(listdata) + while i(listlen-1) or i+1==listlen: + ''' + ถ้า i เกินความยาว list ให้ออกจากการลูป + ''' + break + elif re.search(r'[0-9]',listdata[i]): + ''' + ถ้าหาก listdata[i] เป็นตัวเลขให้ข้ามไป + ''' + pass + elif re.search(r'[ะา]',listdata[i]) and (len(listdata[i])==lennum and len(listdata[i+1])==lennum): + ''' + ถ้าหาก listdata[i] คือ ะ/า ซึ่งเปนสระที่ไว้ข้างหลังได้เท่านั้น และ listdata[i] กับ listdata[i+1] ยาวเท่า lennum + จึงนำ listdata[i] ไปรวมกับ listdata[i-1] แล้วลบ listdata[i] ออก + ''' + listdata[i-1]+=listdata[i] + del listdata[i] + i-=1 + elif re.search(r'[ก-ฮ]',listdata[i]) and re.search(r'[0-9]',listdata[i+1]): + ''' + กันปัญหา ก-ฮ ตัวต่อมาเป็น 0-9 มีความยาวเท่ากัน ให้ ก-ฮ ไปรวมกับตัวก่อนหน้า + ''' + listdata[i-1]+=listdata[i] + del listdata[i] + i-=1 + elif len(listdata[i])==lennum and len(listdata[i+1])==lennum: + ''' + ถ้าหาก list มีความยาวเท่ากันอยู่ติดกัน + ''' + #print(listdata,'99') + T=True + num=1 + while T==True: + if (i+num)>=listlen: + ii=i + num2=1 + TT=True + while TT==True: + if (i+num2)<=(listlen-1): + listdata[i]+=listdata[i+num2] + num2+=1 + elif (i+num2)>(listlen-1): + num2-=1 + TT=False + TT=True + while TT==True: + if (i+num2) != i: + del listdata[i+num2] + num2-=1 + else: + TT=False + T=False + elif len(listdata[i+(num-1)])!=len(listdata[i+num]): #and re.search(r'[0-9]',listdata[i+(num-1)])==False:# and isThai(listdata[i+(num-1)])==True: + ii=1+i + while ii<(i+num) and ii<(len(listdata)-1): + listdata[i]+=listdata[ii] + ii+=1 + ii=i+num-1 + while ii>i: + del listdata[ii] + ii-=1 + T=False + num+=1 + del T,ii + elif len(listdata[i])==lennum and len(listdata[i+1])!=lennum: + ''' + ในกรณีที่ list ความยาวที่กำหนด แต่ตัวต่อไปยาวไม่เท่า ให้ยุบรวมกัน + ''' + if re.search(r'[เแโใไ]',listdata[i]): + ''' + ถ้าหากเป็นสระต้นคำ ให้รวมกัน + ''' + listdata[i]+=listdata[i+1] + del listdata[i+1] + elif re.search(r'[ก-ฮ]',listdata[i]) or re.search(r'[ะา]',listdata[i]): + ''' + หากเป็นแค่พยัญชนะให้รวมกับตัวหลัง + ''' + listdata[i-1]+=listdata[i] + del listdata[i] + i-=1 + listlen=len(listdata) + i+=1 + return listdata def segment(text): pt = wordcut(stopNumber=False, removeNonCharacter=True, caseSensitive=False,removeRepeat=True) - return pt.segment(text) + return mergelistlen(pt.segment(text),1) From e9159a26a6756a4bc1d0259f22683bcd18e5cbc1 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 20 Jun 2017 00:27:02 +0700 Subject: [PATCH 16/71] =?UTF-8?q?mm=20=E0=B9=80=E0=B8=9B=E0=B8=A5=E0=B8=B5?= =?UTF-8?q?=E0=B9=88=E0=B8=A2=E0=B8=99=E0=B9=84=E0=B8=9B=E0=B9=83=E0=B8=8A?= =?UTF-8?q?=E0=B9=89=20newdict?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pythainlp/tokenize/mm.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pythainlp/tokenize/mm.py b/pythainlp/tokenize/mm.py index 1e79f2cf9..8d6175254 100644 --- a/pythainlp/tokenize/mm.py +++ b/pythainlp/tokenize/mm.py @@ -11,13 +11,13 @@ from __future__ import print_function from six.moves import range,zip import re -from .thai import data # load dictionary +from .thai import newdata # load dictionary from pythainlp.corpus import stopwords # load stopwords #import marisa_trie class wordcut(object): def __init__(self, removeRepeat=True, stopDictionary="", removeSpaces=True, minLength=1, stopNumber=False, removeNonCharacter=False, caseSensitive=True, ngram=(1,1), negation=False): - d = data() # load dictionary + d = newdata() # load dictionary # load negation listdir self.negationDict = ['ไม่','แต่'] self.stopword = False From 880c47853217013c50e238a468c642127120cf41 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 20 Jun 2017 15:52:27 +0700 Subject: [PATCH 17/71] add tcc and etcc --- pythainlp/tokenize/etcc.py | 54 ++++++++++++++++++++++++++++++++++++++ pythainlp/tokenize/tcc.py | 40 ++++++++++++++++++++++++++++ 2 files changed, 94 insertions(+) create mode 100644 pythainlp/tokenize/etcc.py create mode 100644 pythainlp/tokenize/tcc.py diff --git a/pythainlp/tokenize/etcc.py b/pythainlp/tokenize/etcc.py new file mode 100644 index 000000000..5c76ce120 --- /dev/null +++ b/pythainlp/tokenize/etcc.py @@ -0,0 +1,54 @@ +''' +โปรแกรม ETCC ใน Python + +พัฒนาโดย นาย วรรณพงษ์ ภัททิยไพบูลย์ + +19 มิ.ย. 2560 + +วิธีใช้งาน +etcc(คำ) +คืนค่า โดยมี / แบ่งกลุ่มคำ +''' +import re +C=['ก','ข','ฃ','ค','ฅ','ฆ','ง','จ','ฉ','ช','ฌ','ซ','ศ','ษ','ส','ญ','ฎ','ฑ','ด','ฏ','ต','ฐ','ฑ','ฒ','ถ','ท','ธ','ณ','น','บ','ป','ผ','พ','ภ','ฝ','ฟ','ม','ย','ร','ล','ฬ','ว','ห','ฮ'] +UV=['็','ี','ื','ิ'] +UV1=['ั','ี'] +LV=['ุ','ู'] +c='['+''.join(C)+']' +uv2='['+''.join(['ั','ื'])+']' +def etcc(text): + if (re.search('[เแ]'+c+'['+''.join(UV)+']'+'\w',text,re.U)): + search=re.findall('[เแ]'+c+'['+''.join(UV)+']'+'\w',text,re.U) + for i in search: + text=re.sub(i, '/'+i+'/', text) + if (re.search(c+'['+''.join(UV1)+']'+c+c+'ุ'+'์',text,re.U)): + search=re.findall(c+'['+''.join(UV1)+']'+c+c+'ุ'+'์',text,re.U) + for i in search: + text=re.sub(i, '//'+i+'/', text) + if (re.search(c+uv2+c,text,re.U)): + search=re.findall(c+uv2+c,text,re.U) + for i in search: + text=re.sub(i, '/'+i+'/', text) + re.sub('//','/',text) + if (re.search('เ'+c+'า'+'ะ',text,re.U)): + search=re.findall('เ'+c+'า'+'ะ',text,re.U) + for i in search: + text=re.sub(i, '/'+i+'/', text) + if (re.search('เ'+'\w\w'+'า'+'ะ',text,re.U)): + search=re.findall('เ'+'\w\w'+'า'+'ะ',text,re.U) + for i in search: + text=re.sub(i, '/'+i+'/', text) + text=re.sub('//','/',text) + if (re.search(c+'['+''.join(UV1)+']'+c+c+'์',text,re.U)): + search=re.findall(c+'['+''.join(UV1)+']'+c+c+'์',text,re.U) + for i in search: + text=re.sub(i, '/'+i+'/', text) + if (re.search('/'+c+''.join(['ุ', '์'])+'/',text,re.U)): + '''แก้ไขในกรณี พัน/ธุ์''' + search=re.findall('/'+c+''.join(['ุ', '์'])+'/',text,re.U) + for i in search: + ii=re.sub('/','', i) + text=re.sub(i,ii+'/', text) + return re.sub('//','/',text) +if __name__ == '__main__': + print(etcc('พันธุ์เด็กเปียเสือเงินพังมือเพราะเกาะเอาะยีนส์เพราะเรือดีเพราะ')) \ No newline at end of file diff --git a/pythainlp/tokenize/tcc.py b/pythainlp/tokenize/tcc.py new file mode 100644 index 000000000..8ee58cc7a --- /dev/null +++ b/pythainlp/tokenize/tcc.py @@ -0,0 +1,40 @@ +''' +โปรแกรม TCC ใน Python + +พัฒนาโดย นาย วรรณพงษ์ ภัททิยไพบูลย์ + +19 มิ.ย. 2560 + +วิธีใช้งาน +tcc(คำ) +คืนค่า โดยมี / แบ่งกลุ่มคำ +''' +import re +C=['ก','ข','ฃ','ค','ฅ','ฆ','ง','จ','ฉ','ช','ฌ','ซ','ศ','ษ','ส','ญ','ฎ','ฑ','ด','ฏ','ต','ฐ','ฑ','ฒ','ถ','ท','ธ','ณ','น','บ','ป','ผ','พ','ภ','ฝ','ฟ','ม','ย','ร','ล','ฬ','ว','ห','ฮ'] +UV=['ิ','ี','ึ','ื','ั','็','่','้','๊','๋'] +LV=['ุ','ู'] +FV=['เ','แ','โ','ใ','ไ'] +RV=['ะ','า','ำ'] +def rulestcc(r1,r2,data): + rules='['+''.join(r1)+']'+'['+''.join(r2)+']' + if (re.search(rules,data,re.U)): + search=re.findall(rules,data,re.U) + for i in search: + data=re.sub(i, '/'+i+'/', data) + return data +def tcc(text): + ''' + วิธีใช้งาน + tcc(คำ) + คืนค่า โดยมี / แบ่งกลุ่มคำ + ''' + text=rulestcc(C,RV,text) + text=rulestcc(FV,C,text) + text=rulestcc(C,UV,text) + text=rulestcc(C,LV,text) + return re.sub('//','/',text) +if __name__ == '__main__': + print(tcc('แมวกิน')) + print(tcc('ประชาชน')) + print(tcc('ขุด')+'/'+tcc('หลุม')) + print(tcc('ยินดี')) \ No newline at end of file From 7707c192139cbb94bf32a172b97dcc230e2ab44b Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 20 Jun 2017 16:08:10 +0700 Subject: [PATCH 18/71] add docs 1.4 --- README.md | 10 +- docs/pythainlp-1-4-thai.md | 225 +++++++++++++++++++++++++++++++++++++ 2 files changed, 233 insertions(+), 2 deletions(-) create mode 100644 docs/pythainlp-1-4-thai.md diff --git a/README.md b/README.md index bb88fbfa1..6097798ea 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ Homepages :[https://sites.google.com/view/pythainlp/home](https://sites.google.c ประมวลภาษาธรรมชาติภาษาไทยในภาษา Python -Natural language processing หรือ การประมวลภาษาธรรมชาติ โมดูล PyThaiNLP เป็นโมดูลที่ถูกพัฒนาขึ้นเพื่องานวิจัยและพัฒนาการประมวลภาษาธรรมชาติภาษาไทยในภาษา Python +Natural language processing หรือ การประมวลภาษาธรรมชาติ โมดูล PyThaiNLP เป็นโมดูลที่ถูกพัฒนาขึ้นเพื่อพัฒนาการประมวลภาษาธรรมชาติภาษาไทยในภาษา Python และ**มันฟรี (ตลอดไป) เพื่อคนไทยและชาวโลกทุกคน !** + +> เพราะโลกขับเคลื่อนต่อไปด้วยการแบ่งปัน รองรับ Python 3.4 ขึ้นไป @@ -23,6 +25,10 @@ Natural language processing หรือ การประมวลภาษา ### Version 1.4 +### สิ่งใหม่ที่เพิ่มเข้ามาใน PyThaiNLP 1.4 + +- รองรับ Thai Character Clusters (TCC) และ ETCC + ### ความสามารถ - ตัดคำภาษาไทย - ถอดเสียงภาษาไทยเป็น Latin @@ -72,7 +78,7 @@ $ CFLAGS=-I/usr/local/opt/icu4c/include LDFLAGS=-L/usr/local/opt/icu4c/lib pip i # เอกสารการใช้งานเบื้องต้น -อ่านได้ที่ https://github.com/wannaphongcom/pythainlp/blob/master/docs/pythainlp-1-3-thai.md +อ่านได้ที่ https://github.com/wannaphongcom/pythainlp/blob/master/docs/pythainlp-1-4-thai.md ### License diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md new file mode 100644 index 000000000..4cdba99ee --- /dev/null +++ b/docs/pythainlp-1-4-thai.md @@ -0,0 +1,225 @@ +# คู่มือการใช้งาน PyThaiNLP 1.4 + +รองรับเฉพาะ Python 3.4 ขึ้นไปเท่านั้น + +ติดตั้งใช้คำสั่ง + +``` +pip install pythainlp +``` + +**วิธีติดตั้งสำหรับ Windows** + +ให้ทำการติดตั้ง pyicu โดยใช้ไฟล์ .whl จาก [http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyicu](http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyicu) + +หากใช้ python 3.5 64 bit ให้โหลด PyICU‑1.9.7‑cp35‑cp35m‑win_amd64.whl แล้วเปิด cmd ใช้คำสั่ง + +``` +pip install PyICU‑1.9.7‑cp35‑cp35m‑win_amd64.whl +``` + +แล้วจึงใช้ + +``` +pip install pythainlp +``` + +**ติดตั้งบน Mac** + +```sh +$ brew install icu4c --force +$ brew link --force icu4c +$ CFLAGS=-I/usr/local/opt/icu4c/include LDFLAGS=-L/usr/local/opt/icu4c/lib pip install pythainlp +``` + +ข้อมูลเพิ่มเติม [คลิกที่นี้](https://medium.com/data-science-cafe/install-polyglot-on-mac-3c90445abc1f#.rdfrorxjx) + +## API + +### ตัดคำไทย + +สำหรับการตัดคำไทยนั้น ใช้ API ดังต่อไปนี้ + +```python +from pythainlp.tokenize import word_tokenize +word_tokenize(text,engine) +``` +text คือ ข้อความในรูปแบบสตริง str เท่านั้น + +engine คือ ระบบตัดคำไทย ปัจจุบันนี้ PyThaiNLP ได้พัฒนามี 3 engine ให้ใช้งานกันดังนี้ + +1. icu - engine ตัวดั้งเดิมของ PyThaiNLP (ความแม่นยำต่ำ) และเป็นค่าเริ่มต้น +2. dict - เป็นการตัดคำโดยใช้พจานุกรมจาก thaiword.txt ใน corpus (ความแม่นยำปานกลาง) +3. mm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย + +คืนค่าเป็น ''list'' เช่น ['แมว','กิน'] + +**ตัวอย่าง** + +```python +from pythainlp.tokenize import word_tokenize +text='ผมรักคุณนะครับโอเคบ่พวกเราเป็นคนไทยรักภาษาไทยภาษาบ้านเกิด' +a=word_tokenize(text,engine='icu') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอ', 'เค', 'บ่', 'พวก', 'เรา', 'เป็น', 'คน', 'ไทย', 'รัก', 'ภาษา', 'ไทย', 'ภาษา', 'บ้าน', 'เกิด'] +b=word_tokenize(text,engine='dict') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] +c=word_tokenize(text,engine='mm') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] +``` + +### Postaggers ภาษาไทย + +```python +from pythainlp.tag import pos_tag +pos_tag(list,engine='old') +``` + +list คือ list ที่เก็บข้อความหลังผ่านการตัดคำแล้ว + +engine คือ ชุดเครื่องมือในการ postaggers มี 2 ตัวดังนี้ + +1. old เป็น UnigramTagger (ค่าเริ่มต้น) +2. artagger เป็น RDR POS Tagger ละเอียดยิ่งกว่าเดิม รองรับเฉพาะ Python 3 เท่านั้น + +### แปลงข้อความเป็น Latin + +```python +from pythainlp.romanization import romanization +romanization(str) +``` +**ตัวอย่าง** + +```python +from pythainlp.romanization import romanization +romanization("แมว") # 'mæw' +``` + +### เช็คคำผิด * + +*ความสามารถนี้รองรับเฉพาะ Python 3 + +ก่อนใช้งานความสามารถนี้ ให้ทำการติดตั้ง hunspell และ hunspell-th ก่อน + +**วิธีติดตั้ง** สำหรับบน Debian , Ubuntu + +``` +sudo apt-get install hunspell hunspell-th +``` + +บน Mac OS ติดตั้งตามนี้ [http://pankdm.github.io/hunspell.html](http://pankdm.github.io/hunspell.html) + +ให้ใช้ pythainlp.spell ตามตัวอย่างนี้ + +```python +from pythainlp.spell import * +a=spell("สี่เหลียม") +print(a) # ['สี่เหลี่ยม', 'เสียเหลี่ยม', 'เหลี่ยม'] +``` +### pythainlp.number + +```python +from pythainlp.number import * +``` +จัดการกับตัวเลข โดยมีดังนี้ + +- nttn(str) - เป็นการแปลงเลขไทยสู่เลข +- nttt(str) - เลขไทยสู่ข้อความ +- ntnt(str) - เลขสู่เลขไทย +- ntt(str) - เลขสู่ข้อความ +- ttn(str) - ข้อความสู่เลข +- numtowords(float) - อ่านจำนวนตัวเลขภาษาไทย (บาท) รับค่าเป็น ''float'' คืนค่าเป็น 'str' + +### เรียงลำดับข้อมูลภาษาไทยใน List + +```python +from pythainlp.collation import collation +print(collation(['ไก่','ไข่','ก','ฮา'])) # ['ก', 'ไก่', 'ไข่', 'ฮา'] +``` + +รับ list คืนค่า list + +### รับเวลาปัจจุบันเป็นภาษาไทย + +```python +from pythainlp.date import now +now() # '30 พฤษภาคม 2560 18:45:24' +``` +### WordNet ภาษาไทย + +เรียกใช้งาน + +```python +from pythainlp.corpus import wordnet +``` + +### stopword ภาษาไทย + +```python +from pythainlp.corpus import stopwords +stopwords = stopwords.words('thai') +``` + +### หาคำที่มีจำนวนการใช้งานมากที่สุด + +```python +from pythainlp.rank import rank +rank(list) +``` + +คืนค่าออกมาเป็น dict + +**ตัวอย่างการใช้งาน** + +```python +>>> rank(['แมง','แมง','คน']) +Counter({'แมง': 2, 'คน': 1}) +``` + +### แก้ไขปัญหาการพิมพ์ลืมเปลี่ยนภาษา + +```python +from pythainlp.change import * +``` + +มีคำสั่งดังนี้ + +- texttothai(str) แปลงแป้นตัวอักษรภาษาอังกฤษเป็นภาษาไทย +- texttoeng(str) แปลงแป้นตัวอักษรภาษาไทยเป็นภาษาอังกฤษ + +คืนค่าออกมาเป็น str + +### Thai Character Clusters (TCC) + +PyThaiNLP 1.4 รองรับ Thai Character Clusters (TCC) โดยจะแบ่งกลุ่มด้วย / + +**การใช้งาน** + +```python +>>> from pythainlp.tokenize import tcc +>>> tcc.tcc('ประเทศไทย') +'ป/ระ/เท/ศ/ไท/ย' +``` + +### ETCC + +นอกจาก TCC แล้ว PyThaiNLP 1.4 ยังรองรับ ETCC โดยแบ่งกลุ่มด้วย / + +**การใช้งาน** + +```python +>>> from pythainlp.tokenize import etcc +>>> etcc.etcc('คืนความสุข') +'/คืน/ความสุข' +``` + +### Sentiment analysis ภาษาไทย + +ใช้ข้อมูลจาก https://github.com/wannaphongcom/lexicon-thai/tree/master/ข้อความ/ + +```python +from pythainlp.sentiment import sentiment +sentiment(str) +``` + +รับค่า str ส่งออกเป็น pos , neg หรือ neutral + + + +เขียนโดย นาย วรรณพงษ์ ภัททิยไพบูลย์ \ No newline at end of file From fd8dbae403955f2ceb14eefcaf3cc7c46beac118 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 20 Jun 2017 16:27:54 +0700 Subject: [PATCH 19/71] fix pip install --- README.md | 3 ++- pythainlp/sentiment/__init__.py | 12 +++++++++++- pythainlp/tag/__init__.py | 11 ++++++++++- setup.py | 3 --- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 6097798ea..5a780d20f 100644 --- a/README.md +++ b/README.md @@ -28,6 +28,7 @@ Natural language processing หรือ การประมวลภาษา ### สิ่งใหม่ที่เพิ่มเข้ามาใน PyThaiNLP 1.4 - รองรับ Thai Character Clusters (TCC) และ ETCC +- Thai WordNet ตัวใหม่ ### ความสามารถ - ตัดคำภาษาไทย @@ -78,7 +79,7 @@ $ CFLAGS=-I/usr/local/opt/icu4c/include LDFLAGS=-L/usr/local/opt/icu4c/lib pip i # เอกสารการใช้งานเบื้องต้น -อ่านได้ที่ https://github.com/wannaphongcom/pythainlp/blob/master/docs/pythainlp-1-4-thai.md +อ่านได้ที่ https://github.com/wannaphongcom/pythainlp/blob/pythainlp1.4/docs/pythainlp-1-4-thai.md ### License diff --git a/pythainlp/sentiment/__init__.py b/pythainlp/sentiment/__init__.py index c2535f447..1b6559a9a 100644 --- a/pythainlp/sentiment/__init__.py +++ b/pythainlp/sentiment/__init__.py @@ -9,7 +9,17 @@ import pythainlp import os from pythainlp.tokenize import word_tokenize -import dill +try: + import dill +except ImportError: + import pip + pip.main(['install','dill']) + try: + import dill + except ImportError: + print("Error ! using 'pip install dill'") + sys.exit(0) + templates_dir = os.path.join(os.path.dirname(pythainlp.__file__), 'sentiment') def sentiment(text): """ diff --git a/pythainlp/tag/__init__.py b/pythainlp/tag/__init__.py index b83ebdfab..53f426850 100644 --- a/pythainlp/tag/__init__.py +++ b/pythainlp/tag/__init__.py @@ -17,7 +17,16 @@ def pos_tag(text,engine='old'): if sys.version_info < (3,4): sys.exit('Sorry, Python < 3.4 is not supported') def tag(text1): - from artagger import Tagger + try: + from artagger import Tagger + except ImportError: + import pip + pip.main(['install','https://github.com/franziz/artagger/archive/master.zip']) + try: + from artagger import Tagger + except ImportError: + print("Error ! using 'pip install https://github.com/franziz/artagger/archive/master.zip'") + sys.exit(0) tagger = Tagger() words = tagger.tag(' '.join(text1)) totag=[] diff --git a/setup.py b/setup.py index 1bf65a7da..2c227de53 100644 --- a/setup.py +++ b/setup.py @@ -10,9 +10,6 @@ 'marisa_trie', 'langdetect' ] -if sys.version_info >= (3,4): - requirements.append('artagger') - requirements.append('dill') test_requirements = [ # TODO: put package test requirements here From f6b310bbabe45a82224f41ced30fd056ff5930ce Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 20 Jun 2017 16:38:54 +0700 Subject: [PATCH 20/71] add pylexto --- docs/pythainlp-1-4-thai.md | 1 + pythainlp/tokenize/__init__.py | 5 ++++- pythainlp/tokenize/pylexto.py | 16 ++++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 pythainlp/tokenize/pylexto.py diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 4cdba99ee..072ef4185 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -51,6 +51,7 @@ engine คือ ระบบตัดคำไทย ปัจจุบัน 1. icu - engine ตัวดั้งเดิมของ PyThaiNLP (ความแม่นยำต่ำ) และเป็นค่าเริ่มต้น 2. dict - เป็นการตัดคำโดยใช้พจานุกรมจาก thaiword.txt ใน corpus (ความแม่นยำปานกลาง) 3. mm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย +4. pylexto ใช้ LexTo ในการตัดคำ คืนค่าเป็น ''list'' เช่น ['แมว','กิน'] diff --git a/pythainlp/tokenize/__init__.py b/pythainlp/tokenize/__init__.py index f2dae46e1..984094761 100644 --- a/pythainlp/tokenize/__init__.py +++ b/pythainlp/tokenize/__init__.py @@ -4,11 +4,12 @@ def word_tokenize(text,engine='icu'): """ ระบบตัดคำภาษาไทย - word_tokenize(text,engine='icu') + word_tokenize(text,engine='mm') engine มี - icu - dict - mm ใช้ Maximum Matching algorithm + - pylexto ใช้ LexTo ในการตัดคำ """ if engine=='icu': from .pyicu import segment @@ -16,4 +17,6 @@ def word_tokenize(text,engine='icu'): from .dict import segment elif engine=='mm': from .mm import segment + elif engine=='pylexto': + from .pylexto import segment return segment(text) \ No newline at end of file diff --git a/pythainlp/tokenize/pylexto.py b/pythainlp/tokenize/pylexto.py new file mode 100644 index 000000000..92ecb8158 --- /dev/null +++ b/pythainlp/tokenize/pylexto.py @@ -0,0 +1,16 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import,unicode_literals +import sys +try: + from pylexto import LexTo +except ImportError: + import pip + pip.main(['install','https://github.com/wannaphongcom/pylexto/archive/master.zip']) + try: + from pylexto import LexTo + except ImportError: + sys.exit('Error ! using pip install https://github.com/wannaphongcom/pylexto/archive/master.zip') +def segment(text): + lexto = LexTo() + words, types = lexto.tokenize(text) + return words \ No newline at end of file From ee0820c70cd54de97dd5f4683a51c72eca7d6b13 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 20 Jun 2017 16:52:51 +0700 Subject: [PATCH 21/71] update docs --- docs/pythainlp-1-4-thai.md | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 072ef4185..6d69792c8 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -150,6 +150,40 @@ now() # '30 พฤษภาคม 2560 18:45:24' from pythainlp.corpus import wordnet ``` +**การใช้งาน** + +API เหมือนกับ NLTK โดยรองรับ API ดังนี้ + +- wordnet.synsets(word) +- wordnet.synset(name_synsets) +- wordnet.all_lemma_names(pos=None, lang="tha") +- wordnet.all_synsets(pos=None) +- wordnet.langs() +- wordnet.lemmas(word,pos=None,lang="tha") +- wordnet.lemma(name_synsets) +- wordnet.lemma_from_key(key) +- wordnet.path_similarity(synsets1,synsets2) +- wordnet.lch_similarity(synsets1,synsets2) +- wordnet.wup_similarity(synsets1,synsets2) +- wordnet.morphy(form, pos=None) +- wordnet.custom_lemmas(tab_file, lang) + +**ตัวอย่าง** + +```python +>>> from pythainlp.corpus import wordnet +>>> print(wordnet.synsets('หนึ่ง')) +[Synset('one.s.05'), Synset('one.s.04'), Synset('one.s.01'), Synset('one.n.01')] +>>> print(wordnet.synsets('หนึ่ง')[0].lemma_names('tha')) +[] +>>> print(wordnet.synset('one.s.05')) +Synset('one.s.05') +>>> print(wordnet.synset('spy.n.01').lemmas()) +[Lemma('spy.n.01.spy'), Lemma('spy.n.01.undercover_agent')] +>>> print(wordnet.synset('spy.n.01').lemma_names('tha')) +['สปาย', 'สายลับ'] +``` + ### stopword ภาษาไทย ```python From d8fda84c0b9cfeed5e0527e5e12cba1aaacfc41b Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 20 Jun 2017 17:10:51 +0700 Subject: [PATCH 22/71] =?UTF-8?q?add=20-=20=E0=B8=AB=E0=B8=A5=E0=B8=B1?= =?UTF-8?q?=E0=B8=81=E0=B9=80=E0=B8=81=E0=B8=93=E0=B8=91=E0=B9=8C=E0=B8=81?= =?UTF-8?q?=E0=B8=B2=E0=B8=A3=E0=B8=96=E0=B8=AD=E0=B8=94=E0=B8=AD=E0=B8=B1?= =?UTF-8?q?=E0=B8=81=E0=B8=A9=E0=B8=A3=E0=B9=84=E0=B8=97=E0=B8=A2=E0=B9=80?= =?UTF-8?q?=E0=B8=9B=E0=B9=87=E0=B8=99=E0=B8=AD=E0=B8=B1=E0=B8=81=E0=B8=A9?= =?UTF-8?q?=E0=B8=A3=E0=B9=82=E0=B8=A3=E0=B8=A1=E0=B8=B1=E0=B8=99=20?= =?UTF-8?q?=E0=B8=89=E0=B8=9A=E0=B8=B1=E0=B8=9A=E0=B8=A3=E0=B8=B2=E0=B8=8A?= =?UTF-8?q?=E0=B8=9A=E0=B8=B1=E0=B8=93=E0=B8=91=E0=B8=B4=E0=B8=95=E0=B8=A2?= =?UTF-8?q?=E0=B8=AA=E0=B8=96=E0=B8=B2=E0=B8=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 1 + docs/pythainlp-1-4-thai.md | 13 +- pythainlp/romanization/__init__.py | 19 +- pythainlp/romanization/royin.py | 692 ++++++++++++++++++++++++----- pythainlp/tokenize/__init__.py | 2 +- 5 files changed, 611 insertions(+), 116 deletions(-) diff --git a/README.md b/README.md index 5a780d20f..ebfa8d048 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ Natural language processing หรือ การประมวลภาษา - รองรับ Thai Character Clusters (TCC) และ ETCC - Thai WordNet ตัวใหม่ +- เพิ่มหลักเกณฑ์การถอดอักษรไทยเป็นอักษรโรมัน ฉบับราชบัณฑิตยสถาน ### ความสามารถ - ตัดคำภาษาไทย diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 6d69792c8..8b3e4c719 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -83,8 +83,19 @@ engine คือ ชุดเครื่องมือในการ postagge ```python from pythainlp.romanization import romanization -romanization(str) +romanization(str,engine='pyicu') ``` +มี 2 engine ดังนี้ + +- pyicu ส่งค่า Latin +- royin ใช้หลักเกณฑ์การถอดอักษรไทยเป็นอักษรโรมัน ฉบับราชบัณฑิตยสถาน + +data : + +รับค่า ''str'' ข้อความ + +คืนค่าเป็น ''str'' ข้อความ + **ตัวอย่าง** ```python diff --git a/pythainlp/romanization/__init__.py b/pythainlp/romanization/__init__.py index ee26a875a..525bc7e0f 100644 --- a/pythainlp/romanization/__init__.py +++ b/pythainlp/romanization/__init__.py @@ -1,8 +1,17 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import,unicode_literals -import icu # ถอดเสียงภาษาไทยเป็น Latin -def romanization(data): - """เป็นคำสั่ง ถอดเสียงภาษาไทยเป็น Latin รับค่า ''str'' ข้อความ คืนค่าเป็น ''str'' ข้อความ Latin""" - thai2latin = icu.Transliterator.createInstance('Thai-Latin') - return thai2latin.transliterate(data) +def romanization(data,engine='pyicu'): + """เป็นคำสั่ง ถอดเสียงภาษาไทยเป็นอังกฤษ + romanization(data,engine='pyicu') + มี 2 engine ดังนี้ + - pyicu ส่งค่า Latin + - royin ใช้หลักเกณฑ์การถอดอักษรไทยเป็นอักษรโรมัน ฉบับราชบัณฑิตยสถาน + data : + รับค่า ''str'' ข้อความ + คืนค่าเป็น ''str'' ข้อความ""" + if engine=='royin': + from .royin import romanization + elif engine=='pyicu': + from .pyicu import romanization + return romanization(data) diff --git a/pythainlp/romanization/royin.py b/pythainlp/romanization/royin.py index 7cd6270f5..ece15d05d 100644 --- a/pythainlp/romanization/royin.py +++ b/pythainlp/romanization/royin.py @@ -1,114 +1,588 @@ -# ยังไม่สามารถถอดเสียงสระได้ *** -from __future__ import absolute_import -from pythainlp.segment import segment -import re +# -*- coding: utf-8 -*- +from __future__ import absolute_import,division,unicode_literals,print_function +''' +โมดูลถอดเสียงไทยเป็นอังกฤษ -th = u'[ก-ฮ]+' +พัฒนาต่อจาก new-thai.py -p = [['อักษรไทย', 'ต้น', 'ทั่วไป'], - ['ก', 'k', 'k'], - ['ข', 'kh', 'k'], - ['ฃ', 'kh', 'k'], - ['ค', 'kh', 'k'], - ['ฅ', 'kh', 'k'], - ['ฆ', 'kh', 'k'], - ['ง', 'ng', 'ng'], - ['จ', 'ch', 't'], - ['ฉ', 'ch', 't'], - ['ช', 'ch', 't'], - ['ซ', 's', 't'], - ['ฌ', 'ch', 't'], - ['ญ', 'y', 'n'], - ['ฎ', 'd', 't'], - ['ฏ', 't', 't'], - ['ฐ', 'th', 't'], - ['ฑ', 'th', 't'], - ['ฒ', 'th', 't'], - ['ณ', 'n', 'n'], - ['ด', 'd', 't'], - ['ต', 't', 't'], - ['ถ', 'th', 't'], - ['ท', 'th', 't'], - ['ธ', 'th', 't'], - ['น', 'n', 'n'], - ['บ', 'b', 'p'], - ['ป', 'p', 'p'], - ['ผ', 'ph', 'p'], - ['ฝ', 'f', 'p'], - ['พ', 'ph', 'p'], - ['ฟ', 'f', 'p'], - ['ภ', 'ph', 'p'], - ['ม', 'm', 'm'], - ['ย', 'y', ''], - ['ร', 'r', 'n'], - ['ล', 'l', 'n'], - ['ว', 'w', ''], - ['ศ', 's', 't'], - ['ษ', 's', 't'], - ['ส', 's', 't'], - ['ห', 'h', ''], - ['ฬ', 'l', 'n'], - ['อ', '', 'o'], - ['ฮ', 'h', '']] -p2 = dict((x[0], x[2]) for x in p[1:]) -p1 = dict((x[0], x[1]) for x in p[1:]) -d1 = 0 -# p1 อักรต้น -# p2 ทั่วไป -# def sub1(txt) +พัฒนาโดย นาย วรรณพงษ์ ภัททิยไพบูลย์ -tone = ['่','้','๊','๋'] -def delete1(data): - #โค้ดส่วนตัดวรรณยุกต์ออก - for a in tone: - if (re.search(a,data)): - data = re.sub(a,'',data) +เริ่มพัฒนา 20 มิ.ย. 2560 +''' +from pythainlp.tokenize import word_tokenize +from pythainlp.tokenize import tcc +from pythainlp.tokenize import etcc +import re +Consonants = { # พยัญชนะ ต้น สะกด +'ก':['k','k'], +'ข':['kh','k'], +'ฃ':['kh','k'], +'ค':['kh','k'], +'ฅ':['kh','k'], +'ฆ':['kh','k'], +'ง':['ng','ng'], +'จ':['ch','t'], +'ฉ':['ch','t'], +'ช':['ch','t'], +'ซ':['s','t'], +'ฌ':['ch','t'], +'ญ':['y','n'], +'ฎ':['d','t'], +'ฏ':['t','t'], +'ฐ':['th','t'], +'ฑ':['th','t'], #* พยัญชนะต้น เป็น d ได้ +'ฒ':['th','t'], +'ณ':['n','n'], +'ด':['d','t'], +'ต':['t','t'], +'ถ':['th','t'], +'ท':['th','t'], +'ธ':['th','t'], +'น':['n','n'], +'บ':['b','p'], +'ป':['p','p'], +'ผ':['ph','p'], +'ฝ':['f','p'], +'พ':['ph','p'], +'ฟ':['f','p'], +'ภ':['ph','p'], +'ม':['m','m'], +'ย':['y',''], +'ร':['r','n'], +'ล':['l','n'], +'ว':['w',''], +'ศ':['s','t'], +'ษ':['s','t'], +'ส':['s','t'], +'ห':['h',''], +'ฬ':['l','n'], +'ฮ':['h',''] +} +Consonantsthai= u'[กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬฮ]' +def deletetone(data): + #โค้ดส่วนตัดวรรณยุกต์ออก + for tone in ['่','้','๊','๋']: + if (re.search(tone,data)): + data = re.sub(tone,'',data) return data -# ส่วนพยัญชนะ -def consonant(text): - try: - txt = delete1(text) - text = list(txt) - text1 = "" - text1 = p1[text[0]] - #print(len(text)) - #print(text) - if len(txt) == 2: # จัดการแก้ไขการสะกดคำที่มี 2 ตัว โดยการเติม o - text1 += 'o' - for a in txt[1:]: - #a=delete1(a) - if (re.search(th, a, re.U)): - text1 += p2[a] - else: - text1 += a - return text1 - except: - return text - -# ส่วนสระ -def vowel(data): - #พัฒนาอยู่ - #[ก-ฮ]ะ - a=list(data) - word=consonant(a[0]) + 'a' - return word +def romanization(text): + text=deletetone(text) + text1=word_tokenize(text,engine='mm') + textdata=[] + #print(text1) + for text in text1: + a1=etcc.etcc(text) + a2=tcc.tcc(a1) + text=re.sub('//','/',a2) + #print(text) + if re.search(u'เ[\w]'+'/ี'+'ย/ว/',text, re.U): + ''' + จัดการกับ เอียว + ''' + #print('เอียว') + search=re.findall(u'เ[\w]'+'/ี'+'ย/ว',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'iao',text,flags=re.U) + if re.search(u'แ[\w]'+'/็'+'ว',text, re.U): + ''' + จัดการกับ แอ็ว + ''' + #print('แอ็ว') + search=re.findall(u'แ[\w]'+'/็'+'ว',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'aeo',text,flags=re.U) + if re.search(u'แ[\w]/[\w]'+'็/'+'ว',text, re.U): + ''' + จัดการกับ แออ็ว + ''' + #print('แออ็ว') + search=re.findall(u'แ[\w]/[\w]'+'็/'+'ว',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+list(i)[3]+'aeo',text,flags=re.U) + if re.search(u'แ[\w]/'+'ว',text, re.U): + ''' + จัดการกับ แอว + ''' + #print('แอว') + search=re.findall(u'แ[\w]/'+'ว',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'aeo',text,flags=re.U) + if re.search(u'เ[\w]'+'ว',text, re.U): + ''' + จัดการกับ เอว + ''' + #print('เอว') + search=re.findall(u'เ[\w]'+'ว',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'eo',text,flags=re.U) + if re.search(u'เ[\w]/็ว',text, re.U): + ''' + จัดการกับ เอ็ว + ''' + #print('เอ็ว') + search=re.findall(u'เ[\w]/็ว',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'eo',text,flags=re.U) + if re.search(u'เ[\w]ี/ยะ',text, re.U): + ''' + จัดการกับ เอียะ + ''' + #print('เอียะ') + search=re.findall(u'เ[\w]ี/ยะ',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ia',text,flags=re.U) + if re.search(u'เ[\w]ีย',text, re.U): + ''' + จัดการกับ เอีย (1) + ''' + #print('เอีย 1') + search=re.findall(u'เ[\w]ีย',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ia',text,flags=re.U) + if re.search(u'เ[\w]/ีย',text, re.U): + ''' + จัดการกับ เอีย (2) + ''' + #print('เอีย 2') + search=re.findall(u'เ[\w]/ีย',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ia',text,flags=re.U) + if re.search(u'เ[\w]/ือ/ย',text, re.U): + ''' + จัดการกับ เอือย + ''' + #print('เอือย') + search=re.findall(u'เ[\w]/ือ/ย',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ueai',text,flags=re.U) + if re.search(u'เ[\w]/ือ/ะ',text, re.U): + ''' + จัดการกับ เอือ + ''' + #print('เอือ') + search=re.findall(u'เ[\w]/ือ/ะ',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'uea',text,flags=re.U) + if re.search(u'เ[\w]/ือ',text, re.U): + ''' + จัดการกับ เอือ + ''' + #print('เอือ') + search=re.findall(u'เ[\w]/ือ',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'uea',text,flags=re.U) + if re.search(u'โ[\w]/ย',text, re.U): + ''' + จัดการกับ โอย + ''' + #print('โอย') + search=re.findall(u'โ[\w]/ย',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'oi',text,flags=re.U) + if re.search(u'[\w]อย',text, re.U): + ''' + จัดการกับ โอย + ''' + #print('โอย') + search=re.findall(u'[\w]อย',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'oi',text,flags=re.U) + if re.search(u'โ/[\w]ะ/',text, re.U): + ''' + จัดการกับ โอะ + ''' + #print('โอะ') + search=re.findall(u'โ/[\w]ะ/',text, re.U) + for i in search: + text=re.sub(i,list(i)[2]+'o',text,flags=re.U) + if re.search(u'โ[\w]',text, re.U): + ''' + จัดการกับ โอ + ''' + #print('โอ') + search=re.findall(u'โ[\w]',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'o',text,flags=re.U) + if re.search(u'เ/[\w]า/ะ/',text, re.U): + ''' + จัดการกับ เอาะ (1) + ''' + #print('เอาะ 1') + search=re.findall(u'เ/[\w]า/ะ/',text, re.U) + for i in search: + text=re.sub(i,list(i)[2]+'o',text,flags=re.U) + if re.search(u'เ[\w]าะ/',text, re.U): + ''' + จัดการกับ เอาะ (2) + ''' + #print('เอาะ 2') + search=re.findall(u'เ[\w]าะ/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'o',text,flags=re.U) + if re.search(u'อำ',text, re.U): + ''' + จัดการกับ อำ + ''' + #print('อำ') + search=re.findall(u'อำ',text, re.U) + for i in search: + text=re.sub(i,'am',text,flags=re.U) + if re.search(u'อี',text, re.U): + ''' + จัดการกับ อี + ''' + #print('"อี"') + search=re.findall(u'อี',text, re.U) + for i in search: + text=re.sub(i,'i',text,flags=re.U) + if re.search(u'[\w]อ',text, re.U): + ''' + จัดการกับ ออ + ''' + #print('ออ') + search=re.findall(u'[\w]อ',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'o',text,flags=re.U) + if re.search(u'/[\w]ั/ว/ะ',text, re.U): + ''' + จัดการกับ อัวะ + ''' + #print('อัวะ') + search=re.findall(u'/[\w]ั/ว/ะ',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ua',text,flags=re.U) + if re.search(u'/[\w]ั/ว',text, re.U): + ''' + จัดการกับ อัว + ''' + #print('อัว') + search=re.findall(u'/[\w]ั/ว',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ua',text,flags=re.U) -def romanization(txt): - txt = segment(txt) # (','.join(str(x) for x in txt)) # แยกออกมาเป็น list - cc='' - #print(txt) - for b in txt: - cc+=consonant(b) - return cc - # return txt -if __name__ == "__main__": - print(romanization('ตอง') == "tong") - print(romanization('มอง')) - print(romanization('มด')) - print(romanization('พร')) - print(romanization('คน')) - print(romanization('พรม')) #! - #romanization('แมว') - print(vowel("ปะ") == "pa") - print(romanization('ชล')) - print(romanization('ต้น') == "ton") \ No newline at end of file + # ใอ,อัย , อาย + if re.search(u'ใ[\w]/',text, re.U): + ''' + จัดการกับ ใอ + ''' + #print('ใอ') + search=re.findall(u'ใ[\w]/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ai',text,flags=re.U) + if re.search(u'[\w]ั/ย',text, re.U): + ''' + จัดการกับ อัย + ''' + #print('อัย') + search=re.findall(u'[\w]ั/ย',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'ai',text,flags=re.U) + if re.search(u'[\w]า/ย',text, re.U): + ''' + จัดการกับ อาย + ''' + #print('อาย') + search=re.findall(u'[\w]า/ย',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'ai',text,flags=re.U) + #เอา, อาว + if re.search(u'เ/[\w]า/',text, re.U): + ''' + จัดการกับ เอา + ''' + #print('เอา') + search=re.findall(u'เ/[\w]า/',text, re.U) + for i in search: + text=re.sub(i,list(i)[2]+'ao',text,flags=re.U) + if re.search(u'[\w]า/ว',text, re.U): + ''' + จัดการกับ อาว + ''' + #print('อาว') + search=re.findall(u'[\w]า/ว',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'ao',text,flags=re.U) + #อุย + if re.search(u'[\w]ุ/ย',text, re.U): + ''' + จัดการกับ อุย + ''' + #print('อุย') + search=re.findall(u'[\w]ุ/ย',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'ui',text,flags=re.U) + #เอย + if re.search(u'เ[\w]/ย',text, re.U): + ''' + จัดการกับ เอย + ''' + #print('เอย') + search=re.findall(u'เ[\w]/ย',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'oei',text,flags=re.U) + # เออ + if re.search(u'เ[\w]/อ',text, re.U): + ''' + จัดการกับ เออ + ''' + #print('เออ') + search=re.findall(u'เ[\w]/อ',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'oe',text,flags=re.U) + # แอะ, แอ + if re.search(u'แ/[\w]ะ/',text, re.U): + ''' + จัดการกับ แอะ + ''' + #print('แอะ') + search=re.findall(u'แ/[\w]ะ/',text, re.U) + for i in search: + text=re.sub(i,list(i)[2]+'ae',text,flags=re.U) + if re.search(u'/แ[\w]/',text, re.U): + ''' + จัดการกับ แอ + ''' + #print('แอ') + search=re.findall(u'/แ[\w]/',text, re.U) + for i in search: + text=re.sub(i,list(i)[2]+'ae',text,flags=re.U) + # เอะ + if re.search(u'เ/[\w]ะ/',text, re.U): + ''' + จัดการกับ เอะ + ''' + #print('เอะ') + search=re.findall(u'เ/[\w]ะ/',text, re.U) + for i in search: + text=re.sub(i,list(i)[2]+'e',text,flags=re.U) + # อิว + if re.search(u'/[\w]ิ/ว',text, re.U): + ''' + จัดการกับ อิว + ''' + #print('อิว') + search=re.findall(u'/[\w]ิ/ว',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'io',text,flags=re.U) + # อวย + if re.search(u'[\w]วย',text, re.U): + ''' + จัดการกับ อวย + ''' + #print('อวย') + search=re.findall(u'[\w]วย',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'uai',text,flags=re.U) + # -ว- + if re.search(u'[\w]ว[\w]',text, re.U): + ''' + จัดการกับ -ว- + ''' + #print('-ว-') + search=re.findall(u'[\w]ว[\w]',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'ua'+list(i)[2],text,flags=re.U) + # เ–็,เอ + if re.search(u'เ[\w]/'+'็',text, re.U): + ''' + จัดการกับ เ–็ + ''' + #print('เ–็') + search=re.findall(u'เ[\w]/'+'็',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'e',text,flags=re.U) + if re.search(u'เ[\w]/',text, re.U): + ''' + จัดการกับ เอ + ''' + #print('เอ') + search=re.findall(u'เ[\w]/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'e',text,flags=re.U) + #ไอย + if re.search(u'ไ[\w]/ย',text, re.U): + ''' + จัดการกับ ไอย + ''' + #print('ไอย') + search=re.findall(u'ไ[\w]/ย',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ai',text,flags=re.U) + #ไอ + if re.search(u'ไ[\w]/',text, re.U): + ''' + จัดการกับ ไอ + ''' + #print('ไอ') + search=re.findall(u'ไ[\w]/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ai',text,flags=re.U) + #อะ + if re.search(u'/[\w]ะ/',text, re.U): + ''' + จัดการกับ อะ + ''' + #print('อะ') + search=re.findall(u'/[\w]ะ/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'a',text,flags=re.U) + # –ั + if re.search(u'/[\w]ั/',text, re.U): + ''' + จัดการกับ –ั + ''' + #print('–ั ') + search=re.findall(u'/[\w]ั/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'a',text,flags=re.U) + # รร + """ + if re.search(u'[\w]รร[\w]',text, re.U): + ''' + จัดการกับ -รร- + ''' + #print('-รร- 1') + search=re.findall(u'[\w]รร[\w]',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'a'+list(i)[3],text,flags=re.U) + if re.search(u'[\w]รร',text, re.U): + ''' + จัดการกับ -รร- + ''' + #print('-รร- 2') + search=re.findall(u'[\w]รร',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'an'+'/',text,flags=re.U) + """ + if re.search(u'[\w]รร',text, re.U): + ''' + จัดการกับ -รร- + ''' + #print('-รร- 1') + if len(text)==3: + search=re.findall(u'[\w]รร',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'an',text,flags=re.U) + else: + search=re.findall(u'[\w]รร',text, re.U) + for i in search: + text=re.sub(i,list(i)[0]+'a',text,flags=re.U) + #อา + if re.search(u'อา',text, re.U): + ''' + จัดการกับ อา 1 + ''' + #print('อา 1') + search=re.findall(u'อา',text, re.U) + for i in search: + text=re.sub(i,'a',text,flags=re.U) + if re.search(u'/[\w]า/',text, re.U): + ''' + จัดการกับ อา 2 + ''' + #print('อา 2') + search=re.findall(u'/[\w]า/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'a',text,flags=re.U) + #อำ + if re.search(u'/[\w]ำ/',text, re.U): + ''' + จัดการกับ อำ 1 + ''' + #print('อำ 1') + search=re.findall(u'/[\w]ำ/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'am',text,flags=re.U) + #อิ , อี + if re.search(u'/[\w]ิ/',text, re.U): + ''' + จัดการกับ อิ + ''' + #print('อิ') + search=re.findall(u'/[\w]ิ/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'i'+'/',text,flags=re.U) + if re.search(u'/[\w]ี/',text, re.U): + ''' + จัดการกับ อี + ''' + #print('อี') + search=re.findall(u'/[\w]ี/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'i'+'/',text,flags=re.U) + #อึ , อื + if re.search(u'/[\w]ึ/',text, re.U): + ''' + จัดการกับ อึ + ''' + #print('อึ') + search=re.findall(u'/[\w]ึ/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ue'+'/',text,flags=re.U) + if re.search(u'/[\w]ื/',text, re.U): + ''' + จัดการกับ อื + ''' + #print('อื') + search=re.findall(u'/[\w]ื/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'ue'+'/',text,flags=re.U) + #อุ , อู + if re.search(u'/[\w]ุ/',text, re.U): + ''' + จัดการกับ อุ + ''' + #print('อุ') + search=re.findall(u'/[\w]ุ/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'u'+'/',text,flags=re.U) + if re.search(u'/[\w]ู/',text, re.U): + ''' + จัดการกับ อู + ''' + #print('อู') + search=re.findall(u'/[\w]ู/',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'u'+'/',text,flags=re.U) + if re.search(r'[^กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬฮ]',text, re.U): + ''' + ใช้ในกรณีคำนั้นมีสระด้วย จะได้เอาพยัญชนะตัวแรกไปเทียบ + ''' + d=re.search(Consonantsthai,text,re.U) + text=re.sub(d.group(0),Consonants[d.group(0)][0],text,flags=re.U) + listtext=list(text) + if re.search(Consonantsthai,listtext[0], re.U): + ''' + จัดการกับพยัญชนะต้น + ''' + listtext[0]=Consonants[listtext[0]][0] + two=False + if len(listtext)==2: + if re.search(Consonantsthai,listtext[1], re.U): + ''' + จัดการกับพยัญชนะ 2 ตัว และมีแค่ 2 ตั และมีแค่ 2 ตัวติดกันในคำ + ''' + listtext.append(Consonants[listtext[1]][1]) + listtext[1]='o' + two=True + else: + two=False + i=0 + while i Date: Tue, 20 Jun 2017 17:23:35 +0700 Subject: [PATCH 23/71] update docs --- docs/pythainlp-1-4-thai.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 8b3e4c719..6d6b0ac00 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -1,5 +1,9 @@ # คู่มือการใช้งาน PyThaiNLP 1.4 +Natural language processing หรือ การประมวลภาษาธรรมชาติ โมดูล PyThaiNLP เป็นโมดูลที่ถูกพัฒนาขึ้นเพื่อพัฒนาการประมวลภาษาธรรมชาติภาษาไทยในภาษา Python และ**มันฟรี (ตลอดไป) เพื่อคนไทยและชาวโลกทุกคน !** + +> เพราะโลกขับเคลื่อนต่อไปด้วยการแบ่งปัน + รองรับเฉพาะ Python 3.4 ขึ้นไปเท่านั้น ติดตั้งใช้คำสั่ง From 1fa20bd2ebbc47587d6e45f5cb99856a9ac9db59 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 20 Jun 2017 17:29:36 +0700 Subject: [PATCH 24/71] update docs --- docs/pythainlp-1-4-thai.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 6d6b0ac00..47d6629b9 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -67,6 +67,7 @@ text='ผมรักคุณนะครับโอเคบ่พวกเ a=word_tokenize(text,engine='icu') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอ', 'เค', 'บ่', 'พวก', 'เรา', 'เป็น', 'คน', 'ไทย', 'รัก', 'ภาษา', 'ไทย', 'ภาษา', 'บ้าน', 'เกิด'] b=word_tokenize(text,engine='dict') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] c=word_tokenize(text,engine='mm') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] +d=word_tokenize(text,engine='pylexto') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] ``` ### Postaggers ภาษาไทย From 2ed322841e6b97d7eeff0de3c57fc169830abb20 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 20 Jun 2017 20:23:40 +0700 Subject: [PATCH 25/71] fix royin MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ลบตัวการันต์ออก --- pythainlp/romanization/royin.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pythainlp/romanization/royin.py b/pythainlp/romanization/royin.py index ece15d05d..2dd45754b 100644 --- a/pythainlp/romanization/royin.py +++ b/pythainlp/romanization/royin.py @@ -64,6 +64,10 @@ def deletetone(data): for tone in ['่','้','๊','๋']: if (re.search(tone,data)): data = re.sub(tone,'',data) + if re.search(u'[\w]'+'์',data, re.U): + search=re.findall(u'[\w]'+'์',data, re.U) + for i in search: + data=re.sub(i,'',data,flags=re.U) return data def romanization(text): text=deletetone(text) From 856603103681ad0abcd014d9027d07f4b770e3a9 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 21 Jun 2017 11:34:39 +0700 Subject: [PATCH 26/71] new tcc --- pythainlp/tokenize/tcc.py | 96 +++++++++++++++++++++++++-------------- 1 file changed, 63 insertions(+), 33 deletions(-) diff --git a/pythainlp/tokenize/tcc.py b/pythainlp/tokenize/tcc.py index 8ee58cc7a..59086b0d3 100644 --- a/pythainlp/tokenize/tcc.py +++ b/pythainlp/tokenize/tcc.py @@ -1,38 +1,68 @@ +""" +โปรแกรม TCC ภาษาไทย +เดติด +TCC : Mr.Jakkrit TeCho +grammar : คุณ Wittawat Jitkrittum (https://github.com/wittawatj/jtcc/blob/master/TCC.g) +โค้ด : คุณ Korakot Chaovavanich +""" +import re +pat_list = """\ +เc็c +เcctาะ +เccีtยะ +เccีtย(?=[เ-ไก-ฮ]|$) +เccอะ +เcc็c +เcิc์c +เcิtc +เcีtยะ? +เcืtอะ? +เc[ิีุู]tย(?=[เ-ไก-ฮ]|$) +เctา?ะ? +cัtวะ +c[ัื]tc[ุิะ]? +c[ิุู]์ +c[ะ-ู]t +c็ +ct[ะาำ]? +แc็c +แcc์ +แctะ +แcc็c +แccc์ +โctะ +[เ-ไ]ct +ๆ +ฯลฯ +ฯ +""".replace('c','[ก-ฮ]').replace('t', '[่-๋]?').split() ''' -โปรแกรม TCC ใน Python - -พัฒนาโดย นาย วรรณพงษ์ ภัททิยไพบูลย์ - -19 มิ.ย. 2560 - -วิธีใช้งาน -tcc(คำ) -คืนค่า โดยมี / แบ่งกลุ่มคำ +def tcc(w): + p = 0 # position + while p Date: Wed, 21 Jun 2017 14:21:18 +0700 Subject: [PATCH 27/71] new code --- docs/pythainlp-1-4-thai.md | 14 +- pythainlp/romanization/royin.py | 238 +++++++++++++++----------------- 2 files changed, 122 insertions(+), 130 deletions(-) diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 47d6629b9..097da5697 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -93,7 +93,7 @@ romanization(str,engine='pyicu') มี 2 engine ดังนี้ - pyicu ส่งค่า Latin -- royin ใช้หลักเกณฑ์การถอดอักษรไทยเป็นอักษรโรมัน ฉบับราชบัณฑิตยสถาน +- royin ใช้หลักเกณฑ์การถอดอักษรไทยเป็นอักษรโรมัน ฉบับราชบัณฑิตยสถาน (**หากมีข้อผิดพลาด ให้ใช้คำอ่าน เนื่องจากตัว royin ไม่มีตัวแปลงคำเป็นคำอ่าน**) data : @@ -240,6 +240,14 @@ from pythainlp.change import * PyThaiNLP 1.4 รองรับ Thai Character Clusters (TCC) โดยจะแบ่งกลุ่มด้วย / +เดติด + +TCC : Mr.Jakkrit TeCho + +grammar : คุณ Wittawat Jitkrittum (https://github.com/wittawatj/jtcc/blob/master/TCC.g) + +โค้ด : คุณ Korakot Chaovavanich + **การใช้งาน** ```python @@ -248,9 +256,9 @@ PyThaiNLP 1.4 รองรับ Thai Character Clusters (TCC) โดยจะ 'ป/ระ/เท/ศ/ไท/ย' ``` -### ETCC +### Enhanced Thai Character Cluster (ETCC) -นอกจาก TCC แล้ว PyThaiNLP 1.4 ยังรองรับ ETCC โดยแบ่งกลุ่มด้วย / +นอกจาก TCC แล้ว PyThaiNLP 1.4 ยังรองรับ Enhanced Thai Character Cluster (ETCC) โดยแบ่งกลุ่มด้วย / **การใช้งาน** diff --git a/pythainlp/romanization/royin.py b/pythainlp/romanization/royin.py index 2dd45754b..dd84d7289 100644 --- a/pythainlp/romanization/royin.py +++ b/pythainlp/romanization/royin.py @@ -76,23 +76,23 @@ def romanization(text): #print(text1) for text in text1: a1=etcc.etcc(text) - a2=tcc.tcc(a1) + a2=tcc.tcc(text) text=re.sub('//','/',a2) - #print(text) - if re.search(u'เ[\w]'+'/ี'+'ย/ว/',text, re.U): + if re.search(u'เ[\w]'+'ี'+'ย/ว',text, re.U): ''' จัดการกับ เอียว ''' #print('เอียว') - search=re.findall(u'เ[\w]'+'/ี'+'ย/ว',text, re.U) + search=re.findall(u'เ[\w]'+'ี'+'ย/ว',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'iao',text,flags=re.U) - if re.search(u'แ[\w]'+'/็'+'ว',text, re.U): + + if re.search(u'แ[\w]'+'็'+'ว',text, re.U): ''' จัดการกับ แอ็ว ''' #print('แอ็ว') - search=re.findall(u'แ[\w]'+'/็'+'ว',text, re.U) + search=re.findall(u'แ[\w]'+'็'+'ว',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'aeo',text,flags=re.U) if re.search(u'แ[\w]/[\w]'+'็/'+'ว',text, re.U): @@ -111,28 +111,28 @@ def romanization(text): search=re.findall(u'แ[\w]/'+'ว',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'aeo',text,flags=re.U) - if re.search(u'เ[\w]'+'ว',text, re.U): + if re.search(u'เ[\w]/ว',text, re.U): ''' จัดการกับ เอว ''' #print('เอว') - search=re.findall(u'เ[\w]'+'ว',text, re.U) + search=re.findall(u'เ[\w]/ว',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'eo',text,flags=re.U) - if re.search(u'เ[\w]/็ว',text, re.U): + if re.search(u'เ[\w]็ว',text, re.U): ''' จัดการกับ เอ็ว ''' #print('เอ็ว') - search=re.findall(u'เ[\w]/็ว',text, re.U) + search=re.findall(u'เ[\w]็ว',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'eo',text,flags=re.U) - if re.search(u'เ[\w]ี/ยะ',text, re.U): + if re.search(u'เ[\w]ียะ',text, re.U): ''' จัดการกับ เอียะ ''' #print('เอียะ') - search=re.findall(u'เ[\w]ี/ยะ',text, re.U) + search=re.findall(u'เ[\w]ียะ',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'ia',text,flags=re.U) if re.search(u'เ[\w]ีย',text, re.U): @@ -151,28 +151,28 @@ def romanization(text): search=re.findall(u'เ[\w]/ีย',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'ia',text,flags=re.U) - if re.search(u'เ[\w]/ือ/ย',text, re.U): + if re.search(u'เ[\w]ือ/ย',text, re.U): ''' จัดการกับ เอือย ''' #print('เอือย') - search=re.findall(u'เ[\w]/ือ/ย',text, re.U) + search=re.findall(u'เ[\w]ือ/ย',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'ueai',text,flags=re.U) - if re.search(u'เ[\w]/ือ/ะ',text, re.U): + if re.search(u'เ[\w]ือะ',text, re.U): ''' - จัดการกับ เอือ + จัดการกับ เอือะ ''' - #print('เอือ') - search=re.findall(u'เ[\w]/ือ/ะ',text, re.U) + #print('เอือะ') + search=re.findall(u'เ[\w]ือะ',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'uea',text,flags=re.U) - if re.search(u'เ[\w]/ือ',text, re.U): + if re.search(u'เ[\w]ือ',text, re.U): ''' จัดการกับ เอือ ''' #print('เอือ') - search=re.findall(u'เ[\w]/ือ',text, re.U) + search=re.findall(u'เ[\w]ือ',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'uea',text,flags=re.U) if re.search(u'โ[\w]/ย',text, re.U): @@ -183,22 +183,22 @@ def romanization(text): search=re.findall(u'โ[\w]/ย',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'oi',text,flags=re.U) - if re.search(u'[\w]อย',text, re.U): + if re.search(u'[\w]/อ/ย',text, re.U): ''' - จัดการกับ โอย + จัดการกับ ออย ''' - #print('โอย') - search=re.findall(u'[\w]อย',text, re.U) + #print('ออย') + search=re.findall(u'[\w]/อ/ย',text, re.U) for i in search: text=re.sub(i,list(i)[0]+'oi',text,flags=re.U) - if re.search(u'โ/[\w]ะ/',text, re.U): + if re.search(u'โ[\w]ะ',text, re.U): ''' จัดการกับ โอะ ''' #print('โอะ') - search=re.findall(u'โ/[\w]ะ/',text, re.U) + search=re.findall(u'โ[\w]ะ',text, re.U) for i in search: - text=re.sub(i,list(i)[2]+'o',text,flags=re.U) + text=re.sub(i,list(i)[1]+'o',text,flags=re.U) if re.search(u'โ[\w]',text, re.U): ''' จัดการกับ โอ @@ -215,12 +215,12 @@ def romanization(text): search=re.findall(u'เ/[\w]า/ะ/',text, re.U) for i in search: text=re.sub(i,list(i)[2]+'o',text,flags=re.U) - if re.search(u'เ[\w]าะ/',text, re.U): + if re.search(u'เ[\w]าะ',text, re.U): ''' จัดการกับ เอาะ (2) ''' #print('เอาะ 2') - search=re.findall(u'เ[\w]าะ/',text, re.U) + search=re.findall(u'เ[\w]าะ',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'o',text,flags=re.U) if re.search(u'อำ',text, re.U): @@ -239,46 +239,54 @@ def romanization(text): search=re.findall(u'อี',text, re.U) for i in search: text=re.sub(i,'i',text,flags=re.U) - if re.search(u'[\w]อ',text, re.U): + # เออ + if re.search(u'เ[\w]/อ',text, re.U): + ''' + จัดการกับ เออ + ''' + #print('เออ') + search=re.findall(u'เ[\w]/อ',text, re.U) + for i in search: + text=re.sub(i,list(i)[1]+'oe',text,flags=re.U) + if re.search(u'[\w]/อ',text, re.U): ''' จัดการกับ ออ ''' #print('ออ') - search=re.findall(u'[\w]อ',text, re.U) + search=re.findall(u'[\w]/อ',text, re.U) for i in search: text=re.sub(i,list(i)[0]+'o',text,flags=re.U) - if re.search(u'/[\w]ั/ว/ะ',text, re.U): + if re.search(u'[\w]ัวะ',text, re.U): ''' จัดการกับ อัวะ ''' #print('อัวะ') - search=re.findall(u'/[\w]ั/ว/ะ',text, re.U) + search=re.findall(u'[\w]ัวะ',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'ua',text,flags=re.U) - if re.search(u'/[\w]ั/ว',text, re.U): + text=re.sub(i,list(i)[0]+'ua',text,flags=re.U) + if re.search(u'[\w]ัว',text, re.U): ''' จัดการกับ อัว ''' #print('อัว') - search=re.findall(u'/[\w]ั/ว',text, re.U) + search=re.findall(u'[\w]ัว',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'ua',text,flags=re.U) - + text=re.sub(i,list(i)[0]+'ua',text,flags=re.U) # ใอ,อัย , อาย - if re.search(u'ใ[\w]/',text, re.U): + if re.search(u'ใ[\w]',text, re.U): ''' จัดการกับ ใอ ''' #print('ใอ') - search=re.findall(u'ใ[\w]/',text, re.U) + search=re.findall(u'ใ[\w]',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'ai',text,flags=re.U) - if re.search(u'[\w]ั/ย',text, re.U): + if re.search(u'[\w]ัย',text, re.U): ''' จัดการกับ อัย ''' #print('อัย') - search=re.findall(u'[\w]ั/ย',text, re.U) + search=re.findall(u'[\w]ัย',text, re.U) for i in search: text=re.sub(i,list(i)[0]+'ai',text,flags=re.U) if re.search(u'[\w]า/ย',text, re.U): @@ -290,14 +298,14 @@ def romanization(text): for i in search: text=re.sub(i,list(i)[0]+'ai',text,flags=re.U) #เอา, อาว - if re.search(u'เ/[\w]า/',text, re.U): + if re.search(u'เ[\w]า',text, re.U): ''' จัดการกับ เอา ''' #print('เอา') - search=re.findall(u'เ/[\w]า/',text, re.U) + search=re.findall(u'เ[\w]า',text, re.U) for i in search: - text=re.sub(i,list(i)[2]+'ao',text,flags=re.U) + text=re.sub(i,list(i)[1]+'ao',text,flags=re.U) if re.search(u'[\w]า/ว',text, re.U): ''' จัดการกับ อาว @@ -324,75 +332,66 @@ def romanization(text): search=re.findall(u'เ[\w]/ย',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'oei',text,flags=re.U) - # เออ - if re.search(u'เ[\w]/อ',text, re.U): - ''' - จัดการกับ เออ - ''' - #print('เออ') - search=re.findall(u'เ[\w]/อ',text, re.U) - for i in search: - text=re.sub(i,list(i)[1]+'oe',text,flags=re.U) # แอะ, แอ - if re.search(u'แ/[\w]ะ/',text, re.U): + if re.search(u'แ[\w]ะ',text, re.U): ''' จัดการกับ แอะ ''' #print('แอะ') - search=re.findall(u'แ/[\w]ะ/',text, re.U) + search=re.findall(u'แ[\w]ะ',text, re.U) for i in search: - text=re.sub(i,list(i)[2]+'ae',text,flags=re.U) - if re.search(u'/แ[\w]/',text, re.U): + text=re.sub(i,list(i)[1]+'ae',text,flags=re.U) + if re.search(u'แ[\w]',text, re.U): ''' จัดการกับ แอ ''' #print('แอ') - search=re.findall(u'/แ[\w]/',text, re.U) + search=re.findall(u'แ[\w]',text, re.U) for i in search: - text=re.sub(i,list(i)[2]+'ae',text,flags=re.U) + text=re.sub(i,list(i)[1]+'ae',text,flags=re.U) # เอะ - if re.search(u'เ/[\w]ะ/',text, re.U): + if re.search(u'เ[\w]ะ',text, re.U): ''' จัดการกับ เอะ ''' #print('เอะ') - search=re.findall(u'เ/[\w]ะ/',text, re.U) + search=re.findall(u'เ[\w]ะ',text, re.U) for i in search: - text=re.sub(i,list(i)[2]+'e',text,flags=re.U) + text=re.sub(i,list(i)[1]+'e',text,flags=re.U) # อิว - if re.search(u'/[\w]ิ/ว',text, re.U): + if re.search(u'[\w]ิ/ว',text, re.U): ''' จัดการกับ อิว ''' #print('อิว') - search=re.findall(u'/[\w]ิ/ว',text, re.U) + search=re.findall(u'[\w]ิ/ว',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'io',text,flags=re.U) + text=re.sub(i,list(i)[0]+'io',text,flags=re.U) # อวย - if re.search(u'[\w]วย',text, re.U): + if re.search(u'[\w]/ว/ย',text, re.U): ''' จัดการกับ อวย ''' #print('อวย') - search=re.findall(u'[\w]วย',text, re.U) + search=re.findall(u'[\w]/ว/ย',text, re.U) for i in search: text=re.sub(i,list(i)[0]+'uai',text,flags=re.U) # -ว- - if re.search(u'[\w]ว[\w]',text, re.U): + if re.search(u'[\w]/ว/[\w]',text, re.U): ''' จัดการกับ -ว- ''' #print('-ว-') - search=re.findall(u'[\w]ว[\w]',text, re.U) + search=re.findall(u'[\w]/ว/[\w]',text, re.U) for i in search: - text=re.sub(i,list(i)[0]+'ua'+list(i)[2],text,flags=re.U) + text=re.sub(i,list(i)[0]+'ua'+list(i)[4],text,flags=re.U) # เ–็,เอ - if re.search(u'เ[\w]/'+'็',text, re.U): + if re.search(u'เ[\w]'+'็',text, re.U): ''' จัดการกับ เ–็ ''' #print('เ–็') - search=re.findall(u'เ[\w]/'+'็',text, re.U) + search=re.findall(u'เ[\w]'+'็',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'e',text,flags=re.U) if re.search(u'เ[\w]/',text, re.U): @@ -413,64 +412,49 @@ def romanization(text): for i in search: text=re.sub(i,list(i)[1]+'ai',text,flags=re.U) #ไอ - if re.search(u'ไ[\w]/',text, re.U): + if re.search(u'ไ[\w]',text, re.U): ''' จัดการกับ ไอ ''' #print('ไอ') - search=re.findall(u'ไ[\w]/',text, re.U) + search=re.findall(u'ไ[\w]',text, re.U) for i in search: text=re.sub(i,list(i)[1]+'ai',text,flags=re.U) #อะ - if re.search(u'/[\w]ะ/',text, re.U): + if re.search(u'[\w]ะ',text, re.U): ''' จัดการกับ อะ ''' #print('อะ') - search=re.findall(u'/[\w]ะ/',text, re.U) + search=re.findall(u'[\w]ะ',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'a',text,flags=re.U) + text=re.sub(i,list(i)[0]+'a',text,flags=re.U) # –ั - if re.search(u'/[\w]ั/',text, re.U): + if re.search(u'[\w]ั',text, re.U): ''' จัดการกับ –ั ''' #print('–ั ') - search=re.findall(u'/[\w]ั/',text, re.U) + search=re.findall(u'[\w]ั',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'a',text,flags=re.U) + text=re.sub(i,list(i)[0]+'a',text,flags=re.U) # รร - """ - if re.search(u'[\w]รร[\w]',text, re.U): + if re.search(u'[\w]/ร/ร/[\w][^ก-ฮ]',text, re.U): ''' จัดการกับ -รร- ''' #print('-รร- 1') - search=re.findall(u'[\w]รร[\w]',text, re.U) + search=re.findall(u'[\w]/ร/ร/[\w][^ก-ฮ]',text, re.U) for i in search: - text=re.sub(i,list(i)[0]+'a'+list(i)[3],text,flags=re.U) - if re.search(u'[\w]รร',text, re.U): + text=re.sub(i,list(i)[0]+'an'+list(i)[6]+list(i)[7],text,flags=re.U) + if re.search(u'[\w]/ร/ร/',text, re.U): ''' จัดการกับ -รร- ''' #print('-รร- 2') - search=re.findall(u'[\w]รร',text, re.U) + search=re.findall(u'[\w]/ร/ร/',text, re.U) for i in search: - text=re.sub(i,list(i)[0]+'an'+'/',text,flags=re.U) - """ - if re.search(u'[\w]รร',text, re.U): - ''' - จัดการกับ -รร- - ''' - #print('-รร- 1') - if len(text)==3: - search=re.findall(u'[\w]รร',text, re.U) - for i in search: - text=re.sub(i,list(i)[0]+'an',text,flags=re.U) - else: - search=re.findall(u'[\w]รร',text, re.U) - for i in search: - text=re.sub(i,list(i)[0]+'a',text,flags=re.U) + text=re.sub(i,list(i)[0]+'a',text,flags=re.U) #อา if re.search(u'อา',text, re.U): ''' @@ -480,74 +464,74 @@ def romanization(text): search=re.findall(u'อา',text, re.U) for i in search: text=re.sub(i,'a',text,flags=re.U) - if re.search(u'/[\w]า/',text, re.U): + if re.search(u'[\w]า',text, re.U): ''' จัดการกับ อา 2 ''' #print('อา 2') - search=re.findall(u'/[\w]า/',text, re.U) + search=re.findall(u'[\w]า',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'a',text,flags=re.U) - #อำ - if re.search(u'/[\w]ำ/',text, re.U): + text=re.sub(i,list(i)[0]+'a',text,flags=re.U) + #อำ + if re.search(u'[\w]ำ',text, re.U): ''' จัดการกับ อำ 1 ''' #print('อำ 1') - search=re.findall(u'/[\w]ำ/',text, re.U) + search=re.findall(u'[\w]ำ',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'am',text,flags=re.U) + text=re.sub(i,list(i)[0]+'am',text,flags=re.U) #อิ , อี - if re.search(u'/[\w]ิ/',text, re.U): + if re.search(u'[\w]ิ',text, re.U): ''' จัดการกับ อิ ''' #print('อิ') - search=re.findall(u'/[\w]ิ/',text, re.U) + search=re.findall(u'[\w]ิ',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'i'+'/',text,flags=re.U) - if re.search(u'/[\w]ี/',text, re.U): + text=re.sub(i,list(i)[0]+'i'+'/',text,flags=re.U) + if re.search(u'[\w]ี',text, re.U): ''' จัดการกับ อี ''' #print('อี') - search=re.findall(u'/[\w]ี/',text, re.U) + search=re.findall(u'[\w]ี',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'i'+'/',text,flags=re.U) + text=re.sub(i,list(i)[0]+'i'+'/',text,flags=re.U) #อึ , อื - if re.search(u'/[\w]ึ/',text, re.U): + if re.search(u'[\w]ึ',text, re.U): ''' จัดการกับ อึ ''' #print('อึ') - search=re.findall(u'/[\w]ึ/',text, re.U) + search=re.findall(u'[\w]ึ',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'ue'+'/',text,flags=re.U) - if re.search(u'/[\w]ื/',text, re.U): + text=re.sub(i,list(i)[0]+'ue'+'/',text,flags=re.U) + if re.search(u'[\w]ื',text, re.U): ''' จัดการกับ อื ''' #print('อื') - search=re.findall(u'/[\w]ื/',text, re.U) + search=re.findall(u'[\w]ื',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'ue'+'/',text,flags=re.U) + text=re.sub(i,list(i)[0]+'ue'+'/',text,flags=re.U) #อุ , อู - if re.search(u'/[\w]ุ/',text, re.U): + if re.search(u'[\w]ุ',text, re.U): ''' จัดการกับ อุ ''' #print('อุ') - search=re.findall(u'/[\w]ุ/',text, re.U) + search=re.findall(u'[\w]ุ',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'u'+'/',text,flags=re.U) - if re.search(u'/[\w]ู/',text, re.U): + text=re.sub(i,list(i)[0]+'u'+'/',text,flags=re.U) + if re.search(u'[\w]ู',text, re.U): ''' จัดการกับ อู ''' #print('อู') - search=re.findall(u'/[\w]ู/',text, re.U) + search=re.findall(u'[\w]ู',text, re.U) for i in search: - text=re.sub(i,list(i)[1]+'u'+'/',text,flags=re.U) + text=re.sub(i,list(i)[0]+'u'+'/',text,flags=re.U) if re.search(r'[^กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬฮ]',text, re.U): ''' ใช้ในกรณีคำนั้นมีสระด้วย จะได้เอาพยัญชนะตัวแรกไปเทียบ From d6f87201be457120dd77a1e32dcc7442497b1e64 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 21 Jun 2017 20:18:03 +0700 Subject: [PATCH 28/71] add corpus_license.md --- README.md | 2 + pythainlp/corpus/LICENSE_THA_WN | 35 ----- pythainlp/corpus/corpus_license.md | 218 +++++++++++++++++++++++++++++ pythainlp/romanization/royin.py | 3 +- setup.py | 2 +- 5 files changed, 223 insertions(+), 37 deletions(-) delete mode 100644 pythainlp/corpus/LICENSE_THA_WN create mode 100644 pythainlp/corpus/corpus_license.md diff --git a/README.md b/README.md index ebfa8d048..8839dbc8a 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,8 @@ $ CFLAGS=-I/usr/local/opt/icu4c/include LDFLAGS=-L/usr/local/opt/icu4c/lib pip i Apache Software License 2.0 +สามารถนำไปใช้ได้ทั้งงานวิจัยและในเชิงการค้า ใช้ในโปรแกรมปิดโค้ดได้ โดยคุณต้องระบุว่าใช้ PyThaiNLP ในเอกสารของโปรแกรมคุณและแนบ Apache Software License 2.0 ของ PyThaiNLP ไปด้วย + พัฒนาโดย นาย วรรณพงษ์ ภัททิยไพบูลย์ diff --git a/pythainlp/corpus/LICENSE_THA_WN b/pythainlp/corpus/LICENSE_THA_WN deleted file mode 100644 index e9774060e..000000000 --- a/pythainlp/corpus/LICENSE_THA_WN +++ /dev/null @@ -1,35 +0,0 @@ -Copyright: 2011 NICT - -Thai WordNet - -This software and database is being provided to you, the LICENSEE, by -the National Institute of Information and Communications Technology -under the following license. By obtaining, using and/or copying this -software and database, you agree that you have read, understood, and -will comply with these terms and conditions: - - Permission to use, copy, modify and distribute this software and - database and its documentation for any purpose and without fee or - royalty is hereby granted, provided that you agree to comply with - the following copyright notice and statements, including the - disclaimer, and that the same appear on ALL copies of the software, - database and documentation, including modifications that you make - for internal use or for distribution. - -Thai WordNet Copyright 2011 by the National Institute of -Information and Communications Technology (NICT). All rights -reserved. - -THIS SOFTWARE AND DATABASE IS PROVIDED "AS IS" AND NICT MAKES NO -REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, -BUT NOT LIMITATION, NICT MAKES NO REPRESENTATIONS OR WARRANTIES OF -MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE -OF THE LICENSED SOFTWARE, DATABASE OR DOCUMENTATION WILL NOT INFRINGE -ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. - -The name of the National Institute of Information and Communications -Technology may not be used in advertising or publicity pertaining to -distribution of the software and/or database. Title to copyright in -this software, database and any associated documentation shall at all -times remain with National Institute of Information and Communications -Technology and LICENSEE agrees to preserve same. diff --git a/pythainlp/corpus/corpus_license.md b/pythainlp/corpus/corpus_license.md new file mode 100644 index 000000000..803c9b59f --- /dev/null +++ b/pythainlp/corpus/corpus_license.md @@ -0,0 +1,218 @@ +# Corpus License + +tha-wn.db + +``` +Copyright: 2011 NICT + +Thai WordNet + +This software and database is being provided to you, the LICENSEE, by +the National Institute of Information and Communications Technology +under the following license. By obtaining, using and/or copying this +software and database, you agree that you have read, understood, and +will comply with these terms and conditions: + + Permission to use, copy, modify and distribute this software and + database and its documentation for any purpose and without fee or + royalty is hereby granted, provided that you agree to comply with + the following copyright notice and statements, including the + disclaimer, and that the same appear on ALL copies of the software, + database and documentation, including modifications that you make + for internal use or for distribution. + +Thai WordNet Copyright 2011 by the National Institute of +Information and Communications Technology (NICT). All rights +reserved. + +THIS SOFTWARE AND DATABASE IS PROVIDED "AS IS" AND NICT MAKES NO +REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, +BUT NOT LIMITATION, NICT MAKES NO REPRESENTATIONS OR WARRANTIES OF +MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE +OF THE LICENSED SOFTWARE, DATABASE OR DOCUMENTATION WILL NOT INFRINGE +ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS. + +The name of the National Institute of Information and Communications +Technology may not be used in advertising or publicity pertaining to +distribution of the software and/or database. Title to copyright in +this software, database and any associated documentation shall at all +times remain with National Institute of Information and Communications +Technology and LICENSEE agrees to preserve same. +``` + +thaiword.txt , new-thaidict.txt , stopwords-th.txt , stopwords-th1.txt , stopwords-th2.txt , stopwords-th3.txt , stopwords-th4.txt , stopwords-th-old.txt and คำมูล-คำอ่าน.db using Creative Commons Attribution-ShareAlike 4.0 International Public License + +## creative commons + +# Attribution-ShareAlike 4.0 International + +Creative Commons Corporation (“Creative Commons”) is not a law firm and does not provide legal services or legal advice. Distribution of Creative Commons public licenses does not create a lawyer-client or other relationship. Creative Commons makes its licenses and related information available on an “as-is” basis. Creative Commons gives no warranties regarding its licenses, any material licensed under their terms and conditions, or any related information. Creative Commons disclaims all liability for damages resulting from their use to the fullest extent possible. + +### Using Creative Commons Public Licenses + +Creative Commons public licenses provide a standard set of terms and conditions that creators and other rights holders may use to share original works of authorship and other material subject to copyright and certain other rights specified in the public license below. The following considerations are for informational purposes only, are not exhaustive, and do not form part of our licenses. + +* __Considerations for licensors:__ Our public licenses are intended for use by those authorized to give the public permission to use material in ways otherwise restricted by copyright and certain other rights. Our licenses are irrevocable. Licensors should read and understand the terms and conditions of the license they choose before applying it. Licensors should also secure all rights necessary before applying our licenses so that the public can reuse the material as expected. Licensors should clearly mark any material not subject to the license. This includes other CC-licensed material, or material used under an exception or limitation to copyright. [More considerations for licensors](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensors). + +* __Considerations for the public:__ By using one of our public licenses, a licensor grants the public permission to use the licensed material under specified terms and conditions. If the licensor’s permission is not necessary for any reason–for example, because of any applicable exception or limitation to copyright–then that use is not regulated by the license. Our licenses grant only permissions under copyright and certain other rights that a licensor has authority to grant. Use of the licensed material may still be restricted for other reasons, including because others have copyright or other rights in the material. A licensor may make special requests, such as asking that all changes be marked or described. Although not required by our licenses, you are encouraged to respect those requests where reasonable. [More considerations for the public](http://wiki.creativecommons.org/Considerations_for_licensors_and_licensees#Considerations_for_licensees). + +## Creative Commons Attribution-ShareAlike 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree to be bound by the terms and conditions of this Creative Commons Attribution-ShareAlike 4.0 International Public License ("Public License"). To the extent this Public License may be interpreted as a contract, You are granted the Licensed Rights in consideration of Your acceptance of these terms and conditions, and the Licensor grants You such rights in consideration of benefits the Licensor receives from making the Licensed Material available under these terms and conditions. + +### Section 1 – Definitions. + +a. __Adapted Material__ means material subject to Copyright and Similar Rights that is derived from or based upon the Licensed Material and in which the Licensed Material is translated, altered, arranged, transformed, or otherwise modified in a manner requiring permission under the Copyright and Similar Rights held by the Licensor. For purposes of this Public License, where the Licensed Material is a musical work, performance, or sound recording, Adapted Material is always produced where the Licensed Material is synched in timed relation with a moving image. + +b. __Adapter's License__ means the license You apply to Your Copyright and Similar Rights in Your contributions to Adapted Material in accordance with the terms and conditions of this Public License. + +c. __BY-SA Compatible License__ means a license listed at [creativecommons.org/compatiblelicenses](http://creativecommons.org/compatiblelicenses), approved by Creative Commons as essentially the equivalent of this Public License. + +d. __Copyright and Similar Rights__ means copyright and/or similar rights closely related to copyright including, without limitation, performance, broadcast, sound recording, and Sui Generis Database Rights, without regard to how the rights are labeled or categorized. For purposes of this Public License, the rights specified in Section 2(b)(1)-(2) are not Copyright and Similar Rights. + +e. __Effective Technological Measures__ means those measures that, in the absence of proper authority, may not be circumvented under laws fulfilling obligations under Article 11 of the WIPO Copyright Treaty adopted on December 20, 1996, and/or similar international agreements. + +f. __Exceptions and Limitations__ means fair use, fair dealing, and/or any other exception or limitation to Copyright and Similar Rights that applies to Your use of the Licensed Material. + +g. __License Elements__ means the license attributes listed in the name of a Creative Commons Public License. The License Elements of this Public License are Attribution and ShareAlike. + +h. __Licensed Material__ means the artistic or literary work, database, or other material to which the Licensor applied this Public License. + +i. __Licensed Rights__ means the rights granted to You subject to the terms and conditions of this Public License, which are limited to all Copyright and Similar Rights that apply to Your use of the Licensed Material and that the Licensor has authority to license. + +j. __Licensor__ means the individual(s) or entity(ies) granting rights under this Public License. + +k. __Share__ means to provide material to the public by any means or process that requires permission under the Licensed Rights, such as reproduction, public display, public performance, distribution, dissemination, communication, or importation, and to make material available to the public including in ways that members of the public may access the material from a place and at a time individually chosen by them. + +l. __Sui Generis Database Rights__ means rights other than copyright resulting from Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, as amended and/or succeeded, as well as other essentially equivalent rights anywhere in the world. + +m. __You__ means the individual or entity exercising the Licensed Rights under this Public License. Your has a corresponding meaning. + +### Section 2 – Scope. + +a. ___License grant.___ + + 1. Subject to the terms and conditions of this Public License, the Licensor hereby grants You a worldwide, royalty-free, non-sublicensable, non-exclusive, irrevocable license to exercise the Licensed Rights in the Licensed Material to: + + A. reproduce and Share the Licensed Material, in whole or in part; and + + B. produce, reproduce, and Share Adapted Material. + + 2. __Exceptions and Limitations.__ For the avoidance of doubt, where Exceptions and Limitations apply to Your use, this Public License does not apply, and You do not need to comply with its terms and conditions. + + 3. __Term.__ The term of this Public License is specified in Section 6(a). + + 4. __Media and formats; technical modifications allowed.__ The Licensor authorizes You to exercise the Licensed Rights in all media and formats whether now known or hereafter created, and to make technical modifications necessary to do so. The Licensor waives and/or agrees not to assert any right or authority to forbid You from making technical modifications necessary to exercise the Licensed Rights, including technical modifications necessary to circumvent Effective Technological Measures. For purposes of this Public License, simply making modifications authorized by this Section 2(a)(4) never produces Adapted Material. + + 5. __Downstream recipients.__ + + A. __Offer from the Licensor – Licensed Material.__ Every recipient of the Licensed Material automatically receives an offer from the Licensor to exercise the Licensed Rights under the terms and conditions of this Public License. + + B. __Additional offer from the Licensor – Adapted Material. Every recipient of Adapted Material from You automatically receives an offer from the Licensor to exercise the Licensed Rights in the Adapted Material under the conditions of the Adapter’s License You apply. + + C. __No downstream restrictions.__ You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, the Licensed Material if doing so restricts exercise of the Licensed Rights by any recipient of the Licensed Material. + + 6. __No endorsement.__ Nothing in this Public License constitutes or may be construed as permission to assert or imply that You are, or that Your use of the Licensed Material is, connected with, or sponsored, endorsed, or granted official status by, the Licensor or others designated to receive attribution as provided in Section 3(a)(1)(A)(i). + +b. ___Other rights.___ + + 1. Moral rights, such as the right of integrity, are not licensed under this Public License, nor are publicity, privacy, and/or other similar personality rights; however, to the extent possible, the Licensor waives and/or agrees not to assert any such rights held by the Licensor to the limited extent necessary to allow You to exercise the Licensed Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this Public License. + + 3. To the extent possible, the Licensor waives any right to collect royalties from You for the exercise of the Licensed Rights, whether directly or through a collecting society under any voluntary or waivable statutory or compulsory licensing scheme. In all other cases the Licensor expressly reserves any right to collect such royalties. + +### Section 3 – License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the following conditions. + +a. ___Attribution.___ + + 1. If You Share the Licensed Material (including in modified form), You must: + + A. retain the following if it is supplied by the Licensor with the Licensed Material: + + i. identification of the creator(s) of the Licensed Material and any others designated to receive attribution, in any reasonable manner requested by the Licensor (including by pseudonym if designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of warranties; + + v. a URI or hyperlink to the Licensed Material to the extent reasonably practicable; + + B. indicate if You modified the Licensed Material and retain an indication of any previous modifications; and + + C. indicate the Licensed Material is licensed under this Public License, and include the text of, or the URI or hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any reasonable manner based on the medium, means, and context in which You Share the Licensed Material. For example, it may be reasonable to satisfy the conditions by providing a URI or hyperlink to a resource that includes the required information. + + 3. If requested by the Licensor, You must remove any of the information required by Section 3(a)(1)(A) to the extent reasonably practicable. + +b. ___ShareAlike.___ + +In addition to the conditions in Section 3(a), if You Share Adapted Material You produce, the following conditions also apply. + +1. The Adapter’s License You apply must be a Creative Commons license with the same License Elements, this version or later, or a BY-SA Compatible License. + +2. You must include the text of, or the URI or hyperlink to, the Adapter's License You apply. You may satisfy this condition in any reasonable manner based on the medium, means, and context in which You Share Adapted Material. + +3. You may not offer or impose any additional or different terms or conditions on, or apply any Effective Technological Measures to, Adapted Material that restrict exercise of the rights granted under the Adapter's License You apply. + +### Section 4 – Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that apply to Your use of the Licensed Material: + +a. for the avoidance of doubt, Section 2(a)(1) grants You the right to extract, reuse, reproduce, and Share all or a substantial portion of the contents of the database; + +b. if You include all or a substantial portion of the database contents in a database in which You have Sui Generis Database Rights, then the database in which You have Sui Generis Database Rights (but not its individual contents) is Adapted Material, including for purposes of Section 3(b); and + +c. You must comply with the conditions in Section 3(a) if You Share all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not replace Your obligations under this Public License where the Licensed Rights include other Copyright and Similar Rights. + +### Section 5 – Disclaimer of Warranties and Limitation of Liability. + +a. __Unless otherwise separately undertaken by the Licensor, to the extent possible, the Licensor offers the Licensed Material as-is and as-available, and makes no representations or warranties of any kind concerning the Licensed Material, whether express, implied, statutory, or other. This includes, without limitation, warranties of title, merchantability, fitness for a particular purpose, non-infringement, absence of latent or other defects, accuracy, or the presence or absence of errors, whether or not known or discoverable. Where disclaimers of warranties are not allowed in full or in part, this disclaimer may not apply to You.__ + +b. __To the extent possible, in no event will the Licensor be liable to You on any legal theory (including, without limitation, negligence) or otherwise for any direct, special, indirect, incidental, consequential, punitive, exemplary, or other losses, costs, expenses, or damages arising out of this Public License or use of the Licensed Material, even if the Licensor has been advised of the possibility of such losses, costs, expenses, or damages. Where a limitation of liability is not allowed in full or in part, this limitation may not apply to You.__ + +c. The disclaimer of warranties and limitation of liability provided above shall be interpreted in a manner that, to the extent possible, most closely approximates an absolute disclaimer and waiver of all liability. + +### Section 6 – Term and Termination. + +a. This Public License applies for the term of the Copyright and Similar Rights licensed here. However, if You fail to comply with this Public License, then Your rights under this Public License terminate automatically. + +b. Where Your right to use the Licensed Material has terminated under Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided it is cured within 30 days of Your discovery of the violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any right the Licensor may have to seek remedies for Your violations of this Public License. + +c. For the avoidance of doubt, the Licensor may also offer the Licensed Material under separate terms or conditions or stop distributing the Licensed Material at any time; however, doing so will not terminate this Public License. + +d. Sections 1, 5, 6, 7, and 8 survive termination of this Public License. + +### Section 7 – Other Terms and Conditions. + +a. The Licensor shall not be bound by any additional or different terms or conditions communicated by You unless expressly agreed. + +b. Any arrangements, understandings, or agreements regarding the Licensed Material not stated herein are separate from and independent of the terms and conditions of this Public License.t stated herein are separate from and independent of the terms and conditions of this Public License. + +### Section 8 – Interpretation. + +a. For the avoidance of doubt, this Public License does not, and shall not be interpreted to, reduce, limit, restrict, or impose conditions on any use of the Licensed Material that could lawfully be made without permission under this Public License. + +b. To the extent possible, if any provision of this Public License is deemed unenforceable, it shall be automatically reformed to the minimum extent necessary to make it enforceable. If the provision cannot be reformed, it shall be severed from this Public License without affecting the enforceability of the remaining terms and conditions. + +c. No term or condition of this Public License will be waived and no failure to comply consented to unless expressly agreed to by the Licensor. + +d. Nothing in this Public License constitutes or may be interpreted as a limitation upon, or waiver of, any privileges and immunities that apply to the Licensor or You, including from the legal processes of any jurisdiction or authority. + +> Creative Commons is not a party to its public licenses. Notwithstanding, Creative Commons may elect to apply one of its public licenses to material it publishes and in those instances will be considered the “Licensor.” Except for the limited purpose of indicating that material is shared under a Creative Commons public license or as otherwise permitted by the Creative Commons policies published at [creativecommons.org/policies](http://creativecommons.org/policies), Creative Commons does not authorize the use of the trademark “Creative Commons” or any other trademark or logo of Creative Commons without its prior written consent including, without limitation, in connection with any unauthorized modifications to any of its public licenses or any other arrangements, understandings, or agreements concerning use of licensed material. For the avoidance of doubt, this paragraph does not form part of the public licenses. +> +> Creative Commons may be contacted at creativecommons.org + diff --git a/pythainlp/romanization/royin.py b/pythainlp/romanization/royin.py index dd84d7289..37a45c472 100644 --- a/pythainlp/romanization/royin.py +++ b/pythainlp/romanization/royin.py @@ -56,6 +56,7 @@ 'ส':['s','t'], 'ห':['h',''], 'ฬ':['l','n'], +'อ':['',''], 'ฮ':['h',''] } Consonantsthai= u'[กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬฮ]' @@ -75,7 +76,7 @@ def romanization(text): textdata=[] #print(text1) for text in text1: - a1=etcc.etcc(text) + #a1=etcc.etcc(text) a2=tcc.tcc(text) text=re.sub('//','/',a2) if re.search(u'เ[\w]'+'ี'+'ย/ว',text, re.U): diff --git a/setup.py b/setup.py index 2c227de53..e3eea66a3 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ url='https://github.com/wannaphongcom/pythainlp', packages=find_packages(), test_suite='pythainlp.test', - package_data={'pythainlp.corpus':['stopwords-th.txt','thaipos.json','thaiword.txt','LICENSE_THA_WN','tha-wn.db','new-thaidict.txt','negation.txt'],'pythainlp.sentiment':['vocabulary.data','sentiment.data']}, + package_data={'pythainlp.corpus':['stopwords-th.txt','thaipos.json','thaiword.txt','corpus_license.md','tha-wn.db','new-thaidict.txt','negation.txt'],'pythainlp.sentiment':['vocabulary.data','sentiment.data']}, include_package_data=True, install_requires=requirements, license='Apache Software License 2.0', From 94eaead7e9dac34c30830b657539063494a3e318 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 21 Jun 2017 20:18:53 +0700 Subject: [PATCH 29/71] fix data --- README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/README.md b/README.md index 8839dbc8a..ebfa8d048 100644 --- a/README.md +++ b/README.md @@ -86,8 +86,6 @@ $ CFLAGS=-I/usr/local/opt/icu4c/include LDFLAGS=-L/usr/local/opt/icu4c/lib pip i Apache Software License 2.0 -สามารถนำไปใช้ได้ทั้งงานวิจัยและในเชิงการค้า ใช้ในโปรแกรมปิดโค้ดได้ โดยคุณต้องระบุว่าใช้ PyThaiNLP ในเอกสารของโปรแกรมคุณและแนบ Apache Software License 2.0 ของ PyThaiNLP ไปด้วย - พัฒนาโดย นาย วรรณพงษ์ ภัททิยไพบูลย์ From 504f6690a411d4ff6ed45698a229d3e52144bbe3 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Thu, 22 Jun 2017 12:29:51 +0700 Subject: [PATCH 30/71] add Meta Sound --- README.md | 1 + References.md | 3 +++ docs/pythainlp-1-4-thai.md | 14 ++++++++++ pythainlp/MetaSound.py | 52 ++++++++++++++++++++++++++++++++++++++ pythainlp/__init__.py | 1 + 5 files changed, 71 insertions(+) create mode 100644 References.md create mode 100644 pythainlp/MetaSound.py diff --git a/README.md b/README.md index ebfa8d048..1d4cec74b 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ Natural language processing หรือ การประมวลภาษา - รองรับ Thai Character Clusters (TCC) และ ETCC - Thai WordNet ตัวใหม่ - เพิ่มหลักเกณฑ์การถอดอักษรไทยเป็นอักษรโรมัน ฉบับราชบัณฑิตยสถาน +- เพิ่ม Meta Sound ภาษาไทย ### ความสามารถ - ตัดคำภาษาไทย diff --git a/References.md b/References.md new file mode 100644 index 000000000..5ea558d57 --- /dev/null +++ b/References.md @@ -0,0 +1,3 @@ +# References + +Snae & Brückner. (2009). Novel Phonetic Name Matching Algorithm with a Statistical Ontology for Analysing Names Given in Accordance with Thai Astrology. Retrieved from https://pdfs.semanticscholar.org/3983/963e87ddc6dfdbb291099aa3927a0e3e4ea6.pdf \ No newline at end of file diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 097da5697..885895236 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -268,6 +268,20 @@ grammar : คุณ Wittawat Jitkrittum (https://github.com/wittawatj/jtcc/blob/ '/คืน/ความสุข' ``` +### Meta Sound ภาษาไทย + +``` +Snae & Brückner. (2009). Novel Phonetic Name Matching Algorithm with a Statistical Ontology for Analysing Names Given in Accordance with Thai Astrology. Retrieved from https://pdfs.semanticscholar.org/3983/963e87ddc6dfdbb291099aa3927a0e3e4ea6.pdf +``` + +**การใช้งาน** + +```python +>>> from pythainlp.MetaSound import * +>>> MetaSound('คน') +'15' +``` + ### Sentiment analysis ภาษาไทย ใช้ข้อมูลจาก https://github.com/wannaphongcom/lexicon-thai/tree/master/ข้อความ/ diff --git a/pythainlp/MetaSound.py b/pythainlp/MetaSound.py new file mode 100644 index 000000000..af708dc98 --- /dev/null +++ b/pythainlp/MetaSound.py @@ -0,0 +1,52 @@ +''' +MetaSound + +References + +Snae & Brückner. (2009). Novel Phonetic Name Matching Algorithm with a Statistical Ontology for Analysing Names Given in Accordance with Thai Astrology. Retrieved from https://pdfs.semanticscholar.org/3983/963e87ddc6dfdbb291099aa3927a0e3e4ea6.pdf +''' +import re +def MetaSound(name): + ''' + MetaSound(str) + ''' + name1=list(name) + count=len(name1) + word=[] + i=0 + while i Date: Thu, 22 Jun 2017 12:35:11 +0700 Subject: [PATCH 31/71] add TCC References --- References.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/References.md b/References.md index 5ea558d57..1e29854a3 100644 --- a/References.md +++ b/References.md @@ -1,3 +1,5 @@ # References -Snae & Brückner. (2009). Novel Phonetic Name Matching Algorithm with a Statistical Ontology for Analysing Names Given in Accordance with Thai Astrology. Retrieved from https://pdfs.semanticscholar.org/3983/963e87ddc6dfdbb291099aa3927a0e3e4ea6.pdf \ No newline at end of file +Snae & Brückner. (2009). Novel Phonetic Name Matching Algorithm with a Statistical Ontology for Analysing Names Given in Accordance with Thai Astrology. Retrieved from https://pdfs.semanticscholar.org/3983/963e87ddc6dfdbb291099aa3927a0e3e4ea6.pdf + +T. Teeramunkong, V. Sornlertlamvanich, T. Tanhermhong and W. Chinnan, “Character cluster based Thai information retrieval,” in IRAL '00 Proceedings of the fifth international workshop on on Information retrieval with Asian languages, 2000. \ No newline at end of file From e7adba46f7bf2304b0fe604e8ba9d4cf3767a3b1 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Sun, 25 Jun 2017 17:00:46 +0700 Subject: [PATCH 32/71] add thai soundex --- AUTHORS.rst | 5 +++ README.md | 6 ++++ docs/pythainlp-1-4-thai.md | 22 ++++++++++++ pythainlp/soundex.py | 72 ++++++++++++++++++++++++++++++++++++++ 4 files changed, 105 insertions(+) create mode 100644 pythainlp/soundex.py diff --git a/AUTHORS.rst b/AUTHORS.rst index 1f70fce22..842282fe7 100644 --- a/AUTHORS.rst +++ b/AUTHORS.rst @@ -7,6 +7,11 @@ Development Lead * Wannaphong Phatthiyaphaibun +TCC & THAI SOUNDEX CODE +------------ + +* Korakot Chaovavanich + Contributors ------------ diff --git a/README.md b/README.md index 1d4cec74b..017b4c096 100644 --- a/README.md +++ b/README.md @@ -31,6 +31,7 @@ Natural language processing หรือ การประมวลภาษา - Thai WordNet ตัวใหม่ - เพิ่มหลักเกณฑ์การถอดอักษรไทยเป็นอักษรโรมัน ฉบับราชบัณฑิตยสถาน - เพิ่ม Meta Sound ภาษาไทย +- เพิ่ม Thai Soundex ### ความสามารถ - ตัดคำภาษาไทย @@ -40,6 +41,11 @@ Natural language processing หรือ การประมวลภาษา - เรียงจำนวนคำของประโยค - แก้ไขปัญหาการพิมพ์ลืมเปลี่ยนภาษา - เช็คคำผิดในภาษาไทย + - รองรับ Thai Character Clusters (TCC) และ ETCC + - Thai WordNet + - Stop Word ภาษาไทย + - Meta Sound ภาษาไทย + - Thai Soundex - และอื่น ๆ # ติดตั้ง diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 885895236..675be86ca 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -268,6 +268,28 @@ grammar : คุณ Wittawat Jitkrittum (https://github.com/wittawatj/jtcc/blob/ '/คืน/ความสุข' ``` +### Thai Soundex ภาษาไทย + +เดติด คุณ Korakot Chaovavanich (จาก https://gist.github.com/korakot/0b772e09340cac2f493868da035597e8) + +กฎที่รองรับในเวชั่น 1.4 + +- กฎการเข้ารหัสซาวน์เด็กซ์ของ วิชิตหล่อจีระชุณห์กุล และ เจริญ คุวินทร์พันธุ์ + +**การใช้งาน** + +```python +>>> from pythainlp.soundex import LK82 +>>> print(LK82('รถ')) +ร3000 +>>> print(LK82('รด')) +ร3000 +>>> print(LK82('จัน')) +จ4000 +>>> print(LK82('จันทร์')) +จ4000 +``` + ### Meta Sound ภาษาไทย ``` diff --git a/pythainlp/soundex.py b/pythainlp/soundex.py new file mode 100644 index 000000000..d5a765dcd --- /dev/null +++ b/pythainlp/soundex.py @@ -0,0 +1,72 @@ +''' +Thai soundex + +โค้ดพัฒนาโดย คุณ Korakot Chaovavanich (จาก https://gist.github.com/korakot/0b772e09340cac2f493868da035597e8) +''' +import re +def LK82(s): + ''' + LK82 - กฎการเข้ารหัสซาวน์เด็กซ์ของ วิชิตหล่อจีระชุณห์กุล และ เจริญ คุวินทร์พันธุ์ + LK82(str) + ''' + t1 = str.maketrans("กขฃคฅฆงจฉชฌซศษสญยฎดฏตณนฐฑฒถทธบปผพภฝฟมรลฬฤฦวหฮอ","กกกกกกงจชชชซซซซยยดดตตนนททททททบปพพพฟฟมรรรรรวหหอ") + t2 = str.maketrans("กขฃคฅฆงจฉชซฌฎฏฐฑฒดตถทธศษสญณนรลฬฤฦบปพฟภผฝมำยวไใหฮาๅึืเแโุูอ","1111112333333333333333333444444445555555667777889AAABCDEEF") + res = [] + s = re.sub("[่-๋]", "", s) # 4.ลบวรรณยุกต์ + if re.search("[ก-ฮ][ิุู]?์",s): + # 4.ลบการันต์ + # เนื่องจากภาษาไทยมีตัวการ์รันต์ เช่น ตร์ ทร์ ดร์ อยู่ด้วย จึงต้องเอาออกไปด้วย + if re.search("ตร์",s): + s = re.sub("ตร์","",s) + elif re.search("ทร์",s): + s = re.sub("ทร์","",s) + elif re.search("ดร์",s): + s = re.sub("ทร์","",s) + else: + s = re.sub("[ก-ฮ][ิุู]?์", "", s) + s = re.sub("[็ํฺๆฯ]", "", s) # 5.ทิ้งไม้ไต่คู่ ฯลฯ + # 6.เข้ารหัสตัวแรก + if 'ก'<=s[0]<='ฮ': + res.append(s[0].translate(t1)) + s = s[1:] + else: + s = s[1:] + res.append(s[0].translate(t2)) + s = s[2:] + # เข้ารหัสตัวที่เหลือ + i_v = None # ตำแหน่งตัวคั่นล่าสุด (สระ) + for i,c in enumerate(s): + if c in "ะัิี": # 7. ตัวคั่นเฉยๆ + i_v = i + res.append('') + elif c in "าๅึืู": # 8.คั่นและใส่ + i_v = i + res.append(c.translate(t2)) + elif c == 'ุ': # 9.สระอุ + i_v = i + if i==0 or (s[i-1] not in "ตธ"): + res.append(c.translate(t2)) + else: + res.append('') + elif c in 'หอ': + if i+1 Date: Sun, 25 Jun 2017 17:12:07 +0700 Subject: [PATCH 33/71] add thai soundex api --- pythainlp/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pythainlp/__init__.py b/pythainlp/__init__.py index a0267011c..b681d075a 100644 --- a/pythainlp/__init__.py +++ b/pythainlp/__init__.py @@ -18,3 +18,4 @@ from pythainlp.test import * from pythainlp.Text import * from pythainlp.MetaSound import * +from pythainlp.soundex import * From da9edc03d13603b708c8f36cdd8edb4e0f1f21d9 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Mon, 26 Jun 2017 12:02:09 +0700 Subject: [PATCH 34/71] add extract_keyword --- pythainlp/tokenize/mm.py | 45 +++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/pythainlp/tokenize/mm.py b/pythainlp/tokenize/mm.py index 8d6175254..00835ec1c 100644 --- a/pythainlp/tokenize/mm.py +++ b/pythainlp/tokenize/mm.py @@ -10,20 +10,37 @@ from __future__ import print_function from six.moves import range,zip +import codecs import re from .thai import newdata # load dictionary from pythainlp.corpus import stopwords # load stopwords -#import marisa_trie +import marisa_trie class wordcut(object): - def __init__(self, removeRepeat=True, stopDictionary="", removeSpaces=True, minLength=1, stopNumber=False, removeNonCharacter=False, caseSensitive=True, ngram=(1,1), negation=False): + def __init__(self, removeRepeat=True, keyDictionary="", stopDictionary="", removeSpaces=True, minLength=1, stopNumber=False, removeNonCharacter=False, caseSensitive=True, ngram=(1,1), negation=False): d = newdata() # load dictionary # load negation listdir - self.negationDict = ['ไม่','แต่'] + self.negationDict = [] + if negation: + self.negationDict = ['ไม่','แต่'] self.stopword = False - self.stopdict = stopwords.words('thai') + self.stopdict = [] + if(stopDictionary is not ""): + self.stopword = True + with codecs.open(stopDictionary, 'r',encoding='utf8') as f: + for line in f: + self.stopdict.append(line) + else: + self.stopdict = stopwords.words('thai') + self.keyword = False + self.keydict = [] + if(keyDictionary is not ""): + self.keyword = True + with codecs.open(keyDictionary, 'r',encoding='utf8') as f: + for line in f.read().splitlines(): + self.keydict.append(line) - self.trie = d + self.trie = marisa_trie.Trie(d) self.removeRepeat = removeRepeat self.stopNumber = stopNumber self.removeSpaces = removeSpaces @@ -80,7 +97,7 @@ def searchTrie(self, word): if longest > 20: for data in self.trie.keys(word[0:longest]): - if(len(data) > longest): + if len(data) > longest: if data in word[0:len(data)]: longest = len(data) maxData = data @@ -110,6 +127,20 @@ def transform(self, wordArray): return wordArray + def extract_keyword(self, wordArray): + resultArray = [] + for dd in wordArray: + try: + if self.caseSensitive: + if dd in self.keydict: + resultArray.append(dd) + else: + if dd.lower() in self.keydict: + resultArray.append(dd) + except ValueError: + pass + + return resultArray # c = sentence which represent as char # N = number of character def find_segment(self, c): @@ -249,4 +280,4 @@ def mergelistlen(listdata,lennum): return listdata def segment(text): pt = wordcut(stopNumber=False, removeNonCharacter=True, caseSensitive=False,removeRepeat=True) - return mergelistlen(pt.segment(text),1) + return mergelistlen(pt.segment(text),1) \ No newline at end of file From d6059aeb5a75ebafa74ea3fc4390b51605343a23 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 27 Jun 2017 13:13:09 +0700 Subject: [PATCH 35/71] add coveralls --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 017b4c096..b3a5f67d1 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![pypi](https://img.shields.io/pypi/v/pythainlp.svg)](https://pypi.python.org/pypi/pythainlp) [![Build Status](https://travis-ci.org/wannaphongcom/pythainlp.svg?branch=develop)](https://travis-ci.org/wannaphongcom/pythainlp) [![Build status](https://ci.appveyor.com/api/projects/status/uxerymgggp1uch0p?svg=true)](https://ci.appveyor.com/project/wannaphongcom/pythainlp) +[![Coverage Status](https://coveralls.io/repos/github/wannaphongcom/pythainlp/badge.svg?branch=pythainlp1.4)](https://coveralls.io/github/wannaphongcom/pythainlp?branch=pythainlp1.4) Homepages :[https://sites.google.com/view/pythainlp/home](https://sites.google.com/view/pythainlp/home) From 92f16b24f6e7a5d33d83738745b30d3aa32ff301 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 27 Jun 2017 13:21:38 +0700 Subject: [PATCH 36/71] fix travis --- .travis.yml | 2 +- requirements.txt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 requirements.txt diff --git a/.travis.yml b/.travis.yml index 653cf3d3e..4f93a48a5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ python: - "3.5" - "3.6" # command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors -install: pip install -U tox +install: pip install -r requirements.txt os: - linux diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 000000000..d4f03bec2 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,6 @@ +pyicu +nltk>=3.2.2 +future>=0.16.0 +six +marisa_trie +langdetect From 7a1b5b4b158c36e5569499be9cc4214dfe3ec310 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 27 Jun 2017 13:25:51 +0700 Subject: [PATCH 37/71] fix travis --- .travis.yml | 2 +- requirements-travis.txt | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 requirements-travis.txt diff --git a/.travis.yml b/.travis.yml index 4f93a48a5..39ac27b18 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,7 +7,7 @@ python: - "3.5" - "3.6" # command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors -install: pip install -r requirements.txt +install: pip install -r requirements-travis.txt os: - linux diff --git a/requirements-travis.txt b/requirements-travis.txt new file mode 100644 index 000000000..73a7a63a9 --- /dev/null +++ b/requirements-travis.txt @@ -0,0 +1,6 @@ +pyicu==1.9.3 +nltk>=3.2.2 +future>=0.16.0 +six +marisa_trie +langdetect From a6cf0aa263dd451339659a0ed01a60cc4d5d5591 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 27 Jun 2017 23:04:18 +0700 Subject: [PATCH 38/71] fix appveyor --- appveyor.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 appveyor.yml diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000..c9efefcc9 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,20 @@ +build: false + +environment: + matrix: + - PYTHON: "C:/Python35" + - PYTHON: "C:/Python36" + +init: + - "ECHO %PYTHON%" + - ps: "ls C:/Python*" + +install: + # FIXME: updating pip fails with PermissionError + # - "%PYTHON%/Scripts/pip.exe install -U pip setuptools" + - "%PYTHON%/Scripts/pip.exe install -e ." + +test_script: + - "%PYTHON%/Scripts/pip.exe --version" + - "%PYTHON%/Scripts/http.exe --debug" + - "%PYTHON%/python.exe setup.py test" From 60a99b063360662a3dfa2bcb3afbc02ec88d8d00 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 27 Jun 2017 23:09:50 +0700 Subject: [PATCH 39/71] add coveralls --- .coveralls.yml | 1 + 1 file changed, 1 insertion(+) create mode 100644 .coveralls.yml diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 000000000..67e4706de --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1 @@ +repo_token: 5ePOifPYAFJegC6aJxwhFP5zLRaOjDhhwBujw From 8d3a108cd21715b878834a9f9b9a390601bcdb2e Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 27 Jun 2017 23:13:00 +0700 Subject: [PATCH 40/71] fix coveralls --- .coveralls.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.coveralls.yml b/.coveralls.yml index 67e4706de..6683b0fae 100644 --- a/.coveralls.yml +++ b/.coveralls.yml @@ -1 +1 @@ -repo_token: 5ePOifPYAFJegC6aJxwhFP5zLRaOjDhhwBujw +repo_token: dG5Q7pqy4FO1J5WgV39WsZm4zMyS8qyBA From a77a82ec0909555c9fe250573e4f056b9a77a177 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 27 Jun 2017 23:20:04 +0700 Subject: [PATCH 41/71] fix coveralls --- .coveralls.yml | 1 - .travis.yml | 9 +++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 .coveralls.yml diff --git a/.coveralls.yml b/.coveralls.yml deleted file mode 100644 index 6683b0fae..000000000 --- a/.coveralls.yml +++ /dev/null @@ -1 +0,0 @@ -repo_token: dG5Q7pqy4FO1J5WgV39WsZm4zMyS8qyBA diff --git a/.travis.yml b/.travis.yml index 39ac27b18..d398b1ee6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,12 +7,17 @@ python: - "3.5" - "3.6" # command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors -install: pip install -r requirements-travis.txt +install: + - pip install -r requirements-travis.txt + - pip install coveralls os: - linux # command to run tests, e.g. python setup.py test -script: python setup.py test +script: + coverage run --source=yourpackagename setup.py test +after_success: + coveralls # After you create the Github repo and add it to Travis, run the # travis_pypi_setup.py script to finish PyPI deployment setup From 850e317d6b2606d83c3c18b761975578e9097600 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 27 Jun 2017 23:23:31 +0700 Subject: [PATCH 42/71] fix test --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d398b1ee6..a44fee55c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -15,7 +15,7 @@ os: - linux # command to run tests, e.g. python setup.py test script: - coverage run --source=yourpackagename setup.py test + coverage run --source=pythainlp setup.py test after_success: coveralls From 170b9cc923441af4ce8099e26b250bf3094093de Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 27 Jun 2017 23:41:54 +0700 Subject: [PATCH 43/71] add test --- README.md | 3 +-- .../{build_pythainlp.py => build_pythainlp.tool} | 0 pythainlp/test/__init__.py | 13 +++++++++++++ 3 files changed, 14 insertions(+), 2 deletions(-) rename pythainlp/sentiment/{build_pythainlp.py => build_pythainlp.tool} (100%) diff --git a/README.md b/README.md index b3a5f67d1..89da6e1ef 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ [![PyPI Downloads](https://img.shields.io/pypi/dm/pythainlp.png)] [![pypi](https://img.shields.io/pypi/v/pythainlp.svg)](https://pypi.python.org/pypi/pythainlp) [![Build Status](https://travis-ci.org/wannaphongcom/pythainlp.svg?branch=develop)](https://travis-ci.org/wannaphongcom/pythainlp) -[![Build status](https://ci.appveyor.com/api/projects/status/uxerymgggp1uch0p?svg=true)](https://ci.appveyor.com/project/wannaphongcom/pythainlp) -[![Coverage Status](https://coveralls.io/repos/github/wannaphongcom/pythainlp/badge.svg?branch=pythainlp1.4)](https://coveralls.io/github/wannaphongcom/pythainlp?branch=pythainlp1.4) +[![Build status](https://ci.appveyor.com/api/projects/status/uxerymgggp1uch0p?svg=true)](https://ci.appveyor.com/project/wannaphongcom/pythainlp)[![Code Issues](https://www.quantifiedcode.com/api/v1/project/7f699ed4cad24be18d0d24ebd60d7543/badge.svg)](https://www.quantifiedcode.com/app/project/7f699ed4cad24be18d0d24ebd60d7543)[![Coverage Status](https://coveralls.io/repos/github/wannaphongcom/pythainlp/badge.svg?branch=pythainlp1.4)](https://coveralls.io/github/wannaphongcom/pythainlp?branch=pythainlp1.4) Homepages :[https://sites.google.com/view/pythainlp/home](https://sites.google.com/view/pythainlp/home) diff --git a/pythainlp/sentiment/build_pythainlp.py b/pythainlp/sentiment/build_pythainlp.tool similarity index 100% rename from pythainlp/sentiment/build_pythainlp.py rename to pythainlp/sentiment/build_pythainlp.tool diff --git a/pythainlp/test/__init__.py b/pythainlp/test/__init__.py index 645e7b0c6..e847c166b 100644 --- a/pythainlp/test/__init__.py +++ b/pythainlp/test/__init__.py @@ -11,6 +11,9 @@ from pythainlp.tag import pos_tag from pythainlp.romanization import romanization from pythainlp.date import now +from pythainlp.tokenize import tcc,etcc +from pythainlp.soundex import LK82 +from pythainlp.MetaSound import * from collections import namedtuple Synset = namedtuple('Synset', 'synset li') class TestUM(unittest.TestCase): @@ -18,6 +21,8 @@ def testSegment(self): self.assertEqual(word_tokenize('ฉันรักภาษาไทยเพราะฉันเป็นคนไทย'),[u'ฉัน', u'รัก', u'ภาษา', u'ไทย', u'เพราะ', u'ฉัน', u'เป็น', u'คน', u'ไทย']) def testSegmentDict(self): self.assertEqual(word_tokenize('ฉันรักภาษาไทยเพราะฉันเป็นคนไทย',engine='dict'),[u'ฉัน', u'รัก', u'ภาษาไทย', u'เพราะ', u'ฉัน', u'เป็น', u'คนไทย']) + def testSegmentMM(self): + self.assertEqual(word_tokenize('ฉันรักภาษาไทยเพราะฉันเป็นคนไทย',engine='mm'),[u'ฉัน', u'รัก', u'ภาษาไทย', u'เพราะ', u'ฉัน', u'เป็น', u'คนไทย']) def testRank(self): self.assertEqual(rank(["แมว","คน","แมว"]),Counter({'แมว': 2, 'คน': 1})) def testChange(self): @@ -26,6 +31,14 @@ def testRomanization(self): self.assertEqual(romanization("แมว"),'mæw') def testNumber(self): self.assertEqual(numtowords(5611116.50),'ห้าล้านหกแสนหนึ่งหมื่นหนึ่งพันหนึ่งร้อยสิบหกบาทห้าสิบสตางค์') + def testTCC(self): + self.assertEqual(tcc.tcc('ประเทศไทย'),'ป/ระ/เท/ศ/ไท/ย') + def testETCC(self): + self.assertEqual(etcc.etcc('คืนความสุข'),'/คืน/ความสุข') + def testLK82(self): + self.assertEqual(LK82('รถ'),'ร3000') + def testMS(self): + self.assertEqual(MetaSound('คน'),'15') def testTag(self): self.assertEqual(pos_tag(word_tokenize("คุณกำลังประชุม"),engine='old'),[('คุณ', 'PPRS'), ('กำลัง', 'XVBM'), ('ประชุม', 'VACT')]) def testTagnew(self): From 1c1e0d05734b64ba5295aba8876aa2a4a480cbd9 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Tue, 27 Jun 2017 23:56:23 +0700 Subject: [PATCH 44/71] add test --- pythainlp/corpus/{make-stopword.py => make-stopword.tool} | 0 pythainlp/test/__init__.py | 6 +++++- 2 files changed, 5 insertions(+), 1 deletion(-) rename pythainlp/corpus/{make-stopword.py => make-stopword.tool} (100%) diff --git a/pythainlp/corpus/make-stopword.py b/pythainlp/corpus/make-stopword.tool similarity index 100% rename from pythainlp/corpus/make-stopword.py rename to pythainlp/corpus/make-stopword.tool diff --git a/pythainlp/test/__init__.py b/pythainlp/test/__init__.py index e847c166b..49eface86 100644 --- a/pythainlp/test/__init__.py +++ b/pythainlp/test/__init__.py @@ -27,8 +27,10 @@ def testRank(self): self.assertEqual(rank(["แมว","คน","แมว"]),Counter({'แมว': 2, 'คน': 1})) def testChange(self): self.assertEqual(texttothai("l;ylfu8iy["),'สวัสดีครับ') - def testRomanization(self): + def testRomanization1(self): self.assertEqual(romanization("แมว"),'mæw') + def testRomanization2(self): + self.assertEqual(romanization("แมว",engine="royin"),'maeo') def testNumber(self): self.assertEqual(numtowords(5611116.50),'ห้าล้านหกแสนหนึ่งหมื่นหนึ่งพันหนึ่งร้อยสิบหกบาทห้าสิบสตางค์') def testTCC(self): @@ -39,6 +41,8 @@ def testLK82(self): self.assertEqual(LK82('รถ'),'ร3000') def testMS(self): self.assertEqual(MetaSound('คน'),'15') + def testWORDNET(self): + self.assertEqual(wordnet.synset('spy.n.01').lemma_names('tha'),['สปาย', 'สายลับ']) def testTag(self): self.assertEqual(pos_tag(word_tokenize("คุณกำลังประชุม"),engine='old'),[('คุณ', 'PPRS'), ('กำลัง', 'XVBM'), ('ประชุม', 'VACT')]) def testTagnew(self): From c6dddacc9c95a0a4e979b131131ae561e874195a Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 28 Jun 2017 00:00:59 +0700 Subject: [PATCH 45/71] fix install wordnet --- pythainlp/corpus/wordnet.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pythainlp/corpus/wordnet.py b/pythainlp/corpus/wordnet.py index 094533ee9..43f510c79 100644 --- a/pythainlp/corpus/wordnet.py +++ b/pythainlp/corpus/wordnet.py @@ -5,6 +5,7 @@ nltk.data.find("corpora/omw") except: nltk.download('omw') + nltk.download('wordnet') from nltk.corpus import wordnet ''' API ตัวเก่า From 91cd669b800e9627b29237130ac06adbc4ab7eb4 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 28 Jun 2017 00:07:28 +0700 Subject: [PATCH 46/71] add test --- pythainlp/test/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pythainlp/test/__init__.py b/pythainlp/test/__init__.py index 49eface86..2966774c9 100644 --- a/pythainlp/test/__init__.py +++ b/pythainlp/test/__init__.py @@ -11,7 +11,7 @@ from pythainlp.tag import pos_tag from pythainlp.romanization import romanization from pythainlp.date import now -from pythainlp.tokenize import tcc,etcc +from pythainlp.tokenize import tcc,etcc,isthai from pythainlp.soundex import LK82 from pythainlp.MetaSound import * from collections import namedtuple @@ -41,8 +41,11 @@ def testLK82(self): self.assertEqual(LK82('รถ'),'ร3000') def testMS(self): self.assertEqual(MetaSound('คน'),'15') + def testISTHAI(self): + self.assertEqual(isthai('ค'),True) def testWORDNET(self): self.assertEqual(wordnet.synset('spy.n.01').lemma_names('tha'),['สปาย', 'สายลับ']) + self.assertEqual(wordnet.langs()!=None,True) def testTag(self): self.assertEqual(pos_tag(word_tokenize("คุณกำลังประชุม"),engine='old'),[('คุณ', 'PPRS'), ('กำลัง', 'XVBM'), ('ประชุม', 'VACT')]) def testTagnew(self): From cb655f5bd768d94064e096b13e33d40189473c61 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 28 Jun 2017 00:20:10 +0700 Subject: [PATCH 47/71] fix test --- pythainlp/corpus/__init__.py | 6 ------ pythainlp/test/__init__.py | 8 +++++--- pythainlp/tokenize/{isthai.py => isthai.py.old} | 0 3 files changed, 5 insertions(+), 9 deletions(-) rename pythainlp/tokenize/{isthai.py => isthai.py.old} (100%) diff --git a/pythainlp/corpus/__init__.py b/pythainlp/corpus/__init__.py index 5e8d250c3..68e349a8f 100644 --- a/pythainlp/corpus/__init__.py +++ b/pythainlp/corpus/__init__.py @@ -1,9 +1,3 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import,unicode_literals #__all__ = ["thaipos", "thaiword","alphabet","tone","country","wordnet"] -from .thaipos import get_data -from .thaiword import get_data -from .alphabet import get_data -from .tone import get_data -from .country import get_data -from .stopwords import words diff --git a/pythainlp/test/__init__.py b/pythainlp/test/__init__.py index 2966774c9..1c251730c 100644 --- a/pythainlp/test/__init__.py +++ b/pythainlp/test/__init__.py @@ -11,8 +11,9 @@ from pythainlp.tag import pos_tag from pythainlp.romanization import romanization from pythainlp.date import now -from pythainlp.tokenize import tcc,etcc,isthai +from pythainlp.tokenize import tcc,etcc from pythainlp.soundex import LK82 +from pythainlp.corpus import stopwords from pythainlp.MetaSound import * from collections import namedtuple Synset = namedtuple('Synset', 'synset li') @@ -27,6 +28,7 @@ def testRank(self): self.assertEqual(rank(["แมว","คน","แมว"]),Counter({'แมว': 2, 'คน': 1})) def testChange(self): self.assertEqual(texttothai("l;ylfu8iy["),'สวัสดีครับ') + self.assertEqual(texttoeng('สวัสดีครับ'),"l;ylfu8iy[") def testRomanization1(self): self.assertEqual(romanization("แมว"),'mæw') def testRomanization2(self): @@ -41,11 +43,11 @@ def testLK82(self): self.assertEqual(LK82('รถ'),'ร3000') def testMS(self): self.assertEqual(MetaSound('คน'),'15') - def testISTHAI(self): - self.assertEqual(isthai('ค'),True) def testWORDNET(self): self.assertEqual(wordnet.synset('spy.n.01').lemma_names('tha'),['สปาย', 'สายลับ']) self.assertEqual(wordnet.langs()!=None,True) + def testSTOPWORD(self): + self.assertEqual(stopwords.words('thai')!=None,True) def testTag(self): self.assertEqual(pos_tag(word_tokenize("คุณกำลังประชุม"),engine='old'),[('คุณ', 'PPRS'), ('กำลัง', 'XVBM'), ('ประชุม', 'VACT')]) def testTagnew(self): diff --git a/pythainlp/tokenize/isthai.py b/pythainlp/tokenize/isthai.py.old similarity index 100% rename from pythainlp/tokenize/isthai.py rename to pythainlp/tokenize/isthai.py.old From 137eae722f1d0fa0220155ef1fc1ffcaed573661 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 28 Jun 2017 11:00:44 +0700 Subject: [PATCH 48/71] =?UTF-8?q?=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88?= =?UTF-8?q?=E0=B8=A1=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=AA=E0=B8=B4=E0=B8=97?= =?UTF-8?q?=E0=B8=98=E0=B8=B4=E0=B8=A0=E0=B8=B2=E0=B8=9E=E0=B9=82=E0=B8=84?= =?UTF-8?q?=E0=B9=89=E0=B8=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pythainlp/Text.py | 4 +-- pythainlp/__init__.py | 28 +++++++++---------- pythainlp/tokenize/__init__.py | 4 +-- .../tokenize/{dict.py => dictsegment.py} | 0 4 files changed, 18 insertions(+), 18 deletions(-) rename pythainlp/tokenize/{dict.py => dictsegment.py} (100%) diff --git a/pythainlp/Text.py b/pythainlp/Text.py index 573d034d9..eb2de5a32 100644 --- a/pythainlp/Text.py +++ b/pythainlp/Text.py @@ -1,8 +1,8 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import,unicode_literals -from pythainlp.tokenize import * +from pythainlp.tokenize import word_tokenize import nltk def Text(str1): if type(str1) != 'list': str1=word_tokenize(str(str1)) - return nltk.Text(str1) \ No newline at end of file + return nltk.Text(str1) diff --git a/pythainlp/__init__.py b/pythainlp/__init__.py index b681d075a..d6d16af5c 100644 --- a/pythainlp/__init__.py +++ b/pythainlp/__init__.py @@ -5,17 +5,17 @@ """ ไว้ใส่ความสามารถที่รองรับเฉพาะ Python 3.4+ เท่านั้น """ - from pythainlp.sentiment import * - from pythainlp.spell import * -from pythainlp.romanization import * -from pythainlp.tokenize import * -from pythainlp.rank import * -from pythainlp.change import * -from pythainlp.number import * -from pythainlp.date import * -from pythainlp.tag import * -from pythainlp.collation import * -from pythainlp.test import * -from pythainlp.Text import * -from pythainlp.MetaSound import * -from pythainlp.soundex import * + from pythainlp.sentiment import sentiment + from pythainlp.spell import hunspell,spell +from pythainlp.romanization import romanization,pyicu,royin +from pythainlp.tokenize import word_tokenize,mm,dictsegment,pyicu,tcc,etcc,thai,pylexto +from pythainlp.rank import rank +from pythainlp.change import texttothai,texttoeng +from pythainlp.number import nttn,nttt,ntnt,ntt,ttn,ttnt,number_format,numtowords,ReadNumber +from pythainlp.date import now +from pythainlp.tag import old,pos_tag +from pythainlp.collation import collation +from pythainlp.test import TestUM +from pythainlp.Text import Text +from pythainlp.MetaSound import MetaSound +from pythainlp.soundex import LK82 \ No newline at end of file diff --git a/pythainlp/tokenize/__init__.py b/pythainlp/tokenize/__init__.py index 655c4645e..15a34ddf4 100644 --- a/pythainlp/tokenize/__init__.py +++ b/pythainlp/tokenize/__init__.py @@ -14,9 +14,9 @@ def word_tokenize(text,engine='icu'): if engine=='icu': from .pyicu import segment elif engine=='dict': - from .dict import segment + from .dictsegment import segment elif engine=='mm': from .mm import segment elif engine=='pylexto': from .pylexto import segment - return segment(text) \ No newline at end of file + return segment(text) diff --git a/pythainlp/tokenize/dict.py b/pythainlp/tokenize/dictsegment.py similarity index 100% rename from pythainlp/tokenize/dict.py rename to pythainlp/tokenize/dictsegment.py From 04afe97b1159b53df659ff2fdf4c3d67a9a560a4 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 28 Jun 2017 11:10:16 +0700 Subject: [PATCH 49/71] =?UTF-8?q?=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88?= =?UTF-8?q?=E0=B8=A1=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=AA=E0=B8=B4=E0=B8=97?= =?UTF-8?q?=E0=B8=98=E0=B8=B4=E0=B8=A0=E0=B8=B2=E0=B8=9E=E0=B9=82=E0=B8=84?= =?UTF-8?q?=E0=B9=89=E0=B8=94=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pythainlp/__init__.py | 2 +- pythainlp/test/__init__.py | 6 +++--- pythainlp/tokenize/mm.py | 12 +++++------- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/pythainlp/__init__.py b/pythainlp/__init__.py index d6d16af5c..dd03b902f 100644 --- a/pythainlp/__init__.py +++ b/pythainlp/__init__.py @@ -8,7 +8,7 @@ from pythainlp.sentiment import sentiment from pythainlp.spell import hunspell,spell from pythainlp.romanization import romanization,pyicu,royin -from pythainlp.tokenize import word_tokenize,mm,dictsegment,pyicu,tcc,etcc,thai,pylexto +from pythainlp.tokenize import word_tokenize,tcc,etcc from pythainlp.rank import rank from pythainlp.change import texttothai,texttoeng from pythainlp.number import nttn,nttt,ntnt,ntt,ttn,ttnt,number_format,numtowords,ReadNumber diff --git a/pythainlp/test/__init__.py b/pythainlp/test/__init__.py index 1c251730c..0636b5328 100644 --- a/pythainlp/test/__init__.py +++ b/pythainlp/test/__init__.py @@ -6,7 +6,7 @@ from pythainlp.corpus import wordnet from pythainlp.tokenize import word_tokenize from pythainlp.rank import rank -from pythainlp.change import * +from pythainlp.change import texttothai,texttoeng from pythainlp.number import numtowords from pythainlp.tag import pos_tag from pythainlp.romanization import romanization @@ -14,7 +14,7 @@ from pythainlp.tokenize import tcc,etcc from pythainlp.soundex import LK82 from pythainlp.corpus import stopwords -from pythainlp.MetaSound import * +from pythainlp.MetaSound import MetaSound from collections import namedtuple Synset = namedtuple('Synset', 'synset li') class TestUM(unittest.TestCase): @@ -54,4 +54,4 @@ def testTagnew(self): if sys.version_info > (3,3): self.assertEqual(pos_tag(word_tokenize("ผมรักคุณ"),engine='artagger'),[('ผม', 'PPRS'), ('รัก', 'VSTA'), ('คุณ', 'PPRS')]) if __name__ == '__main__': - unittest.main() \ No newline at end of file + unittest.main() diff --git a/pythainlp/tokenize/mm.py b/pythainlp/tokenize/mm.py index 00835ec1c..f68b3495c 100644 --- a/pythainlp/tokenize/mm.py +++ b/pythainlp/tokenize/mm.py @@ -97,10 +97,9 @@ def searchTrie(self, word): if longest > 20: for data in self.trie.keys(word[0:longest]): - if len(data) > longest: - if data in word[0:len(data)]: - longest = len(data) - maxData = data + if len(data) > longest and data in word[0:len(data)]: + longest = len(data) + maxData = data if maxData: @@ -131,9 +130,8 @@ def extract_keyword(self, wordArray): resultArray = [] for dd in wordArray: try: - if self.caseSensitive: - if dd in self.keydict: - resultArray.append(dd) + if self.caseSensitive and dd in self.keydict: + resultArray.append(dd) else: if dd.lower() in self.keydict: resultArray.append(dd) From db2835f139c35d07a64f2f53d77565bcd4bc6a31 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 28 Jun 2017 11:20:44 +0700 Subject: [PATCH 50/71] =?UTF-8?q?=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88?= =?UTF-8?q?=E0=B8=A1=E0=B9=80=E0=B8=AD=E0=B8=81=E0=B8=AA=E0=B8=B2=E0=B8=A3?= =?UTF-8?q?=E0=B8=82=E0=B8=AD=E0=B8=87=20Corpus?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/pythainlp-1-4-thai.md | 41 +++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 675be86ca..79a46d3b6 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -200,13 +200,6 @@ Synset('one.s.05') ['สปาย', 'สายลับ'] ``` -### stopword ภาษาไทย - -```python -from pythainlp.corpus import stopwords -stopwords = stopwords.words('thai') -``` - ### หาคำที่มีจำนวนการใช้งานมากที่สุด ```python @@ -293,7 +286,7 @@ grammar : คุณ Wittawat Jitkrittum (https://github.com/wittawatj/jtcc/blob/ ### Meta Sound ภาษาไทย ``` -Snae & Brückner. (2009). Novel Phonetic Name Matching Algorithm with a Statistical Ontology for Analysing Names Given in Accordance with Thai Astrology. Retrieved from https://pdfs.semanticscholar.org/3983/963e87ddc6dfdbb291099aa3927a0e3e4ea6.pdf +Snae & Brückner. (2009). Novel Phonetic Name Matching Algorithm with a Statistical Ontology for Analysing Names Given in Accordance with Thai Astrology. Retrieved from https://pdfs.semanticscholar.org/3983/963e87ddc6dfdbb291099aa3927a0e3e4ea6.pdf ``` **การใช้งาน** @@ -306,7 +299,7 @@ Snae & Brückner. (2009). Novel Phonetic Name Matching Algorithm with a Statisti ### Sentiment analysis ภาษาไทย -ใช้ข้อมูลจาก https://github.com/wannaphongcom/lexicon-thai/tree/master/ข้อความ/ +ใช้ข้อมูลจาก [https://github.com/wannaphongcom/lexicon-thai/tree/master/ข้อความ/](https://github.com/wannaphongcom/lexicon-thai/tree/master/ข้อความ/) ```python from pythainlp.sentiment import sentiment @@ -315,6 +308,36 @@ sentiment(str) รับค่า str ส่งออกเป็น pos , neg หรือ neutral +### Corpus + +#### stopword ภาษาไทย + +```python +from pythainlp.corpus import stopwords +stopwords = stopwords.words('thai') +``` + +#### ชื่อประเทศ ภาษาไทย + +```python +from pythainlp.corpus import country +country.get_data() +``` + +#### ตัววรรณยุกต์ในภาษาไทย + +```python +from pythainlp.corpus import tone +tone.get_data() +``` + +#### ตัวพยัญชนะในภาษาไทย + +```python +from pythainlp.corpus import alphabet +alphabet.get_data() +``` + เขียนโดย นาย วรรณพงษ์ ภัททิยไพบูลย์ \ No newline at end of file From 10813c10736868697e4bce0249291c0b497d8bea Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 28 Jun 2017 11:31:37 +0700 Subject: [PATCH 51/71] =?UTF-8?q?=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B8=A1?= =?UTF-8?q?=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=AA=E0=B8=B4=E0=B8=97=E0=B8=98?= =?UTF-8?q?=E0=B8=B4=E0=B8=A0=E0=B8=B2=E0=B8=9E=203?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pythainlp/test/__init__.py | 32 ++++++++++++++++---------------- pythainlp/tokenize/mm.py | 3 +++ 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/pythainlp/test/__init__.py b/pythainlp/test/__init__.py index 0636b5328..1d0420503 100644 --- a/pythainlp/test/__init__.py +++ b/pythainlp/test/__init__.py @@ -18,39 +18,39 @@ from collections import namedtuple Synset = namedtuple('Synset', 'synset li') class TestUM(unittest.TestCase): - def testSegment(self): + def test_segment(self): self.assertEqual(word_tokenize('ฉันรักภาษาไทยเพราะฉันเป็นคนไทย'),[u'ฉัน', u'รัก', u'ภาษา', u'ไทย', u'เพราะ', u'ฉัน', u'เป็น', u'คน', u'ไทย']) - def testSegmentDict(self): + def test_segment_dict(self): self.assertEqual(word_tokenize('ฉันรักภาษาไทยเพราะฉันเป็นคนไทย',engine='dict'),[u'ฉัน', u'รัก', u'ภาษาไทย', u'เพราะ', u'ฉัน', u'เป็น', u'คนไทย']) - def testSegmentMM(self): + def test_segment_mm(self): self.assertEqual(word_tokenize('ฉันรักภาษาไทยเพราะฉันเป็นคนไทย',engine='mm'),[u'ฉัน', u'รัก', u'ภาษาไทย', u'เพราะ', u'ฉัน', u'เป็น', u'คนไทย']) - def testRank(self): + def test_rank(self): self.assertEqual(rank(["แมว","คน","แมว"]),Counter({'แมว': 2, 'คน': 1})) - def testChange(self): + def test_change(self): self.assertEqual(texttothai("l;ylfu8iy["),'สวัสดีครับ') self.assertEqual(texttoeng('สวัสดีครับ'),"l;ylfu8iy[") - def testRomanization1(self): + def test_romanization1(self): self.assertEqual(romanization("แมว"),'mæw') - def testRomanization2(self): + def test_romanization2(self): self.assertEqual(romanization("แมว",engine="royin"),'maeo') - def testNumber(self): + def test_number(self): self.assertEqual(numtowords(5611116.50),'ห้าล้านหกแสนหนึ่งหมื่นหนึ่งพันหนึ่งร้อยสิบหกบาทห้าสิบสตางค์') - def testTCC(self): + def test_tcc(self): self.assertEqual(tcc.tcc('ประเทศไทย'),'ป/ระ/เท/ศ/ไท/ย') - def testETCC(self): + def test_etcc(self): self.assertEqual(etcc.etcc('คืนความสุข'),'/คืน/ความสุข') - def testLK82(self): + def test_lk82(self): self.assertEqual(LK82('รถ'),'ร3000') - def testMS(self): + def test_ms(self): self.assertEqual(MetaSound('คน'),'15') - def testWORDNET(self): + def test_wordnet(self): self.assertEqual(wordnet.synset('spy.n.01').lemma_names('tha'),['สปาย', 'สายลับ']) self.assertEqual(wordnet.langs()!=None,True) - def testSTOPWORD(self): + def test_stopword(self): self.assertEqual(stopwords.words('thai')!=None,True) - def testTag(self): + def test_tag(self): self.assertEqual(pos_tag(word_tokenize("คุณกำลังประชุม"),engine='old'),[('คุณ', 'PPRS'), ('กำลัง', 'XVBM'), ('ประชุม', 'VACT')]) - def testTagnew(self): + def test_tag_new(self): if sys.version_info > (3,3): self.assertEqual(pos_tag(word_tokenize("ผมรักคุณ"),engine='artagger'),[('ผม', 'PPRS'), ('รัก', 'VSTA'), ('คุณ', 'PPRS')]) if __name__ == '__main__': diff --git a/pythainlp/tokenize/mm.py b/pythainlp/tokenize/mm.py index f68b3495c..b51b02502 100644 --- a/pythainlp/tokenize/mm.py +++ b/pythainlp/tokenize/mm.py @@ -17,6 +17,9 @@ import marisa_trie class wordcut(object): + """ + ตัดคำภาษาไทยด้วย Maximum Matching algorithm + """ def __init__(self, removeRepeat=True, keyDictionary="", stopDictionary="", removeSpaces=True, minLength=1, stopNumber=False, removeNonCharacter=False, caseSensitive=True, ngram=(1,1), negation=False): d = newdata() # load dictionary # load negation listdir From 2e305ff55e6d82ad14e4ffd51b7d18df0c568a77 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 28 Jun 2017 11:40:56 +0700 Subject: [PATCH 52/71] =?UTF-8?q?=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88?= =?UTF-8?q?=E0=B8=A1=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=AA=E0=B8=B4=E0=B8=97?= =?UTF-8?q?=E0=B8=98=E0=B8=B4=E0=B8=A0=E0=B8=B2=E0=B8=9E=204?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pythainlp/romanization/royin.py | 20 ++++++++++---------- pythainlp/tokenize/mm.py | 28 ++++++++++++++-------------- 2 files changed, 24 insertions(+), 24 deletions(-) diff --git a/pythainlp/romanization/royin.py b/pythainlp/romanization/royin.py index 37a45c472..9f1d569ab 100644 --- a/pythainlp/romanization/royin.py +++ b/pythainlp/romanization/royin.py @@ -13,7 +13,7 @@ from pythainlp.tokenize import tcc from pythainlp.tokenize import etcc import re -Consonants = { # พยัญชนะ ต้น สะกด +consonants = { # พยัญชนะ ต้น สะกด 'ก':['k','k'], 'ข':['kh','k'], 'ฃ':['kh','k'], @@ -59,7 +59,7 @@ 'อ':['',''], 'ฮ':['h',''] } -Consonantsthai= u'[กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬฮ]' +consonants_thai= u'[กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬฮ]' def deletetone(data): #โค้ดส่วนตัดวรรณยุกต์ออก for tone in ['่','้','๊','๋']: @@ -537,32 +537,32 @@ def romanization(text): ''' ใช้ในกรณีคำนั้นมีสระด้วย จะได้เอาพยัญชนะตัวแรกไปเทียบ ''' - d=re.search(Consonantsthai,text,re.U) - text=re.sub(d.group(0),Consonants[d.group(0)][0],text,flags=re.U) + d=re.search(consonants_thai,text,re.U) + text=re.sub(d.group(0),consonants[d.group(0)][0],text,flags=re.U) listtext=list(text) - if re.search(Consonantsthai,listtext[0], re.U): + if re.search(consonants_thai,listtext[0], re.U): ''' จัดการกับพยัญชนะต้น ''' - listtext[0]=Consonants[listtext[0]][0] + listtext[0]=consonants[listtext[0]][0] two=False if len(listtext)==2: - if re.search(Consonantsthai,listtext[1], re.U): + if re.search(consonants_thai,listtext[1], re.U): ''' จัดการกับพยัญชนะ 2 ตัว และมีแค่ 2 ตั และมีแค่ 2 ตัวติดกันในคำ ''' - listtext.append(Consonants[listtext[1]][1]) + listtext.append(consonants[listtext[1]][1]) listtext[1]='o' two=True else: two=False i=0 while i 20: for data in self.trie.keys(word[0:longest]): if len(data) > longest and data in word[0:len(data)]: longest = len(data) - maxData = data + max_data = data - if maxData: + if max_data: try: # Special check for case like ๆ - if word[len(maxData)] == 'ๆ': - return word[0:(len(maxData) + 1)] + if word[len(max_data)] == 'ๆ': + return word[0:(len(max_data) + 1)] else: - return maxData + return max_data except: - return maxData + return max_data else: return -1 @@ -130,18 +130,18 @@ def transform(self, wordArray): return wordArray def extract_keyword(self, wordArray): - resultArray = [] + result_array = [] for dd in wordArray: try: if self.caseSensitive and dd in self.keydict: - resultArray.append(dd) + result_array.append(dd) else: if dd.lower() in self.keydict: - resultArray.append(dd) + result_array.append(dd) except ValueError: pass - return resultArray + return result_array # c = sentence which represent as char # N = number of character def find_segment(self, c): @@ -149,7 +149,7 @@ def find_segment(self, c): N = len(c) arr = [] while(i < N): - j = self.searchTrie(c[i:N]) + j = self.search_trie(c[i:N]) if(j == -1): if(self.removeRepeat is False or c[i] != c[i - 1]): arr.append(c[i]) From d4a9ad151bf06ef8d7c0052194af6f0b63b1086f Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 28 Jun 2017 11:53:15 +0700 Subject: [PATCH 53/71] =?UTF-8?q?=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88?= =?UTF-8?q?=E0=B8=A1=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=AA=E0=B8=B4=E0=B8=97?= =?UTF-8?q?=E0=B8=98=E0=B8=B4=E0=B8=A0=E0=B8=B2=E0=B8=9E=205?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pythainlp/soundex.py | 5 ++--- pythainlp/tokenize/etcc.py | 6 ++++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/pythainlp/soundex.py b/pythainlp/soundex.py index d5a765dcd..21f37da6b 100644 --- a/pythainlp/soundex.py +++ b/pythainlp/soundex.py @@ -48,9 +48,8 @@ def LK82(s): res.append(c.translate(t2)) else: res.append('') - elif c in 'หอ': - if i+1 Date: Thu, 29 Jun 2017 01:26:51 +0700 Subject: [PATCH 54/71] =?UTF-8?q?=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88?= =?UTF-8?q?=E0=B8=A1=E0=B8=9B=E0=B8=A3=E0=B8=B0=E0=B8=AA=E0=B8=B4=E0=B8=97?= =?UTF-8?q?=E0=B8=98=E0=B8=B4=E0=B8=A0=E0=B8=B2=E0=B8=9E=E0=B9=82=E0=B8=84?= =?UTF-8?q?=E0=B9=89=E0=B8=94=206?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pythainlp/tokenize/mm.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/pythainlp/tokenize/mm.py b/pythainlp/tokenize/mm.py index 1a836f704..28fbf1cb7 100644 --- a/pythainlp/tokenize/mm.py +++ b/pythainlp/tokenize/mm.py @@ -130,6 +130,9 @@ def transform(self, wordArray): return wordArray def extract_keyword(self, wordArray): + """ + ใช้ในการหาคำสำคัญ + """ result_array = [] for dd in wordArray: try: @@ -173,6 +176,9 @@ def find_ngrams(self, input_list, n): return zip(*[input_list[i:] for i in range(n)]) def segment(self, c): + ''' + ตัดคำใช้ฟังก์ชัน segment + ''' result = self.find_segment(c) if self.stopword: result = self.transform(result) @@ -192,6 +198,9 @@ def segment(self, c): lastresult.append(' '.join(r)) return lastresult def mergelistlen(listdata,lennum): + ''' + แก้ Bug ที่เกิดจาก mm + ''' i=0 listlen=len(listdata) while i Date: Mon, 3 Jul 2017 12:26:59 +0700 Subject: [PATCH 55/71] add Udom83 --- docs/pythainlp-1-4-thai.md | 5 ++++- pythainlp/__init__.py | 2 +- pythainlp/soundex.py | 31 ++++++++++++++++++++----------- pythainlp/test/__init__.py | 3 ++- 4 files changed, 27 insertions(+), 14 deletions(-) diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 79a46d3b6..6ff1fd3f6 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -267,7 +267,8 @@ grammar : คุณ Wittawat Jitkrittum (https://github.com/wittawatj/jtcc/blob/ กฎที่รองรับในเวชั่น 1.4 -- กฎการเข้ารหัสซาวน์เด็กซ์ของ วิชิตหล่อจีระชุณห์กุล และ เจริญ คุวินทร์พันธุ์ +- กฎการเข้ารหัสซาวน์เด็กซ์ของ วิชิตหล่อจีระชุณห์กุล และ เจริญ คุวินทร์พันธุ์ - LK82 +- กฎการเข้ารหัสซาวน์เด็กซ์ของ วรรณี อุดมพาณิชย์ - Udom83 **การใช้งาน** @@ -281,6 +282,8 @@ grammar : คุณ Wittawat Jitkrittum (https://github.com/wittawatj/jtcc/blob/ จ4000 >>> print(LK82('จันทร์')) จ4000 +>>> print(Udom83('รถ')) +ร800000 ``` ### Meta Sound ภาษาไทย diff --git a/pythainlp/__init__.py b/pythainlp/__init__.py index dd03b902f..6e491295d 100644 --- a/pythainlp/__init__.py +++ b/pythainlp/__init__.py @@ -18,4 +18,4 @@ from pythainlp.test import TestUM from pythainlp.Text import Text from pythainlp.MetaSound import MetaSound -from pythainlp.soundex import LK82 \ No newline at end of file +from pythainlp.soundex import LK82,Udom83 \ No newline at end of file diff --git a/pythainlp/soundex.py b/pythainlp/soundex.py index 21f37da6b..702bc8b9c 100644 --- a/pythainlp/soundex.py +++ b/pythainlp/soundex.py @@ -13,17 +13,7 @@ def LK82(s): t2 = str.maketrans("กขฃคฅฆงจฉชซฌฎฏฐฑฒดตถทธศษสญณนรลฬฤฦบปพฟภผฝมำยวไใหฮาๅึืเแโุูอ","1111112333333333333333333444444445555555667777889AAABCDEEF") res = [] s = re.sub("[่-๋]", "", s) # 4.ลบวรรณยุกต์ - if re.search("[ก-ฮ][ิุู]?์",s): - # 4.ลบการันต์ - # เนื่องจากภาษาไทยมีตัวการ์รันต์ เช่น ตร์ ทร์ ดร์ อยู่ด้วย จึงต้องเอาออกไปด้วย - if re.search("ตร์",s): - s = re.sub("ตร์","",s) - elif re.search("ทร์",s): - s = re.sub("ทร์","",s) - elif re.search("ดร์",s): - s = re.sub("ทร์","",s) - else: - s = re.sub("[ก-ฮ][ิุู]?์", "", s) + s = re.sub('จน์|มณ์|ณฑ์|ทร์|ตร์|[ก-ฮ]์|[ก-ฮ][ะ-ู]์', "", s) # 4.ลบตัวการันต์ s = re.sub("[็ํฺๆฯ]", "", s) # 5.ทิ้งไม้ไต่คู่ ฯลฯ # 6.เข้ารหัสตัวแรก if 'ก'<=s[0]<='ฮ': @@ -62,7 +52,26 @@ def LK82(s): res2.append(res[i]) # 14. เติมศูนย์ให้ครบ ถ้าเกินก็ตัด return ("".join(res2)+"0000")[:5] +def Udom83(s): + tu1 = str.maketrans("กขฃคฅฆงจฉชฌซศษสฎดฏตฐฑฒถทธณนบปผพภฝฟมญยรลฬฤฦวอหฮ" ,"กขขขขขงจชชชสสสสดดตตททททททนนบปพพพฟฟมยยรรรรรวอฮฮ") + tu2 = str.maketrans("มวำกขฃคฅฆงยญณนฎฏดตศษสบปพภผฝฟหอฮจฉชซฌฐฑฒถทธรฤลฦ","0001111112233344444445555666666777778888889999") + s = re.sub('รร([เ-ไ])', 'ัน\\1', s) # 4. + s = re.sub('รร([ก-ฮ][ก-ฮเ-ไ])', 'ั\\1', s) # 5. + s = re.sub('รร([ก-ฮ][ะ-ู่-์])','ัน\\1', s) + s = re.sub('รร', 'ัน', s) + + s = re.sub('ไ([ก-ฮ]ย)', '\\1', s) # 2. + s = re.sub('[ไใ]([ก-ฮ])','\\1ย', s) + + s = re.sub('ำ(ม[ะ-ู])', 'ม\\1', s) # 3. + s = re.sub('ำม', 'ม', s) + s = re.sub('ำ', 'ม', s) + s = re.sub('จน์|มณ์|ณฑ์|ทร์|ตร์|[ก-ฮ]์|[ก-ฮ][ะ-ู]์', "", s) # 6. + s = re.sub('[ะ-์]', '', s) # 7. + sd = s[0].translate(tu1) + sd += s[1:].translate(tu2) + return (sd+'000000')[:7] if __name__ == '__main__': print(LK82('รถ')) print(LK82('รส')) diff --git a/pythainlp/test/__init__.py b/pythainlp/test/__init__.py index 1d0420503..715dbf360 100644 --- a/pythainlp/test/__init__.py +++ b/pythainlp/test/__init__.py @@ -12,7 +12,7 @@ from pythainlp.romanization import romanization from pythainlp.date import now from pythainlp.tokenize import tcc,etcc -from pythainlp.soundex import LK82 +from pythainlp.soundex import LK82,Udom83 from pythainlp.corpus import stopwords from pythainlp.MetaSound import MetaSound from collections import namedtuple @@ -41,6 +41,7 @@ def test_etcc(self): self.assertEqual(etcc.etcc('คืนความสุข'),'/คืน/ความสุข') def test_lk82(self): self.assertEqual(LK82('รถ'),'ร3000') + self.assertEqual(Udom83('รถ'),'ร800000') def test_ms(self): self.assertEqual(MetaSound('คน'),'15') def test_wordnet(self): From 101499a52037dfa17236cce2b767ae28214023e1 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Mon, 3 Jul 2017 13:59:09 +0700 Subject: [PATCH 56/71] add stopword in rank --- pythainlp/rank/__init__.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/pythainlp/rank/__init__.py b/pythainlp/rank/__init__.py index 473fdd800..cfc904f3a 100644 --- a/pythainlp/rank/__init__.py +++ b/pythainlp/rank/__init__.py @@ -1,11 +1,17 @@ # -*- coding: utf-8 -*- from __future__ import absolute_import,print_function,unicode_literals from collections import Counter +from pythainlp.corpus import stopwords #เรียงจำนวนคำของประโยค -def rank(data): +def rank(data,stopword=False): """เรียงจำนวนคำของประโยค รับค่าเป็น ''list'' คืนค่าเป็น ''dict'' [ข้อความ,จำนวน]""" - return Counter(data) + if stopword==False: + rankdata=Counter(data) + else: + data = [word for word in data if word not in stopwords.words('thai')] + rankdata=Counter(data) + return rankdata if __name__ == "__main__": text = ['แมว','ชอบ','ปลา','และ','แมว','ชอบ','นอน','มาก','เลย','คน','เลี้ยง','กลาย','เป็น','ทาส','แมว'] print(rank(text)) From 41e940c2c448b72f9067eb9bd4d196c1c855ce42 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 5 Jul 2017 11:21:59 +0700 Subject: [PATCH 57/71] add api --- docs/pythainlp-1-4-thai.md | 7 +++++++ pythainlp/corpus/newthaiword.py | 11 +++++++++++ pythainlp/test/__init__.py | 5 ++++- 3 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 pythainlp/corpus/newthaiword.py diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 6ff1fd3f6..64ee69a7c 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -341,6 +341,13 @@ from pythainlp.corpus import alphabet alphabet.get_data() ``` +#### รายการคำในภาษาไทย +```python +from pythainlp.corpus.thaiword import get_data # ข้อมูลเก่า +get_data() +from pythainlp.corpus.newthaiword import get_data # ข้อมูลใหม่ +get_data() +``` เขียนโดย นาย วรรณพงษ์ ภัททิยไพบูลย์ \ No newline at end of file diff --git a/pythainlp/corpus/newthaiword.py b/pythainlp/corpus/newthaiword.py new file mode 100644 index 000000000..595ff16ae --- /dev/null +++ b/pythainlp/corpus/newthaiword.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import,unicode_literals +import os +import codecs +import pythainlp +templates_dir = os.path.join(os.path.dirname(pythainlp.__file__), 'corpus') +template_file = os.path.join(templates_dir, 'new-thaidict.txt') +def get_data(): + with codecs.open(template_file, 'r',encoding='utf8') as f: + lines = f.read().splitlines() + return lines diff --git a/pythainlp/test/__init__.py b/pythainlp/test/__init__.py index 715dbf360..9a101cf65 100644 --- a/pythainlp/test/__init__.py +++ b/pythainlp/test/__init__.py @@ -18,6 +18,9 @@ from collections import namedtuple Synset = namedtuple('Synset', 'synset li') class TestUM(unittest.TestCase): + """ + ระบบทดสอบการทำงานของโค้ดของ PyThaiNLP + """ def test_segment(self): self.assertEqual(word_tokenize('ฉันรักภาษาไทยเพราะฉันเป็นคนไทย'),[u'ฉัน', u'รัก', u'ภาษา', u'ไทย', u'เพราะ', u'ฉัน', u'เป็น', u'คน', u'ไทย']) def test_segment_dict(self): @@ -55,4 +58,4 @@ def test_tag_new(self): if sys.version_info > (3,3): self.assertEqual(pos_tag(word_tokenize("ผมรักคุณ"),engine='artagger'),[('ผม', 'PPRS'), ('รัก', 'VSTA'), ('คุณ', 'PPRS')]) if __name__ == '__main__': - unittest.main() + unittest.main() \ No newline at end of file From ed0ff68a39f01b27a0befb430fcdc1de09358de0 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 5 Jul 2017 12:00:48 +0700 Subject: [PATCH 58/71] add newmm --- docs/pythainlp-1-4-thai.md | 8 ++-- pythainlp/tokenize/__init__.py | 3 ++ pythainlp/tokenize/newmm.py | 75 ++++++++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+), 3 deletions(-) create mode 100644 pythainlp/tokenize/newmm.py diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 64ee69a7c..136a08414 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -53,9 +53,10 @@ text คือ ข้อความในรูปแบบสตริง str engine คือ ระบบตัดคำไทย ปัจจุบันนี้ PyThaiNLP ได้พัฒนามี 3 engine ให้ใช้งานกันดังนี้ 1. icu - engine ตัวดั้งเดิมของ PyThaiNLP (ความแม่นยำต่ำ) และเป็นค่าเริ่มต้น -2. dict - เป็นการตัดคำโดยใช้พจานุกรมจาก thaiword.txt ใน corpus (ความแม่นยำปานกลาง) -3. mm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย -4. pylexto ใช้ LexTo ในการตัดคำ +2. dict - เป็นการตัดคำโดยใช้พจานุกรมจาก thaiword.txt ใน corpus (ความแม่นยำปานกลาง) จะคืนค่า False หากข้อความนั้นไม่สามารถตัดคำได้ +3. mm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย - API ชุดเก่า +4. newmm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ โดยใช้โค้ดคุณ Korakot Chaovavanich จาก https://www.facebook.com/groups/408004796247683/permalink/431283740586455/ มาพัฒนาต่อ +5. pylexto ใช้ LexTo ในการตัดคำ คืนค่าเป็น ''list'' เช่น ['แมว','กิน'] @@ -68,6 +69,7 @@ a=word_tokenize(text,engine='icu') # ['ผม', 'รัก', 'คุณ', 'น b=word_tokenize(text,engine='dict') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] c=word_tokenize(text,engine='mm') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] d=word_tokenize(text,engine='pylexto') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] +e=word_tokenize(text,engine='newmm') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] ``` ### Postaggers ภาษาไทย diff --git a/pythainlp/tokenize/__init__.py b/pythainlp/tokenize/__init__.py index 15a34ddf4..20c1ffbe8 100644 --- a/pythainlp/tokenize/__init__.py +++ b/pythainlp/tokenize/__init__.py @@ -10,6 +10,7 @@ def word_tokenize(text,engine='icu'): - dict - mm ใช้ Maximum Matching algorithm - pylexto ใช้ LexTo ในการตัดคำ + - newmm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ """ if engine=='icu': from .pyicu import segment @@ -19,4 +20,6 @@ def word_tokenize(text,engine='icu'): from .mm import segment elif engine=='pylexto': from .pylexto import segment + elif engine=='newmm': + from .newmm import mmcut as segment return segment(text) diff --git a/pythainlp/tokenize/newmm.py b/pythainlp/tokenize/newmm.py new file mode 100644 index 000000000..6bbdf830d --- /dev/null +++ b/pythainlp/tokenize/newmm.py @@ -0,0 +1,75 @@ +''' +ตัดคำภาษาไทยโดยใช้ Maximum Matching algorithm +เดติดโค้ดต้นฉบับ คุณ Korakot Chaovavanich +จาก https://www.facebook.com/groups/408004796247683/permalink/431283740586455/ +''' +from marisa_trie import Trie +from collections import Counter, defaultdict +from pythainlp.corpus.thaiword import get_data +class LatticeString(str): + def __new__(cls, value, multi=None): + ''' Return a string instance + ''' + return str.__new__(cls, value) + + def __init__(self, value, multi=None): + self.unique = True + if multi: + self.multi = list(multi) + if len(self.multi) > 1: + self.unique = False + else: + self.multi = [value] + + self.in_dict = True # บอกว่าเป็นคำมีในดิกหรือเปล่า + + def suggest(self): + return [] +def serialize(p, p2): + for w in words_at[p]: + p_ = p + len(w) + if p_== p2: + yield w + elif p_ < p2: + for path in serialize(p_, p2): + yield w+'/'+path +trie = Trie(get_data()) +# มี jigsaw พร้อมแล้ว ต่อไปก็ลองเขียน tcut ใหม่ +def tcut(text): + + words_at = defaultdict(list) # main data structure + + def serialize(p, p2): # helper function + for w in words_at[p]: + p_ = p + len(w) + if p_== p2: + yield w + elif p_ < p2: + for path in serialize(p_, p2): + yield w+'/'+path + + q = {0} + last_p = 0 # last position for yield + while min(q) < len(text): + p = min(q) + q -= {p} # q.pop, but for set + + for w in trie.prefixes(text[p:]): + words_at[p].append(w) + q.add(p+len(w)) + + if len(q)==1: + q0 = min(q) + yield LatticeString(text[last_p:q0], serialize(last_p, q0)) + last_p = q0 + # กรณี len(q) == 0 คือ เจอคำนอก dict +# ตัดคำแบบ maximal matching +def mmcut(text): + res = [] + for w in tcut(text): + if w.unique: + res.append(w) + else: + mm = min(w.multi, key=lambda x: x.count('/')) + res.extend(mm.split('/')) + return res \ No newline at end of file From eb4c4c390539c07b94cb619aa2277827fdd5dcde Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 5 Jul 2017 12:14:46 +0700 Subject: [PATCH 59/71] add deepcut --- docs/pythainlp-1-4-thai.md | 1 + pythainlp/tokenize/__init__.py | 36 +++++++++++++++++++++++++++------- pythainlp/tokenize/deepcut.py | 17 ++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 pythainlp/tokenize/deepcut.py diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 136a08414..81a3d05ed 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -57,6 +57,7 @@ engine คือ ระบบตัดคำไทย ปัจจุบัน 3. mm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย - API ชุดเก่า 4. newmm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ โดยใช้โค้ดคุณ Korakot Chaovavanich จาก https://www.facebook.com/groups/408004796247683/permalink/431283740586455/ มาพัฒนาต่อ 5. pylexto ใช้ LexTo ในการตัดคำ +6. deepcut ใช้ deepcut จาก https://github.com/rkcosmos/deepcut ในการตัดคำภาษาไทย คืนค่าเป็น ''list'' เช่น ['แมว','กิน'] diff --git a/pythainlp/tokenize/__init__.py b/pythainlp/tokenize/__init__.py index 20c1ffbe8..c48f49d58 100644 --- a/pythainlp/tokenize/__init__.py +++ b/pythainlp/tokenize/__init__.py @@ -4,22 +4,44 @@ def word_tokenize(text,engine='icu'): """ ระบบตัดคำภาษาไทย - word_tokenize(text,engine='mm') + word_tokenize(text,engine='icu') engine มี - - icu - - dict - - mm ใช้ Maximum Matching algorithm - - pylexto ใช้ LexTo ในการตัดคำ + - icu - engine ตัวดั้งเดิมของ PyThaiNLP (ความแม่นยำต่ำ) และเป็นค่าเริ่มต้น + - dict - ใช้ dicu ในการตัดคำไทย จะคืนค่า False หากไม่สามารถตัดคำไทย + - mm ใช้ Maximum Matching algorithm - โค้ดชุดเก่า - newmm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ + - pylexto ใช้ LexTo ในการตัดคำ + - deepcut ใช้ Deep Neural Network ในการตัดคำภาษาไทย """ if engine=='icu': + ''' + ตัดคำภาษาไทยโดยใช้ icu ในการตัดคำ + ''' from .pyicu import segment elif engine=='dict': + ''' + ใช้ dicu ในการตัดคำไทย + จะคืนค่า False หากไม่สามารถตัดคำไทย + ''' from .dictsegment import segment elif engine=='mm': + ''' + ใช้ Maximum Matching algorithm - โค้ดชุดเก่า + ''' from .mm import segment - elif engine=='pylexto': - from .pylexto import segment elif engine=='newmm': + ''' + ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ + ''' from .newmm import mmcut as segment + elif engine=='pylexto': + ''' + ใช้ LexTo ในการตัดคำ + ''' + from .pylexto import segment + elif engine=='deepcut': + ''' + ใช้ Deep Neural Network ในการตัดคำภาษาไทย + ''' + from .deepcut import segment return segment(text) diff --git a/pythainlp/tokenize/deepcut.py b/pythainlp/tokenize/deepcut.py new file mode 100644 index 000000000..0eb3fae8d --- /dev/null +++ b/pythainlp/tokenize/deepcut.py @@ -0,0 +1,17 @@ +# -*- coding: utf-8 -*- +from __future__ import absolute_import,unicode_literals +import sys +try: + import deepcut +except ImportError: + ''' + ในกรณ๊ที่ยังไม่ติดตั้ง deepcut ในระบบ + ''' + import pip + pip.main(['install','deepcut']) + try: + from pylexto import LexTo + except ImportError: + sys.exit('Error ! using pip install deepcut') +def segment(text): + return deepcut.tokenize(text) \ No newline at end of file From 296693b5d5176b7411e5ac5028ee983ca2815307 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 5 Jul 2017 12:35:04 +0700 Subject: [PATCH 60/71] fix newmm --- pythainlp/tokenize/newmm.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pythainlp/tokenize/newmm.py b/pythainlp/tokenize/newmm.py index 6bbdf830d..713ede111 100644 --- a/pythainlp/tokenize/newmm.py +++ b/pythainlp/tokenize/newmm.py @@ -33,10 +33,9 @@ def serialize(p, p2): elif p_ < p2: for path in serialize(p_, p2): yield w+'/'+path -trie = Trie(get_data()) # มี jigsaw พร้อมแล้ว ต่อไปก็ลองเขียน tcut ใหม่ def tcut(text): - + trie = Trie(get_data()) words_at = defaultdict(list) # main data structure def serialize(p, p2): # helper function @@ -63,8 +62,10 @@ def serialize(p, p2): # helper function yield LatticeString(text[last_p:q0], serialize(last_p, q0)) last_p = q0 # กรณี len(q) == 0 คือ เจอคำนอก dict -# ตัดคำแบบ maximal matching def mmcut(text): + ''' + ตัดคำแบบ maximal matching + ''' res = [] for w in tcut(text): if w.unique: From a1647d3821585424dc6d81e40f75d45258625300 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 5 Jul 2017 14:03:08 +0700 Subject: [PATCH 61/71] =?UTF-8?q?=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88?= =?UTF-8?q?=E0=B8=A1=E0=B8=84=E0=B8=B3=E0=B9=80=E0=B8=95=E0=B8=B7=E0=B8=AD?= =?UTF-8?q?=E0=B8=99=E0=B9=83=E0=B8=99=E0=B9=80=E0=B8=AD=E0=B8=81=E0=B8=AA?= =?UTF-8?q?=E0=B8=B2=E0=B8=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/pythainlp-1-4-thai.md | 2 +- pythainlp/tokenize/newmm.py | 24 ++++++++++++++++++++++-- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 81a3d05ed..96477fb84 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -55,7 +55,7 @@ engine คือ ระบบตัดคำไทย ปัจจุบัน 1. icu - engine ตัวดั้งเดิมของ PyThaiNLP (ความแม่นยำต่ำ) และเป็นค่าเริ่มต้น 2. dict - เป็นการตัดคำโดยใช้พจานุกรมจาก thaiword.txt ใน corpus (ความแม่นยำปานกลาง) จะคืนค่า False หากข้อความนั้นไม่สามารถตัดคำได้ 3. mm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย - API ชุดเก่า -4. newmm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ โดยใช้โค้ดคุณ Korakot Chaovavanich จาก https://www.facebook.com/groups/408004796247683/permalink/431283740586455/ มาพัฒนาต่อ +4. newmm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ โดยใช้โค้ดคุณ Korakot Chaovavanich จาก https://www.facebook.com/groups/408004796247683/permalink/431283740586455/ มาพัฒนาต่อ *** หมายเหตุ API ตัวนี้ยังไม่เสถียรพอสำหรับใช้งานในโปรแกรมจริง ควรใช้เพื่อการศึกษาหรือวิจัยเท่านั้น อาจจากอยู่ในช่วงกำลังพัฒนา** 5. pylexto ใช้ LexTo ในการตัดคำ 6. deepcut ใช้ deepcut จาก https://github.com/rkcosmos/deepcut ในการตัดคำภาษาไทย diff --git a/pythainlp/tokenize/newmm.py b/pythainlp/tokenize/newmm.py index 713ede111..ca813ecdd 100644 --- a/pythainlp/tokenize/newmm.py +++ b/pythainlp/tokenize/newmm.py @@ -45,7 +45,7 @@ def serialize(p, p2): # helper function yield w elif p_ < p2: for path in serialize(p_, p2): - yield w+'/'+path + yield w+'|'+path q = {0} last_p = 0 # last position for yield @@ -73,4 +73,24 @@ def mmcut(text): else: mm = min(w.multi, key=lambda x: x.count('/')) res.extend(mm.split('/')) - return res \ No newline at end of file + return res +def listcut(text): + ''' + ใช้หาคำที่สามารถตัดได้ทั้งหมดโดยจะเป็น list โดยมี | เป็นตัวแบ่งใน list + ''' + listdata = list(tcut(text)) + listdata1=['']*len(listdata) + i=0 + maxnum=0 + numall=1 + listnum=[0]*len(listdata) + while i Date: Wed, 5 Jul 2017 20:20:27 +0700 Subject: [PATCH 62/71] add listcut --- pythainlp/tokenize/newmm.py | 31 ++++++++++++++----------------- 1 file changed, 14 insertions(+), 17 deletions(-) diff --git a/pythainlp/tokenize/newmm.py b/pythainlp/tokenize/newmm.py index ca813ecdd..8251d78ec 100644 --- a/pythainlp/tokenize/newmm.py +++ b/pythainlp/tokenize/newmm.py @@ -74,23 +74,20 @@ def mmcut(text): mm = min(w.multi, key=lambda x: x.count('/')) res.extend(mm.split('/')) return res +def combine(ww): + if ww == []: + yield "" + else: + w = ww[0] + for tail in combine(ww[1:]): + if w.unique: + yield w+"|"+tail + else: + for m in w.multi: + yield m.replace("/","|")+"|"+tail + def listcut(text): - ''' - ใช้หาคำที่สามารถตัดได้ทั้งหมดโดยจะเป็น list โดยมี | เป็นตัวแบ่งใน list - ''' - listdata = list(tcut(text)) - listdata1=['']*len(listdata) - i=0 - maxnum=0 - numall=1 - listnum=[0]*len(listdata) - while i Date: Wed, 5 Jul 2017 20:27:55 +0700 Subject: [PATCH 63/71] fix newmm --- pythainlp/tokenize/newmm.py | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/pythainlp/tokenize/newmm.py b/pythainlp/tokenize/newmm.py index 8251d78ec..fb37a8bc8 100644 --- a/pythainlp/tokenize/newmm.py +++ b/pythainlp/tokenize/newmm.py @@ -35,8 +35,9 @@ def serialize(p, p2): yield w+'/'+path # มี jigsaw พร้อมแล้ว ต่อไปก็ลองเขียน tcut ใหม่ def tcut(text): + #global last_p, i, q, ww # for debug trie = Trie(get_data()) - words_at = defaultdict(list) # main data structure + words_at = defaultdict(list) # main data structure def serialize(p, p2): # helper function for w in words_at[p]: @@ -45,7 +46,7 @@ def serialize(p, p2): # helper function yield w elif p_ < p2: for path in serialize(p_, p2): - yield w+'|'+path + yield w+'/'+path q = {0} last_p = 0 # last position for yield @@ -61,11 +62,22 @@ def serialize(p, p2): # helper function q0 = min(q) yield LatticeString(text[last_p:q0], serialize(last_p, q0)) last_p = q0 - # กรณี len(q) == 0 คือ เจอคำนอก dict + + # กรณี len(q) == 0 คือ ไม่มีใน dict + if len(q)==0: + # skip น้อยที่สุด ที่เป็นไปได้ + for i in range(p, len(text)): + ww = trie.prefixes(text[i:]) + if ww: + break + else: + i = len(text) + w = text[p:i] + words_at[p].append(w) + yield LatticeString(w, in_dict=False) + last_p = i + q.add(i) def mmcut(text): - ''' - ตัดคำแบบ maximal matching - ''' res = [] for w in tcut(text): if w.unique: @@ -89,5 +101,7 @@ def combine(ww): def listcut(text): ww = list(tcut(text)) return list(combine(ww)) -text='ผมตากลมเย็นสบายดี' -print(listcut(text)) \ No newline at end of file +if __name__ == "__main__": + text='ผมตากลมเย็นสบายดี' + print(mmcut(text)) + print(listcut(text)) \ No newline at end of file From 0b2740a95ddeff80e3b6379712bb3492f53c53a5 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 5 Jul 2017 20:33:12 +0700 Subject: [PATCH 64/71] fix newmm #2 --- pythainlp/tokenize/newmm.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pythainlp/tokenize/newmm.py b/pythainlp/tokenize/newmm.py index fb37a8bc8..c0b76d9f9 100644 --- a/pythainlp/tokenize/newmm.py +++ b/pythainlp/tokenize/newmm.py @@ -7,12 +7,12 @@ from collections import Counter, defaultdict from pythainlp.corpus.thaiword import get_data class LatticeString(str): - def __new__(cls, value, multi=None): + def __new__(cls, value, multi=None, in_dict=True): ''' Return a string instance ''' return str.__new__(cls, value) - def __init__(self, value, multi=None): + def __init__(self, value, multi=None, in_dict=True): self.unique = True if multi: self.multi = list(multi) @@ -21,7 +21,7 @@ def __init__(self, value, multi=None): else: self.multi = [value] - self.in_dict = True # บอกว่าเป็นคำมีในดิกหรือเปล่า + self.in_dict = in_dict # บอกว่าเป็นคำมีในดิกหรือเปล่า def suggest(self): return [] @@ -73,6 +73,7 @@ def serialize(p, p2): # helper function else: i = len(text) w = text[p:i] + w = w.replace(' ','') # ลบค่าที่ว่าง words_at[p].append(w) yield LatticeString(w, in_dict=False) last_p = i @@ -102,6 +103,6 @@ def listcut(text): ww = list(tcut(text)) return list(combine(ww)) if __name__ == "__main__": - text='ผมตากลมเย็นสบายดี' + text='ผมตากลมเย็นสบายดีok เข้าใจ' print(mmcut(text)) print(listcut(text)) \ No newline at end of file From a54eebc082f85192556db982de80e59394d1d4bb Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Wed, 5 Jul 2017 23:29:08 +0700 Subject: [PATCH 65/71] fix code MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ซ่อมโค้ดเก่าและเพิ่มเอกสาร --- docs/pythainlp-1-4-thai.md | 6 ++---- pythainlp/test/__init__.py | 2 ++ pythainlp/tokenize/newmm.py | 8 +++++++- pythainlp/tokenize/pyicu.py | 8 ++++++-- 4 files changed, 17 insertions(+), 7 deletions(-) diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 96477fb84..fe5ec27e6 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -55,7 +55,7 @@ engine คือ ระบบตัดคำไทย ปัจจุบัน 1. icu - engine ตัวดั้งเดิมของ PyThaiNLP (ความแม่นยำต่ำ) และเป็นค่าเริ่มต้น 2. dict - เป็นการตัดคำโดยใช้พจานุกรมจาก thaiword.txt ใน corpus (ความแม่นยำปานกลาง) จะคืนค่า False หากข้อความนั้นไม่สามารถตัดคำได้ 3. mm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย - API ชุดเก่า -4. newmm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ โดยใช้โค้ดคุณ Korakot Chaovavanich จาก https://www.facebook.com/groups/408004796247683/permalink/431283740586455/ มาพัฒนาต่อ *** หมายเหตุ API ตัวนี้ยังไม่เสถียรพอสำหรับใช้งานในโปรแกรมจริง ควรใช้เพื่อการศึกษาหรือวิจัยเท่านั้น อาจจากอยู่ในช่วงกำลังพัฒนา** +4. newmm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ โดยใช้โค้ดคุณ Korakot Chaovavanich จาก https://www.facebook.com/groups/408004796247683/permalink/431283740586455/ มาพัฒนาต่อ * **หมายเหตุ API ตัวนี้ยังไม่เสถียรพอสำหรับใช้งานในโปรแกรมจริง ควรใช้เพื่อการศึกษาหรือวิจัยเท่านั้น อาจจากอยู่ในช่วงกำลังพัฒนา** 5. pylexto ใช้ LexTo ในการตัดคำ 6. deepcut ใช้ deepcut จาก https://github.com/rkcosmos/deepcut ในการตัดคำภาษาไทย @@ -111,9 +111,7 @@ from pythainlp.romanization import romanization romanization("แมว") # 'mæw' ``` -### เช็คคำผิด * - -*ความสามารถนี้รองรับเฉพาะ Python 3 +### เช็คคำผิด ก่อนใช้งานความสามารถนี้ ให้ทำการติดตั้ง hunspell และ hunspell-th ก่อน diff --git a/pythainlp/test/__init__.py b/pythainlp/test/__init__.py index 9a101cf65..687902d8c 100644 --- a/pythainlp/test/__init__.py +++ b/pythainlp/test/__init__.py @@ -27,6 +27,8 @@ def test_segment_dict(self): self.assertEqual(word_tokenize('ฉันรักภาษาไทยเพราะฉันเป็นคนไทย',engine='dict'),[u'ฉัน', u'รัก', u'ภาษาไทย', u'เพราะ', u'ฉัน', u'เป็น', u'คนไทย']) def test_segment_mm(self): self.assertEqual(word_tokenize('ฉันรักภาษาไทยเพราะฉันเป็นคนไทย',engine='mm'),[u'ฉัน', u'รัก', u'ภาษาไทย', u'เพราะ', u'ฉัน', u'เป็น', u'คนไทย']) + def test_segment_newmm(self): + self.assertEqual(word_tokenize('ฉันรักภาษาไทยเพราะฉันเป็นคนไทย',engine='newmm'),[u'ฉัน', u'รัก', u'ภาษาไทย', u'เพราะ', u'ฉัน', u'เป็น', u'คนไทย']) def test_rank(self): self.assertEqual(rank(["แมว","คน","แมว"]),Counter({'แมว': 2, 'คน': 1})) def test_change(self): diff --git a/pythainlp/tokenize/newmm.py b/pythainlp/tokenize/newmm.py index c0b76d9f9..b300e0e34 100644 --- a/pythainlp/tokenize/newmm.py +++ b/pythainlp/tokenize/newmm.py @@ -79,6 +79,9 @@ def serialize(p, p2): # helper function last_p = i q.add(i) def mmcut(text): + ''' + ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย + ''' res = [] for w in tcut(text): if w.unique: @@ -100,9 +103,12 @@ def combine(ww): yield m.replace("/","|")+"|"+tail def listcut(text): + ''' + ใช้ในการหา list ที่สามารถตัดคำได้ทั้งหมด + ''' ww = list(tcut(text)) return list(combine(ww)) if __name__ == "__main__": - text='ผมตากลมเย็นสบายดีok เข้าใจ' + text='ผมรักคุณนะครับโอเคบ่พวกเราเป็นคนไทยรักภาษาไทยภาษาบ้านเกิด' print(mmcut(text)) print(listcut(text)) \ No newline at end of file diff --git a/pythainlp/tokenize/pyicu.py b/pythainlp/tokenize/pyicu.py index 2c33a9b6c..e4b89f603 100644 --- a/pythainlp/tokenize/pyicu.py +++ b/pythainlp/tokenize/pyicu.py @@ -20,7 +20,10 @@ def isEnglish(s): else: return True def isThai(chr): - if isEnglish(chr): + ''' + เช็คตัวอักษรว่าใช่ภาษาไทยไหม + ''' + if isEnglish(chr): return False try: '''cVal = ord(chr) @@ -28,7 +31,8 @@ def isThai(chr): return True''' if detect(chr)=='th': return True - return False + else: + return False except: return False def segment(txt): From 69867fa44f92d3aa55a47756acbe9cda438cfdb8 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Thu, 6 Jul 2017 11:59:04 +0700 Subject: [PATCH 66/71] add pythainlp.util MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - เพิ่ม API ตัวใหม่ โดยมี ngrams --- docs/pythainlp-1-4-thai.md | 19 +++++++++++++++++++ pythainlp/__init__.py | 3 ++- pythainlp/tokenize/pyicu.py | 5 ++++- pythainlp/util/__init__.py | 11 +++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 pythainlp/util/__init__.py diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index fe5ec27e6..4b2a6de01 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -312,6 +312,25 @@ sentiment(str) รับค่า str ส่งออกเป็น pos , neg หรือ neutral +### Util + +การใช้งาน + +```python +from pythainlp.util import * +``` + +#### ngrams + +สำหรับสร้าง ngrams + +```python +ngrams(token,num) +``` + +- token คือ list +- num คือ จำนวน ngrams + ### Corpus #### stopword ภาษาไทย diff --git a/pythainlp/__init__.py b/pythainlp/__init__.py index 6e491295d..47bffa93e 100644 --- a/pythainlp/__init__.py +++ b/pythainlp/__init__.py @@ -18,4 +18,5 @@ from pythainlp.test import TestUM from pythainlp.Text import Text from pythainlp.MetaSound import MetaSound -from pythainlp.soundex import LK82,Udom83 \ No newline at end of file +from pythainlp.soundex import LK82,Udom83 +from pythainlp.util import ngrams \ No newline at end of file diff --git a/pythainlp/tokenize/pyicu.py b/pythainlp/tokenize/pyicu.py index e4b89f603..0ac0e2cce 100644 --- a/pythainlp/tokenize/pyicu.py +++ b/pythainlp/tokenize/pyicu.py @@ -5,7 +5,10 @@ import re import icu def isEnglish(s): - try: + ''' + เช็คว่าตัวอักษรเป็นภาษาอังกฤษหรือไม่ + ''' + try: try: s.encode('ascii') except UnicodeEncodeError: diff --git a/pythainlp/util/__init__.py b/pythainlp/util/__init__.py new file mode 100644 index 000000000..578a12ed9 --- /dev/null +++ b/pythainlp/util/__init__.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +from nltk.util import ngrams as ngramsdata +def ngrams(token,num): + ''' + ngrams สร้าง ngrams + + ngrams(token,num) + - token คือ list + - num คือ จำนวน ngrams + ''' + return ngramsdata(token,int(num)) \ No newline at end of file From 5dff1d07457e053a29d5f5a024f720dba6c40217 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Thu, 6 Jul 2017 12:57:50 +0700 Subject: [PATCH 67/71] add eng --- README.md | 68 +++++++- docs/pythainlp-1-4-eng.md | 307 +++++++++++++++++++++++++++++++++++++ docs/pythainlp-1-4-thai.md | 4 +- 3 files changed, 373 insertions(+), 6 deletions(-) create mode 100644 docs/pythainlp-1-4-eng.md diff --git a/README.md b/README.md index 89da6e1ef..357492dfd 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,69 @@ [![Build Status](https://travis-ci.org/wannaphongcom/pythainlp.svg?branch=develop)](https://travis-ci.org/wannaphongcom/pythainlp) [![Build status](https://ci.appveyor.com/api/projects/status/uxerymgggp1uch0p?svg=true)](https://ci.appveyor.com/project/wannaphongcom/pythainlp)[![Code Issues](https://www.quantifiedcode.com/api/v1/project/7f699ed4cad24be18d0d24ebd60d7543/badge.svg)](https://www.quantifiedcode.com/app/project/7f699ed4cad24be18d0d24ebd60d7543)[![Coverage Status](https://coveralls.io/repos/github/wannaphongcom/pythainlp/badge.svg?branch=pythainlp1.4)](https://coveralls.io/github/wannaphongcom/pythainlp?branch=pythainlp1.4) +## English -Homepages :[https://sites.google.com/view/pythainlp/home](https://sites.google.com/view/pythainlp/home) +Thai natural language processing in Python. + +PyThaiNLP is python module like nltk , but It'working thai language. + +It's support python 3.4 +. + +### Project status + +Developing + +### Version + +1.4 + +### Capability + +- Thai segment +- Thai wordnet +- Thai Character Clusters (TCC) and ETCC +- Thai stop word +- Thai meta sound +- Thai soundex +- Thai postaggers +- Thai romanization +- Check the wrong words in Thai. + +and much more. + +### Install + +**using pip.** + +```sh +$ pip install pythainlp +``` + +**Install in Windows** + +download pyicu from [http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyicu](http://www.lfd.uci.edu/~gohlke/pythonlibs/#pyicu) than install pyicu. install pythainlp using pip. + +``` +pip install pythainlp +``` + +**Install in MacOS** + +```sh +$ brew install icu4c --force +$ brew link --force icu4c +$ CFLAGS=-I/usr/local/opt/icu4c/include LDFLAGS=-L/usr/local/opt/icu4c/lib pip install pythainlp +``` + +### Documentation + +Read on https://github.com/wannaphongcom/pythainlp/blob/pythainlp1.4/docs/pythainlp-1-4-thai.md + +### License + +Apache Software License 2.0 + +## ภาษาไทย ประมวลภาษาธรรมชาติภาษาไทยในภาษา Python @@ -15,7 +76,6 @@ Natural language processing หรือ การประมวลภาษา รองรับ Python 3.4 ขึ้นไป - - เอกสารการใช้งาน : [https://sites.google.com/view/pythainlp/home](https://sites.google.com/view/pythainlp/home) - หน้าหลัก GitHub : [https://github.com/wannaphongcom/pythainlp](https://github.com/wannaphongcom/pythainlp) ### สถานะโครงการ @@ -48,7 +108,7 @@ Natural language processing หรือ การประมวลภาษา - Thai Soundex - และอื่น ๆ -# ติดตั้ง +### ติดตั้ง รองรับ Python 3.4 ขึ้นไป @@ -85,7 +145,7 @@ $ CFLAGS=-I/usr/local/opt/icu4c/include LDFLAGS=-L/usr/local/opt/icu4c/lib pip i ข้อมูลเพิ่มเติม [คลิกที่นี้](https://medium.com/data-science-cafe/install-polyglot-on-mac-3c90445abc1f#.rdfrorxjx) -# เอกสารการใช้งานเบื้องต้น +### เอกสารการใช้งาน อ่านได้ที่ https://github.com/wannaphongcom/pythainlp/blob/pythainlp1.4/docs/pythainlp-1-4-thai.md diff --git a/docs/pythainlp-1-4-eng.md b/docs/pythainlp-1-4-eng.md new file mode 100644 index 000000000..656e29480 --- /dev/null +++ b/docs/pythainlp-1-4-eng.md @@ -0,0 +1,307 @@ +# User manual PyThaiNLP 1.4 + +## API + +### Thai segment + +```python +from pythainlp.tokenize import word_tokenize +word_tokenize(text,engine) +``` +**text** is thai text. + +**engine** is thai segment system have 6 engine + +1. icu - using pyicu. (default) +2. dict - using dict . returns False if the message can not be wrapped. +3. mm - using Maximum Matching algorithm in thai segment. +4. newmm - using Maximum Matching algorithm in thai segment. credit Korakot Chaovavanich from https://www.facebook.com/groups/408004796247683/permalink/431283740586455/ +5. pylexto using LexTo in thai segment. +6. deepcut using deepcut from https://github.com/rkcosmos/deepcut in thai segment. + +returns ''list'' ex. ['แมว','กิน'] + +**ตัวอย่าง** + +```python +from pythainlp.tokenize import word_tokenize +text='ผมรักคุณนะครับโอเคบ่พวกเราเป็นคนไทยรักภาษาไทยภาษาบ้านเกิด' +a=word_tokenize(text,engine='icu') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอ', 'เค', 'บ่', 'พวก', 'เรา', 'เป็น', 'คน', 'ไทย', 'รัก', 'ภาษา', 'ไทย', 'ภาษา', 'บ้าน', 'เกิด'] +b=word_tokenize(text,engine='dict') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] +c=word_tokenize(text,engine='mm') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] +d=word_tokenize(text,engine='pylexto') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] +e=word_tokenize(text,engine='newmm') # ['ผม', 'รัก', 'คุณ', 'นะ', 'ครับ', 'โอเค', 'บ่', 'พวกเรา', 'เป็น', 'คนไทย', 'รัก', 'ภาษาไทย', 'ภาษา', 'บ้านเกิด'] +``` + +### Thai postaggers + +```python +from pythainlp.tag import pos_tag +pos_tag(list,engine='old') +``` + +engine + +1. old is UnigramTagger (default) +2. artagger is RDR POS Tagger. + +### Thai romanization + +```python +from pythainlp.romanization import romanization +romanization(str,engine='pyicu') +``` +It's have 2 engine + +- pyicu +- royin + +data : + +input ''str'' + +returns ''str'' + +**Example** + +```python +from pythainlp.romanization import romanization +romanization("แมว") # 'mæw' +``` + +### Check the wrong word + +Before using this ability. Install hunspell and hunspell-th first. + +```python +from pythainlp.spell import * +a=spell("สี่เหลียม") +print(a) # ['สี่เหลี่ยม', 'เสียเหลี่ยม', 'เหลี่ยม'] +``` +### pythainlp.number + +```python +from pythainlp.number import * +``` +- nttn(str) - To convert thai numbers to numbers. +- nttt(str) - Thai Numbers to text. +- ntnt(str) - numbers to thai numbers. +- ntt(str) - numbers to text. +- ttn(str) - text to numbers. +- numtowords(float) - Read thai numbers (Baht) input ''float'' returns 'str' + +### Sorting List of Thai Information in List + +```python +from pythainlp.collation import collation +print(collation(['ไก่','ไข่','ก','ฮา'])) # ['ก', 'ไก่', 'ไข่', 'ฮา'] +``` + +input list + +returns list + +### Get current time in Thai + +```python +from pythainlp.date import now +now() # '30 พฤษภาคม 2560 18:45:24' +``` +### Thai WordNet + +import + +```python +from pythainlp.corpus import wordnet +``` + +**Use** + +It's like nltk. + +- wordnet.synsets(word) +- wordnet.synset(name_synsets) +- wordnet.all_lemma_names(pos=None, lang="tha") +- wordnet.all_synsets(pos=None) +- wordnet.langs() +- wordnet.lemmas(word,pos=None,lang="tha") +- wordnet.lemma(name_synsets) +- wordnet.lemma_from_key(key) +- wordnet.path_similarity(synsets1,synsets2) +- wordnet.lch_similarity(synsets1,synsets2) +- wordnet.wup_similarity(synsets1,synsets2) +- wordnet.morphy(form, pos=None) +- wordnet.custom_lemmas(tab_file, lang) + +**Example** + +```python +>>> from pythainlp.corpus import wordnet +>>> print(wordnet.synsets('หนึ่ง')) +[Synset('one.s.05'), Synset('one.s.04'), Synset('one.s.01'), Synset('one.n.01')] +>>> print(wordnet.synsets('หนึ่ง')[0].lemma_names('tha')) +[] +>>> print(wordnet.synset('one.s.05')) +Synset('one.s.05') +>>> print(wordnet.synset('spy.n.01').lemmas()) +[Lemma('spy.n.01.spy'), Lemma('spy.n.01.undercover_agent')] +>>> print(wordnet.synset('spy.n.01').lemma_names('tha')) +['สปาย', 'สายลับ'] +``` + +### Find words with the most usage. + +```python +from pythainlp.rank import rank +rank(list) +``` + +returns dict + +**Example** + +```python +>>> rank(['แมง','แมง','คน']) +Counter({'แมง': 2, 'คน': 1}) +``` + +### Solve printing problems forget to change language + +```python +from pythainlp.change import * +``` + +- texttothai(str) - eng to thai. +- texttoeng(str) - thai to eng. + +### Thai Character Clusters (TCC) + +TCC : Mr.Jakkrit TeCho + +grammar : Wittawat Jitkrittum (https://github.com/wittawatj/jtcc/blob/master/TCC.g) + +Code : Korakot Chaovavanich + +**Example** + +```python +>>> from pythainlp.tokenize import tcc +>>> tcc.tcc('ประเทศไทย') +'ป/ระ/เท/ศ/ไท/ย' +``` + +### Enhanced Thai Character Cluster (ETCC) + +**Example** + +```python +>>> from pythainlp.tokenize import etcc +>>> etcc.etcc('คืนความสุข') +'/คืน/ความสุข' +``` + +### Thai Soundex + +credit Korakot Chaovavanich (from https://gist.github.com/korakot/0b772e09340cac2f493868da035597e8) + +- LK82 +- Udom83 + +**Example** + +```python +>>> from pythainlp.soundex import LK82 +>>> print(LK82('รถ')) +ร3000 +>>> print(LK82('รด')) +ร3000 +>>> print(LK82('จัน')) +จ4000 +>>> print(LK82('จันทร์')) +จ4000 +>>> print(Udom83('รถ')) +ร800000 +``` + +### Thai meta sound + +``` +Snae & Brückner. (2009). Novel Phonetic Name Matching Algorithm with a Statistical Ontology for Analysing Names Given in Accordance with Thai Astrology. Retrieved from https://pdfs.semanticscholar.org/3983/963e87ddc6dfdbb291099aa3927a0e3e4ea6.pdf +``` + +**Example** + +```python +>>> from pythainlp.MetaSound import * +>>> MetaSound('คน') +'15' +``` + +### Thai sentiment analysis + +using data from [https://github.com/wannaphongcom/lexicon-thai/tree/master/ข้อความ/](https://github.com/wannaphongcom/lexicon-thai/tree/master/ข้อความ/) + +```python +from pythainlp.sentiment import sentiment +sentiment(str) +``` + +input str returns pos , neg or neutral + +### Util + +using + +```python +from pythainlp.util import * +``` + +#### ngrams + +for building ngrams + +```python +ngrams(token,num) +``` + +- token - list +- num - ngrams + +### Corpus + +#### Thai stopword + +```python +from pythainlp.corpus import stopwords +stopwords = stopwords.words('thai') +``` + +#### Thai country name + +```python +from pythainlp.corpus import country +country.get_data() +``` + +#### Tone in Thai + +```python +from pythainlp.corpus import tone +tone.get_data() +``` + +#### Consonant in thai + +```python +from pythainlp.corpus import alphabet +alphabet.get_data() +``` + +#### Word list in thai + +```python +from pythainlp.corpus.thaiword import get_data # old data +get_data() +from pythainlp.corpus.newthaiword import get_data # new data +get_data() +``` diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index 4b2a6de01..fbcc336e6 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -50,12 +50,12 @@ word_tokenize(text,engine) ``` text คือ ข้อความในรูปแบบสตริง str เท่านั้น -engine คือ ระบบตัดคำไทย ปัจจุบันนี้ PyThaiNLP ได้พัฒนามี 3 engine ให้ใช้งานกันดังนี้ +engine คือ ระบบตัดคำไทย ปัจจุบันนี้ PyThaiNLP ได้พัฒนามี 6 engine ให้ใช้งานกันดังนี้ 1. icu - engine ตัวดั้งเดิมของ PyThaiNLP (ความแม่นยำต่ำ) และเป็นค่าเริ่มต้น 2. dict - เป็นการตัดคำโดยใช้พจานุกรมจาก thaiword.txt ใน corpus (ความแม่นยำปานกลาง) จะคืนค่า False หากข้อความนั้นไม่สามารถตัดคำได้ 3. mm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย - API ชุดเก่า -4. newmm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ โดยใช้โค้ดคุณ Korakot Chaovavanich จาก https://www.facebook.com/groups/408004796247683/permalink/431283740586455/ มาพัฒนาต่อ * **หมายเหตุ API ตัวนี้ยังไม่เสถียรพอสำหรับใช้งานในโปรแกรมจริง ควรใช้เพื่อการศึกษาหรือวิจัยเท่านั้น อาจจากอยู่ในช่วงกำลังพัฒนา** +4. newmm - ใช้ Maximum Matching algorithm ในการตัดคำภาษาไทย โค้ดชุดใหม่ โดยใช้โค้ดคุณ Korakot Chaovavanich จาก https://www.facebook.com/groups/408004796247683/permalink/431283740586455/ มาพัฒนาต่อ 5. pylexto ใช้ LexTo ในการตัดคำ 6. deepcut ใช้ deepcut จาก https://github.com/rkcosmos/deepcut ในการตัดคำภาษาไทย From 02d7db6f8102bd78c03b559bc37181e9d50e71e7 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Thu, 6 Jul 2017 12:59:43 +0700 Subject: [PATCH 68/71] fix docs --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 357492dfd..da66ca3e8 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ $ CFLAGS=-I/usr/local/opt/icu4c/include LDFLAGS=-L/usr/local/opt/icu4c/lib pip i ### Documentation -Read on https://github.com/wannaphongcom/pythainlp/blob/pythainlp1.4/docs/pythainlp-1-4-thai.md +Read on https://github.com/wannaphongcom/pythainlp/blob/pythainlp1.4/docs/pythainlp-1-4-eng.md ### License @@ -68,6 +68,11 @@ Apache Software License 2.0 ## ภาษาไทย +[![PyPI Downloads](https://img.shields.io/pypi/dm/pythainlp.png)] +[![pypi](https://img.shields.io/pypi/v/pythainlp.svg)](https://pypi.python.org/pypi/pythainlp) +[![Build Status](https://travis-ci.org/wannaphongcom/pythainlp.svg?branch=develop)](https://travis-ci.org/wannaphongcom/pythainlp) +[![Build status](https://ci.appveyor.com/api/projects/status/uxerymgggp1uch0p?svg=true)](https://ci.appveyor.com/project/wannaphongcom/pythainlp)[![Code Issues](https://www.quantifiedcode.com/api/v1/project/7f699ed4cad24be18d0d24ebd60d7543/badge.svg)](https://www.quantifiedcode.com/app/project/7f699ed4cad24be18d0d24ebd60d7543)[![Coverage Status](https://coveralls.io/repos/github/wannaphongcom/pythainlp/badge.svg?branch=pythainlp1.4)](https://coveralls.io/github/wannaphongcom/pythainlp?branch=pythainlp1.4) + ประมวลภาษาธรรมชาติภาษาไทยในภาษา Python Natural language processing หรือ การประมวลภาษาธรรมชาติ โมดูล PyThaiNLP เป็นโมดูลที่ถูกพัฒนาขึ้นเพื่อพัฒนาการประมวลภาษาธรรมชาติภาษาไทยในภาษา Python และ**มันฟรี (ตลอดไป) เพื่อคนไทยและชาวโลกทุกคน !** From b9b8fcb17e0ef8a6f17ea4d6e3110893036abece Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Thu, 6 Jul 2017 13:01:38 +0700 Subject: [PATCH 69/71] fix docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index da66ca3e8..73ac0d84c 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Thai natural language processing in Python. -PyThaiNLP is python module like nltk , but It'working thai language. +PyThaiNLP is python module like nltk , but It's working with thai language. It's support python 3.4 +. From 3c895ea2f710d18d94cac92b02ac1c08cc58c9f0 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Thu, 6 Jul 2017 13:08:18 +0700 Subject: [PATCH 70/71] fix bug in pyicu --- pythainlp/tokenize/pyicu.py | 46 ++++++++++++++++++------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/pythainlp/tokenize/pyicu.py b/pythainlp/tokenize/pyicu.py index 0ac0e2cce..0a1d2a8ef 100644 --- a/pythainlp/tokenize/pyicu.py +++ b/pythainlp/tokenize/pyicu.py @@ -9,35 +9,35 @@ def isEnglish(s): เช็คว่าตัวอักษรเป็นภาษาอังกฤษหรือไม่ ''' try: - try: - s.encode('ascii') - except UnicodeEncodeError: - return False - else: - return True - except: - try: - s.decode('ascii') - except UnicodeDecodeError: - return False - else: - return True + try: + s.encode('ascii') + except UnicodeEncodeError: + return False + else: + return True + except: + try: + s.decode('ascii') + except UnicodeDecodeError: + return False + else: + return True def isThai(chr): ''' เช็คตัวอักษรว่าใช่ภาษาไทยไหม ''' if isEnglish(chr): - return False - try: - '''cVal = ord(chr) - if(cVal >= 3584 and cVal <= 3711): - return True''' - if detect(chr)=='th': - return True - else: + return False + try: + '''cVal = ord(chr) + if(cVal >= 3584 and cVal <= 3711): + return True''' + if detect(chr)=='th': + return True + else: return False - except: - return False + except: + return False def segment(txt): """รับค่า ''str'' คืนค่าออกมาเป็น ''list'' ที่ได้มาจากการตัดคำโดย ICU""" bd = icu.BreakIterator.createWordInstance(icu.Locale("th")) From ec0afd139044b16b1770c83376e21402bbdb1142 Mon Sep 17 00:00:00 2001 From: Wannaphong Phatthiyaphaibun Date: Thu, 6 Jul 2017 13:28:23 +0700 Subject: [PATCH 71/71] 1.4: Auto stash before merge of "pythainlp1.4" and "origin/pythainlp1.4" --- docs/pythainlp-1-4-thai.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pythainlp-1-4-thai.md b/docs/pythainlp-1-4-thai.md index fbcc336e6..35a3f7f97 100644 --- a/docs/pythainlp-1-4-thai.md +++ b/docs/pythainlp-1-4-thai.md @@ -234,7 +234,7 @@ from pythainlp.change import * PyThaiNLP 1.4 รองรับ Thai Character Clusters (TCC) โดยจะแบ่งกลุ่มด้วย / -เดติด +**เดติด** TCC : Mr.Jakkrit TeCho