LoginSignup
2
1

韓国語の形態素解析パッケージSoynlp (pure Python)

Last updated at Posted at 2023-06-20

はじめに

韓国語の形態素解析ではkoNLPyを利用することができますが、辞書に未登録の単語の認識がうまくできないという点があります。これにうまく対処するためにPythonのみで作られたパッケージがSoynlpということのようです。(MeCabに対するJanomeのようなもののようです)

紹介の内容は以下の記事をもとにしています。

インポート&コーパス

!pip install soynlp

コーパスのダウンロード

!wget https://raw.githubusercontent.com/lovit/soynlp/master/tutorials/2016-10-20.txt -O 2016-10-20.txt

こんな感じのファイル
スクリーンショット 2023-06-21 1.26.55.png

コーパスの読み込み

行、または2つのスペースで文が区切られているとして、DoublespaceLineCorpusで読み込むとコーパスのオブジェクトが生成される。
なぜ2つのスペース区切りなのかは不明。

from soynlp import DoublespaceLineCorpus

# iter_sent=Trueだと1行に複数文を許容する
corpus = DoublespaceLineCorpus("2016-10-20.txt", iter_sent=True)

オブジェクトの中身はこのような感じ。
スクリーンショット 2023-06-21 1.29.27.png

単語抽出

先ほどのコーパスをもとに単語抽出を行う。なお、koNLPyのように辞書ベースでの分析ではないため、与えられたコーパスでの学習を行う。

from soynlp.word import WordExtractor

word_extractor = WordExtractor()
word_extractor.train(corpus) # 50秒くらいかかる

分割の学習がされた単語ごとに、cohesion, branching entropy, accessor varietyというパラメータが算出され、単語ごとに諸々確認できるらしい

# 各単語でのスコアを算出
word_score = word_extractor.extract()

# cohesion: P(연합|연)で表される生起確率
word_score["연합"].cohesion_forward
#=>0.1943363253634125

# branching entropy: 次に出てくる文字のエントロピー(例えば確実に一文字しかない場合は0になる)
word_score["연합"].right_branching_entropy
#=>0.42721236711742844

# accessor variety: 次に出てくる文字の種類の数
word_score["연합"].right_accessor_variety
#=>42

L-トークン化

韓国語は分かち書きされるものの、その分かち書きにおいては、助詞やサ変動詞における「する」の部分のようなものはくっつけて書きます。そのため、左側のトークンと右側のトークンに分ける機能がsoynlpにあります。

from soynlp.tokenizer import LTokenizer

scores = {word:score.cohesion_forward for word, score in word_score.items()}
l_tokenizer = LTokenizer(scores=scores)

l_tokenizer.tokenize("안전성에 문제있는 스마트폰을 휴대하고 탑승할 경우에 압수한다", flatten=False)

#=>
[('안전', '성에'), # 安全/上に
 ('문제', '있는'), # 問題/がある
 ('스마트폰', ''), # スマートフォン/を
 ('휴대', '하고'), # 携帯/して 
 ('탑승', ''), # 搭乗/する
 ('경우', ''), # 場合/に
 ('압수', '한다')] # 押収/する

最大スコアでの分かち書き

分かち書きすることが韓国語の正書法ではありますが、ネットの書き込みなどで分かち書きを全くしていない文などが存在しています。このような文に対する前処理として使える分かち書きの手法です。

from soynlp.tokenizer import MaxScoreTokenizer

maxscore_tokenizer = MaxScoreTokenizer(scores=scores)
maxscore_tokenizer.tokenize("안전성에문제있는스마트폰을휴대하고탑승할경우에압수한다")

#=>
['안전',
 '성에',
 '문제',
 '있는',
 '스마트폰',
 '',
 '휴대',
 '하고',
 '탑승',
 '',
 '경우',
 '',
 '압수',
 '한다']

おわりに

これを使う日本人、いるのか...?

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1