Pythonで動かして学ぶ 自然言語処理入門を読んだ
tags: 自然言語処理ToC
何を学ぶか
機械学習その他もろもろで文章をこねくり回す機会が増えたが、
前に買ったまま放置していた「Pythonで動かして学ぶ 自然言語処理入門」があったので引っ張り出して学習することにした
自然言語処理の基礎力がないので、機械学習ばかりを調べるのではなく、自然言語処理の学習に活かせる基礎ついて学べればと思う
unicodeの正規化
自然言語処理を行う際の前処理の一つに、Unicodeの正規化がある
具体的には半角全角をそろえたり、①と1のように等価な文字をまとめてくれる
正規化の方法は4種類ある
- NFD
- Normalization Form Canonical Decomposition
- NFC
- Normalization Form Canonical Composition
- NFKD
- Normalization Form Compatibility Decomposition
- NFKC
- Normalization Form Compatibility Composition
Canonicalは正規の、という意味
前者二つが同一としてみなす条件が厳しく(正準等価性)、後者二つが緩い (互換等価性)
NFDの後に再度合成するのがNFC、NFKDの後再度合成するのがNFKC
NFKCがよくつかわれているみたい。NFだと①と1を区別するが、NFKだと区別しない
正規化がそもそも文字の合成と分解、という概念で行われるらしい
文字の合成は規定文字と結合文字の組み合わせによる結合文字列を単一の合成済み文字にする手続き。か゛をがにするって感じかな
合成と分解は等価性
という概念に基づく。この等価性が先述の通り2種類ある
Canonicalは機能的に等しく視覚的にも識別不可能であるべき文字を識別する
Compatibilityは視覚的に異なり、意味的にも異なるかもしれないものを識別する
後者が緩い
Solrを使う
SQLiteは経験があったが、Solrはなかったのでこの本で触って覚えたことをメモしようと思う
とりあえず本のダウンロード手順が面倒だったのでDockerで構築
検索対象のデータセットのことをコアと呼ぶ。solr create -c doc
で作成可能
ダイナミックフィールド
事前にフィールド名と型を定義しなくてもデータを突っ込める仕組み。suffixで型が決まる
- _iで整数
- _txt_jaで日本語
- _sで文字列
クエリの書き方
content_txt_ja:なんとか
AND content_txt_ja:かんとか
のようにANDかORでつなぐ
*でn個の任意の文字列
単語を石油ガスだと、石油とガスで検索されるが、""で囲むと石油ガスのみが対象になる
日本語の構文解析
係り受け解析、句構造解析がある
この本ではCaboChaを使って構文を解析する
SudachiやMecabなど自然言語処理ライブラリは食べ物が多い
私はトンカツを食べて午後に筋トレをした
のような文章があるとき、私は~食べて、のように主語と述語などの句の依存関係を解析するものを係り受け解析と呼ぶそうな
文章の区切りを文節
と呼ぶ。
文章を解析して、文節間の修飾関係による文法構造を係り受け構造
と呼ぶ
文節じゃなくて単語の修飾関係を表す流派もあるそう。英語は単語が一般的
日本語はてにをはがあるからな~
cabochaで構文解析
installめっちゃしんどかった...
- 品詞について学ぼう
- 名詞
- 動詞
- 形容詞
- 連体詞
- あの、この、その、たいした
- 語尾がの、る、な、た・だ、になるそう
- など。名詞を修飾し、活用がない自立語
- あの、この、その、たいした
- 副詞
- 接続詞
- 接頭詞
- 感動詞
- フィラー
- あ~、えっと~、その~
- 記号
- !$。、など
- 助詞
- は、が、を
- 格助詞
- 庭の~、本を~、みたいなね
- 接続助詞
- 朝起きて~
- XXになると~
- 副助詞
- この本は、この本だけ、この本まで、この本など
- 終助詞
- ~ですか?、~ですよ、など話し手から聞き手へ
- 助動詞
- た、ます、れる、られる
- 用言(動詞、形容詞、形容動詞)や体言(モノことを表す活用のない言葉、名詞)に意味を添える語
Parseするとtreeができて、その中にchunkがあり、chunkが複数tokenを含む
グーグル、みたいな辞書になさそうな単語を入れるとlemmaが*になる
精度指標
文章を分割し、アノテーションを付与する場合、その精度を確認したいことがある。
自然言語処理は人間がやったとしても結果が100%にならないものが多い。「赤いボールの下にあるテーブル」という文章では、ボールとテーブルどちらが赤いかわからない
- Recall(再現率)
- 抽出すべきもののうち、正しい対象を抽出した割合
- こっちは全体で10あるけど3だったら3/10
- 100% - 抽出漏れの割合
- 抽出すべきもののうち、正しい対象を抽出した割合
- Precision(適合率)
- 抽出されたもののうち正しい対象を抽出した割合
- 5つ抽出して、あたりが3だったら3/5
- 100% - 誤抽出の割合
- 抽出されたもののうち正しい対象を抽出した割合
この両方の指針でもって、対象のみをもれなく取得できると精度が高い
テキストマイニング
テキストデータの集合を分析して、何かしらの知見を見出すことを指す
ここでは統計的な手法を覚える
トレンドとか、類似文章の検索とか、カテゴライズとか
tf-idf
term frequencyとinverse document frequency。前者がある文書の単語の出現具合。後者がその単語が出てくる文書の割合の逆数(全文書数をその単語が出てくる文書で割った値)。他であまり使われず、少ない文書で多く登場する単語は重要だよね~と判断する指標
ある単語の重要度的なもの
sklearnのTfidfVectorizerを使うと、文書*単語のtf-idf行列を作れる。
この行列でコサイン類似度を取ると、単語の出現頻度で似ている文書を探すことができる
n-gram
言語モデルの一つ。単語の出現確率が、その前のn-1個の単語にのみ依存すると仮定したモデル
テキストをn文字ずつseekして抜き出したものも同じ名前だった気がする。文脈によって違うのか?
言語モデルとしてのものと、転置インデックスの文脈とかがあるっぽ
MB25
tf-idfを発展させたもの
文書の長さを考慮するようになり、一致する単語が多くても、文書が長いときはその分スコアが下がるように調整されている。tf-idfは長い文章に対してスコアが大きくなるとかなんとか
文書の集合全体で登場する単語のスコアが低いのはtf-idfと同じ
LDA(Latent Dirichlet Allocation)
トピックモデルの一つでテキストをクラスタリングするときに使われる
サンプルだけだとよーわからんかったな...
これもまた文章の中の単語の分布であれこれ判断する系っぽい
知識情報
DBPedia、WordNet、Word2Vecについて説明される
DBPediaは昔触ったことがあった。SPARQLというグラフDBへの問い合わせ言語、で問い合わせるんだったはず
雑多めも
- wikiのデータであれこれやっていく感じのようだ。データのparseには
beautifulsoup
を使っている。だいぶ楽に引っこ抜けるな str.maketrans
関数は使ったことなかった。変換表を作って、strのtranslate関数に投げ込める- 掛け算の対数値は、対数値の足し算と等しい。なので計算では対数の足し算が使われる。0~1の値を乗算し続けると小さくなっちゃうからそれの回避方法
- $log_{ab} = log_a + log_b$