From 47b746433180049079597b3a5c78ae3db327f2ea Mon Sep 17 00:00:00 2001 From: kimbyungnam Date: Tue, 6 Nov 2018 01:04:17 +0900 Subject: [PATCH] Add basic Korean support korean stopwords references http://pydoc.net/lexrankr/0.1.5/lexrankr.lexrankr/ https://www.ranks.nl/stopwords/korean --- .travis.yml | 14 +- setup.py | 1 + sumy/data/stopwords/korean.txt | 722 +++++++++++++++++++++++++++++++++ sumy/nlp/stemmers/__init__.py | 3 +- sumy/nlp/tokenizers.py | 23 +- tests/test_tokenizers.py | 22 + 6 files changed, 775 insertions(+), 10 deletions(-) create mode 100644 sumy/data/stopwords/korean.txt diff --git a/.travis.yml b/.travis.yml index 0cfda35b..61676407 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,28 +1,26 @@ -language: - - python +language: python python: # https://github.com/travis-ci/travis-ci/issues/2219#issuecomment-41804942 # https://snarky.ca/how-to-use-your-project-travis-to-help-test-python-itself/ - "2.7" - - "3.3" - "3.4" - "3.5" - "3.5-dev" - "3.6" - "3.6-dev" + - "3.7" - "3.7-dev" + - "3.8-dev" - "nightly" before_install: # install dependencies for NumPy - sudo apt-get update -qq - sudo apt-get install -qq gfortran libatlas-base-dev - sudo apt-get install -qq python-numpy - - sudo apt-get install -qq pandoc install: - pip install -U pip wheel setuptools - - pip install -U --use-wheel pytest pytest-cov + - pip install -U pytest pytest-cov - python setup.py install - - pip install -U tinysegmenter jieba + - pip install -U tinysegmenter jieba konlpy - python -c "import nltk; nltk.download('punkt')" -script: - - pytest tests +script: pytest tests diff --git a/setup.py b/setup.py index bc3ea9fa..847a56e5 100644 --- a/setup.py +++ b/setup.py @@ -51,6 +51,7 @@ "LexRank": ["numpy"], "Japanese": ["tinysegmenter"], "Chinese": ["jieba"], + "Korean": ["konlpy"], }, packages=find_packages(), package_data={"sumy": [ diff --git a/sumy/data/stopwords/korean.txt b/sumy/data/stopwords/korean.txt new file mode 100644 index 00000000..2591b5df --- /dev/null +++ b/sumy/data/stopwords/korean.txt @@ -0,0 +1,722 @@ +그렇지 +보는데서 +좍좍 +어느해 +총적으로 보면 +를 +겸사겸사 +이천구 +할 줄 안다 +이렇게말하자면 +어때 +쳇 +줄은모른다 +딩동 +해서는 안된다 +등등 +하여금 +것과 +얼마 +타다 +정도에 이르다 +비길수 +구 +그들 +쓰여 +그위에 +아이구 +하는 김에 +불문하고 +하지마 +된바에야 +바꾸어말하자면 +논하지 않다 +일지라도 +자마자 +어떻해 +그러면 +넷 +관련이 있다 +여차 +하든지 +으로 인하여 +까지도 +요만한 +툭 +저희 +여 +셋 +한켠으로는 +봐 +차라리 +사 +누구 +에게 +어느곳 +보다더 +누가 +없고 +탕탕 +단지 +그러니 +영 +김에 +영 +한데 +비슷하다 +바꾸어말하면 +예를 +하게될것이다 +공동으로 +향해서 +논하지 +까지 미치다 +결론을 낼 수 있다 +기점으로 +년 +동시에 +하지 +거의 +뿐만 아니라 +한마디 +개의치않고 +야 +당장 +그렇지않으면 +그치지 않다 +하여야 +여러분 +하면서 +두번째로 +말하면 +이러이러하다 +붕붕 +허허 +아울러 +비추어 +혹은 +이와 같은 +할수있어 +하기 +비추어 보아 +로 인하여 +그러니까 +아니라 +예 +쪽 +딱 +생각이다 +만이 아니다 +정도의 +이르다 +부류의 +그리고 +하마터면 +아니 +점에서 +까지 +하는것만 +들자면 +팍 +또 +이봐 +그런 +제 +예컨대 +줄 +하는것만 못하다 +영차 +물론 +아무도 +이번 +그렇지 않다면 +부류의 사람들 +한다면 +관계없이 +자신 +알 +후 +령 +저기 +않는다면 +할만하다 +여부 +와르르 +에 가서 +이런 +이지만 +어 +밖에 +가까스로 +달려 +다른 +어찌 +요컨대 +한 까닭에 +등 +어떤것 +오직 +함으로써 +왜 +모두 +다만 +아니었다면 +낫다 +응당 +못하다 +좀 +있다 +허 +그만이다 +본대로 +하기만 +이쪽 +그러한즉 +의해서 +아니라면 +안다 +이리하여 +이로 인하여 +그에 +와 +어이 +다음 +안 +관하여 +잠시 +할 +으로 +게다가 +만 +그렇게 +그중에서 +그래 +대하여 +하기 위하여 +이 정도의 +양자 +정도에 +하더라도 +졸졸 +어떤것들 +해봐요 +예를 들면 +할지언정 +하는 편이 낫다 +방면으로 +기타 +구체적으로 +앗 +어떠한 +의거하여 +앞의것 +그치지 +하다 +하지마라 +더욱더 +위에서 서술한바와같이 +쿵 +아니면 +더라도 +그래서 +삐걱거리다 +하게하다 +만 못하다 하기보다는 +저것 +뚝뚝 +따르는 +각 +이천칠 +가 +까악 +예를 들자면 +할뿐 +나 +보면 +지말고 +거니와 +반대로 말하자면 +결과에 +주저하지 않고 +너 +이천육 +형식으로 +게우다 +관한 +어찌하든지 +않다 +않기 +여기 +할 생각이다 +모 +지만 +비로소 +봐라 +상대적으로 +것과 같이 +무엇 +소인 +이와 반대로 +헐떡헐떡 +오르다 +해요 +임에 틀림없다 +이 +토하다 +만이 +어떤 +만은 아니다 +참 +할때 +아이쿠 +의해되다 +하물며 +너희들 +이 되다 +그렇지 않으면 +콸콸 +즉시 +너희 +에서 +누가 알겠는가 +더군다나 +다시말하면 +알았어 +얼마 안 되는 것 +일단 +앞에서 +바꿔 +결론을 +총적으로 말하면 +허걱 +요만큼 +아니나다를가 +틀림없다 +할망정 +이렇게되면 +륙 +참나 +까닭에 +이 밖에 +둘 +얼마큼 +그때 +향하여 +퍽 +비교적 +말할것도 없고 +습니다 +로 +그런데 +그런즉 +들 +비록 +않고 +에 +형식으로 쓰여 +불구하고 +흥 +답다 +어쩔수 없다 +즈음하여 +끼익 +응 +및 +자기 +저것 +이럴정도로 +년도 +옆사람 +우리 +임에 +연관되다 +틈타 +조차도 +말하자면 +뿐이다 +하도록하다 +이와 같다 +어찌됏어 +아이 +한적이있다 +여덟 +우에 +엉엉 +이로 +않다면 +이용하여 +퉤 +지든지 +힘이 +서술한바와같이 +따라 +예하면 +매 +어디 +함께 +다소 +매번 +우에 종합한것과같이 +근거하여 +가령 +중에서 +전후 +않으면 +일곱 +어느때 +하도록시키다 +나머지는 +바꾸어서 말하면 +이렇구나 +삼 +이 때문에 +생각한대로 +바꿔 말하면 +끙끙 +휴 +관해서는 +와 같은 사람들 +알 수 있다 +대하면 +갖고말하자면 +가서 +아하 +할 지경이다 +의해 +오히려 +만 못하다 +결과에 이르다 +오 +어찌됐어 +라 해도 +아야 +무릎쓰고 +아이야 +해도 +알겠는가 +해서는 +하는 +까닭으로 +되다 +어찌하여 +만큼 어찌됏든 +과연 +마저 +그에 따르는 +하면 +이때 +지경이다 +그 +인하여 +든간에 +소생 +몰라도 +같이 +다른 방면으로 +이것 +밖에 안된다 +얼마나 +의 +이래 +메쓰겁다 +실로 +훨씬 +윙윙 +에 달려 있다 +꽈당 +이와 +저쪽 +때 +보아 +부터 +듯하다 +진짜로 +자 +잇따라 +같은 +입각하여 +때가 되어 +이와같다면 +아홉 +조금 +인젠 +총적으로 +힘입어 +대해서 +그러므로 +을 +할줄알다 +주저하지 +우르르 +되는 +어느쪽 +댕그 +하려고하다 +시작하여 +더구나 +일 +미치다 +전부 +쉿 +그러나 +않기 위하여 +종합한것과같이 +위해서 +통하여 +외에 +제외하고 +만일 +바로 +하곤하였다 +얼마만큼 +놀라다 +그리하여 +에 한하다 +할지라도 +쪽으로 +으로써 +몇 +하느니 +무엇때문에 +많은 +주룩주룩 +로써 +휘익 +일것이다 +혼자 +하려고 +한항목 +그런 까닭에 +않기 위해서 +하는것도 +안 그러면 +로부터 +삐걱 +하기에 +도착하다 +여보시오 +얼마간 +고로 +해야한다 +반드시 +했어요 +네 +첫번째로 +할수록 +일반적으로 +아무거나 +마치 +요만한 것 +하구나 +어느것 +이렇게 +다시 말하자면 +운운 +으로서 +남들 +할 따름이다 +이렇게 많은 것 +전자 +바꾸어서 한다면 +어느 년도 +관계가 있다 +월 +것들 +각각 +같다 +와아 +따지지 +과 +설령 +그저 +하는바 +언젠가 +이 외에 +하기 때문에 +위하여 +이젠 +인 듯하다 +기대여 +우리들 +동안 +아래윗 +이외에도 +따름이다 +둥둥 +솨 +헉 +하고있었다 +하면 할수록 +하지만 +대로 하다 +비하면 +위에서 +된이상 +시각 +보드득 +그럼에도 불구하고 +하 +그럼 +즉 +제각기 +습니까 +만은 +하나 +그렇지만 +잠깐 +어떻게 +이천팔 +중의하나 +수 +버금 +할 힘이 있다 +여섯 +팔 +낼 +기준으로 +에 대해 +때가 +편이 +다시 +할수있다 +뿐만아니라 +비길수 없다 +어쨋든 +뿐만 +라 +외에도 +따지지 않다 +여전히 +하면된다 +말할것도 +안된다 +헉헉 +저것만큼 +다수 +없다 +하겠는가 +하지 않는다면 +뒤따라 +오로지 +만약에 +또한 +겨우 +한 +하기보다는 +오호 +심지어 +근거로 +요만한걸 +향하다 +왜냐하면 +하자마자 +다음으로 +견지에서 +우선 +연이서 +도달하다 +어느 +각자 +모른다 +이러한 +때문에 +몰랏다 +만약 +곧 +한하다 +설마 +육 +이르기까지 +대로 +관계가 +남짓 +대해 +더욱이는 +그럼에도 +인 +무렵 +하기는한데 +아 +쾅쾅 +마저도 +거바 +다섯 +자기집 +하하 +더불어 +어기여차 +마음대로 +이어서 +관련이 +한다면 몰라도 +어쩔수 +칠 +그래도 +시키다 +어째서 +이었다 +반대로 +되어 +이라면 +들면 +어찌됐든 +하는것이 +이상 +해도좋다 +하도다 +사람들 +따라서 +아이고 +고려하면 +그렇게 함으로써 +무슨 +한 후 +혹시 +하지 않도록 +뒤이어 +시간 +바와같이 +한 이유는 +이유만으로 +시초에 +설사 +구토하다 +해도된다 +에 있다 +좋아 +흐흐 +바꾸어서 +않도록 +만큼 +펄렁 +타인 +오자마자 +언제 +각종 +상대적으로 말하자면 +일때 +대해 말하자면 +따위 +당신 +이곳 +얼마든지 +하고 +아니다 +의지하여 +다음에 +막론하고 +것 +저 +하기만 하면 +줄은 +점에서 보아 +조차 +입장에서 +결국 +비걱거리다 +하고 있다 +약간 +하는것이 낫다 +줄은 몰랏다 +이만큼 +이유는 diff --git a/sumy/nlp/stemmers/__init__.py b/sumy/nlp/stemmers/__init__.py index 5963329a..ee186fd3 100644 --- a/sumy/nlp/stemmers/__init__.py +++ b/sumy/nlp/stemmers/__init__.py @@ -21,7 +21,8 @@ class Stemmer(object): 'czech': czech_stemmer, 'slovak': czech_stemmer, 'chinese': null_stemmer, - 'japanese': null_stemmer + 'japanese': null_stemmer, + 'korean': null_stemmer } def __init__(self, language): diff --git a/sumy/nlp/tokenizers.py b/sumy/nlp/tokenizers.py index 15f102b8..4cf4eb89 100644 --- a/sumy/nlp/tokenizers.py +++ b/sumy/nlp/tokenizers.py @@ -34,6 +34,25 @@ def tokenize(self, text): raise ValueError("Chinese tokenizer requires jieba. Please, install it by command 'pip install jieba'.") return jieba.cut(text) +class KoreanSentencesTokenizer: + def tokenize(self, text): + try: + from konlpy.tag import Kkma + except ImportError as e: + raise ValueError("Korean tokenizer requires konlpy. Please, install it by command 'pip install konlpy'.") + kkma = Kkma() + return kkma.sentences(text) + + +class KoreanWordTokenizer: + def tokenize(self, text): + try: + from konlpy.tag import Kkma + except ImportError as e: + raise ValueError("Korean tokenizer requires konlpy. Please, install it by command 'pip install konlpy'.") + kkma = Kkma() + return kkma.nouns(text) + class Tokenizer(object): """Language dependent tokenizer of text document.""" @@ -53,12 +72,14 @@ class Tokenizer(object): SPECIAL_SENTENCE_TOKENIZERS = { 'japanese': nltk.RegexpTokenizer('[^ !?。]*[!?。]'), - 'chinese': nltk.RegexpTokenizer('[^ !?。]*[!?。]') + 'chinese': nltk.RegexpTokenizer('[^ !?。]*[!?。]'), + 'korean': KoreanSentencesTokenizer() } SPECIAL_WORD_TOKENIZERS = { 'japanese': JapaneseWordTokenizer(), 'chinese': ChineseWordTokenizer(), + 'korean': KoreanWordTokenizer() } def __init__(self, language): diff --git a/tests/test_tokenizers.py b/tests/test_tokenizers.py index ddae56bc..1af8cd0a 100644 --- a/tests/test_tokenizers.py +++ b/tests/test_tokenizers.py @@ -128,3 +128,25 @@ def test_tokenize_chinese_paragraph(): paragraph = '我正在为这个软件添加中文支持。这个软件是用于文档摘要!这个软件支持网页和文本两种输入格式?' assert expected == tokenizer.to_sentences(paragraph) + + +def test_tokenize_korean_sentence(): + tokenizer = Tokenizer('korean') + assert tokenizer.language == 'korean' + + sentence = '대학에서 DB, 통계학, 이산수학 등을 배웠지만...' + expected = ('대학', '통계학', '이산', '이산수학', '수학', '등') + assert expected == tokenizer.to_words(sentence) + + +def test_tokenize_korean_paragraph(): + tokenizer = Tokenizer('korean') + expected = ( + '회사 동료 분들과 다녀왔는데 분위기도 좋고 음식도 맛있었어요', + '다만, 강남 토끼 정이 강남 쉑쉑 버거 골목길로 쭉 올라가야 하는데 다들 쉑쉑버거의 유혹에 넘어갈 뻔 했답니다', + '강남 역 맛 집 토끼정의 외부 모습.' + ) + + + paragraph = '회사 동료 분들과 다녀왔는데 분위기도 좋고 음식도 맛있었어요 다만, 강남 토끼정이 강남 쉑쉑버거 골목길로 쭉 올라가야 하는데 다들 쉑쉑버거의 유혹에 넘어갈 뻔 했답니다 강남역 맛집 토끼정의 외부 모습.' + assert expected == tokenizer.to_sentences(paragraph) \ No newline at end of file