Doc2Vec実践

 
 
 
学習済みモデルのロード

 
・学習済みモデルでDoc2Vecを色々試してみる
 
 
from gensim.models.doc2vec import Doc2Vec
 
model = Doc2Vec.load('jawiki.doc2vec.dbow300d.model')
 
 
 
 
 
Doc2Vecのメソッドを確認

 
# modelオブジェクトのメソッド一覧
for x in dir(model):
print(x)
 
 
# model.docvecsオブジェクトのメソッド一覧
for x in dir(model.docvecs):
print(x)
 
 
 
 
訓練データの確認

 
model.docvecs.doctags
 
 
# tagをリスト化
tags=
for tag in model.docvecs.doctags.keys():
tags.append(tag)
 
tags[:10]
 
 
# tagの存在確認
print('東京' in model.docvecs.doctags)
 
 
 
 
 
文章の解析

 
# 文章ベクトルの表示
print(model.docvecs['東京'])
 
 
# 類似するドキュメントを表示
model.docvecs.most_similar('東京')
 
 
 
# 文書の類似度を算出する
model.docvecs.similarity('東京', '大阪')
#0.43720797
model.docvecs.similarity('東京', 'パリ')
#0.34880832
 
 
 
 
 
未知の入力文を解析

 
import MeCab
 
def tokenize(text):
wakati = MeCab.Tagger("-O wakati")
wakati.parse("")
return wakati.parse(text).strip().split()
 
text = """バーレーンの首都マナマ(マナーマとも)で現在開催されている
ユネスコ(国際連合教育科学文化機関)の第42回世界遺産委員会は日本の推薦していた
世界遺産に登録することを決定した。文化庁が同日発表した。
日本国内の文化財世界遺産登録は昨年に登録された福岡県の
「『神宿る島』宗像・沖ノ島と関連遺産群」に次いで18件目。
2013年の「富士山-信仰の対象と芸術の源泉」の文化遺産登録から6年連続となった。"""
 
# 文章を分かち書きして、ベクトル化
docs_vec = [model.infer_vector(tokenize(text))]
 
 
 
# 任意の入力文に対して類似するドキュメントを表示する
model.docvecs.most_similar(docs_vec)
 
 
 
 
単語の解析

 
# 単語のベクトル化
model.wv['東京']
 
 
# 単語の類似度計算
model.wv.most_similar('東京')
 
 
 
 

 

jupyter-themes


テーマを変更する

 
jupyter-themesというpipパッケージを使用することで、簡単にJupyterのテーマを変更することができます。
 
pip install jupyterthemes
 
 
もしうまくいかなかったら
pip install lesscpy
#LESSCPY(A compiler written in Python for the LESS language)
#これをやるとうまくいくらしい
 
 
 
$ jt -l #変更できるテーマのリストを表示
Available Themes:
chesterish
grade3
monokai
oceans16
onedork
solarizedd
solarizedl
 
 
jt -t monokai #変更したいテーマ
 
jt -r #デフォルトのテーマに戻す
 
<オプション>
-h    ヘルプ表示
-l    適用可能テーマ一覧
-t theme    テーマ適用
-f font    ソースコードセルのフォント
-fs n    ソースコードセルのフォントサイズ
-tf font    MarkDownセルのフォント
-tfs n    MarkDownセルのフォントサイズ
-dfs n    Pandasで生成した画像のフォントサイズ
-ofs n    結果出力セルのフォントサイズ
-T    ノートページにツールバーを表示
-N    ノートページにファイル名とロゴを表示
 
 
参照
 
 
 
 
 
 
好きなフォントを設定

 
・jupyter-themesでもフォント変更できますが、自分の好みのフォントに変更する場合は直接CSSを編集します。
 
div.CodeMirror,
div.CodeMirror pre {
font-family: 'Myrica M';
font-size: 13pt;
}
# 結果出力セル
div.output_subarea.output_text.output_stream.output_stdout,
div.output_subarea.output_text {
font-family: 'Myrica M';
font-size: 13pt;
}
div.output_area pre {
font-family: 'Myrica M';
font-size: 13pt;
}
# テキスト、MarkDownセル
div.text_cell,
div.text_cell_render pre,
div.text_cell_render {
font-family: sans-serif;
font-size: 13pt;
}
 
 
 
 
 
 
Nbextension導入

 
 
pip install jupyter_contrib_nbextensions
jupyter contrib nbextension install --user
 
 
下に各オプションの説明が書いてあるので色々見ながらカスタマイズしてください。
 
c.f.オススメのオプション
Code Font Size  コードの文字の大きさを一発変更できます
highlighter markdownにマーカーを引けます
zenmode 背景とか変えれるっぽいです。
 
 
 
参照
 
 
 
 
 
 
 
 
背景をシリコンバレーの夜景にする

 
zenmodeでは最初のメニュー画面での背景は設定できなかったので、
その方法を調べてみました。
 
 
vim
vi .jupyter/custom/custom.css
を編集する
 
・monokaiにすることで、cssが書き加えられています。
 
 
<div.body>
・最初のdiv.bodyのところで
 
 
background: #*****
のところを
 
に変える。
 

f:id:dgakio:20210122181631p:plain

 
 
*追記:画像を左右中央固定、画面いっぱいに拡大
 
body,
div.body {
font-family: sans-serif;
font-size: 13pt;
color: #f8f8f0;
background-color: #1e1e1e;
background-position: center center;
background-position: center center;
background-attachment: fixed;
background-size: cover;
-webkit-font-smoothing: antialiased !important;
}
 
 
 
<body.notebook_app>
:Notebookを開いた時の背景の設定
 
body.notebook_app {
padding: 0;
background-color: #1e1e1e;
background-position: center center;
background-repeat: no-repeat;
background-attachment: fixed;
background-size: cover;
padding-right: 0px !important;
overflow-y: hidden;
}

Doc2Vec実装 livedoor JUMAN

Doc2Vec実装

 
livedoor newsコーパスの文章の類似度を比較します。
 
 
 
 
JUMANを用いて訓練データを作成

 
# import
import sys
from os import listdir, path
from pyknp import Juman, Jumanpp
from gensim import models
from gensim.models.doc2vec import Doc2Vec, TaggedDocument
import re
from tqdm import notebook
from tqdm.notebook import tqdm as tq
import csv
 
 
# 記事ファイルをダウンロードしたディレクトリから取得する関数
def corpus_files(dir_path):
filepath = [path.join(dir_path, x) for x in listdir(dir_path)]
dirs = [x for x in filepath if path.isdir(x) == True]
docs_path = [path.join(x, y)
for x in dirs for y in listdir(x) if not x.startswith('LICENSE')]
return docs_path
 
# 記事コンテンツをパスから取得する関数
def read_document(file_path):
with open(file_path, 'r', encoding='utf-8') as f:
return f.read()
 
# 取得した記事コンテンツの前処理
def edit_docment(document):
docs =
for x in document:
doc =
# 行ごとに分割
for text in x.split('\n'):
text = text.replace(' ', '') # 半角スペースを消去
text = re.sub('\w*@\w*', '', text) # @...などのドメイン名を削除
text = re.sub('#\w*', '', text) # ハッシュタグを削除
doc.append(text)
del doc[:2] #1,2行目に書いたあるURLと時間は関係ないので取り除きます。
doc = [s for s in doc if s != ''] #\n\nなどの場合、空文字リストが出現するのを防ぐ
docs.append(doc)
return docs
 
# JUMAN++を使って記事を単語リストに変換する関数
def split_jumanpp(doc):
words =
for sentence in tq(doc):
result = Jumanpp().analysis(sentence)
words += [mrph.midasi for mrph in result.mrph_list()]
return words
 
# 記事コンテンツを単語に分割して、Doc2Vecの入力に使うTaggedDocumentに変換し訓練用データを作る
def doc_to_sentence(doc, name):
words = split_jumanpp(doc)
return TaggedDocument(words=words, tags=[name])
 
 
# 記事のパスリストから、記事コンテンツに変換し、単語分割して、センテンスのジェネレーターを返す関数
def corpus_to_sentences(corpus_path):
document = [read_document(x) for x in corpus_path]
docs = edit_docment(document)
sentences =
for idx, (doc, name) in enumerate(zip(docs, corpus_path)):
print('*前処理中 {}/{}'.format(idx, len(docs)))
sentences.append(doc_to_sentence(doc, name))
return sentences
 
 
*ポイント
・JUMANは\n(改行文字)までしか分かち書きしてくれない
→\nでsplit。一行ごとに入力。
 
・'半角空白'があるとValueError
→replace
 
・@***, #***はError
正規表現を用いて削除
 
・各documentの1・2行目はそれぞれ、URLと日付であり、これら半角文字がJUMANに悪影響を及ぼす可能性があった
→1・2行目は全documentで削除
 
・例えば、\n\nなどでは、splitすると''空文字のみの入力になってしまい、Errorがでた
→最後に、空文字のみのリストは削除
 
 
 
dir_path = './livedoor/text'
corpus_path = corpus_files(dir_path)
 
# 訓練データの作成(分かち書き
sentences = corpus_to_sentences(corpus_path)
 
# 訓練データ(リスト)の保存
with open('livedoor_juman_trainig.pkl', 'wb') as f:
pickle.dump(sentences, f)
→10時間程度かかった
 
livedoor_juman_training.pkl」が完成
 
 
 
 
Doc2Vecパラメータを渡して、学習させる

 
# 訓練データの読み込み
with open('livedoor_juman_trainig.pkl', 'rb') as f:
sentences = pickle.load(f)
 
model = models.Doc2Vec(sentences, dm=0, vector_size=300, window=15, alpha=.025,
min_alpha=.025, min_count=1, sample=1e-6)
 
model.save('livedoor_juman')
model = Doc2Vec.load('livedoor_juman')
学習は一瞬
 
 
 
Doc2Vec実践

 
# タグの整理
doc =
for words, tags in sentences:
for tag in tags:
doc.append(tag)
 
 
# 文章ベクトルの表示
print(model.docvecs[doc[7375]])
 
 
# 文章の類似度
model.docvecs.similarity(doc[1], doc[2])
 
 
# 任意の文章との類似度を計算
 
text = """バーレーンの首都マナマ(マナーマとも)で現在開催されている
ユネスコ(国際連合教育科学文化機関)の第42回世界遺産委員会は日本の推薦していた
世界遺産に登録することを決定した。文化庁が同日発表した。
日本国内の文化財世界遺産登録は昨年に登録された福岡県の
「『神宿る島』宗像・沖ノ島と関連遺産群」に次いで18件目。
2013年の「富士山-信仰の対象と芸術の源泉」の文化遺産登録から6年連続となった。"""
 
words = []
result = Jumanpp().analysis(text)
words += [mrph.midasi for mrph in result.mrph_list()]
 
docs_vec = [model.infer_vector(words)]
 
model.docvecs.most_similar(docs_vec)
 
 
# 類似する単語を表示
model.wv.most_similar('東京', topn=10)

NLPを用いたタスク

 
 
NLPを用いたタスク

・文書分類
・予測変換
・文書要約
・質疑応答
・対話
・スパムフィルタ
・音声アシスタント
・小説の執筆
 
 
 
 
 

 
・文節係り受け解析:文を構成する文節間の修飾・被修飾の関係を解析する工程
→・顧客の声分析で良い/悪いなどの評価の対象を特定するために利用されている
 
 
 
・単語依存構造解析:形態素に相当するトークンを単位として前後両方向への依存関係を扱い、依存関係にラベルを付与することで、主語や目的語といった文法的関係を出力する
 

 
 
 
 

NLPの流れ

 
 
 
単語分割

・Ngram
 
 
前処理

・正規化:同じ意味の単語が別々に集計されないようにする
 
・HTMLタグ
ストップワード:頻出キーワード、①やⅰ、です、私など
・数字
・顔文字
 
・化学式:C6H5OHなど
・数学や物理の公式
・URL
・商品コードや型番
 
 
 
単語のベクトル表現

 
・one-hot ベクトル
・Word Embeddings:Word2Vec, fastText, GloVe
 
 
 
 
文書のベクトル表現

 
<文書のベクトル化>
・Doc2Vec
 
 
<トピック分析>
形態素解析済みの文書を自動的に分類し、指定したトピック数に分割する
 
・LDA(Latent Dirichlet Allocation)
→・文書群を与えると、指定したトピック群に話題を分割してくれる
 ・いくつに分割したらいいかがわかりにくい
 
DTM(Dynamic Topic Model)
→・LDAを拡張し,SNS上の一定期間の話題を解析する場合のように,新しいニュースが飛び込んできて話題が遷移する時に使うモデル
 
・HDP(Hierarchical Dirichlet Process)
→・LDAを拡張し,文書をいくつのトピックに分割すればいいか
 
 
 
 
 
 
 
 
 
 
 
 
 
 

NLP

 
 
NL:Natural Language

:日本語や英語のような 自然発生的に生まれた言語
 
プログラミング言語のような人工言語(Artificial Language)とは対比の存在
 
 
 
 
NLP:Natural Language Processing

:人間が日常的に使っている 自然言語をコンピュータに処理させる技術
 
 
トーク自然言語を解析する際、文章の最小単位して扱われる文字や文字列のこと。
タイプ:単語の種類を表す用語。
文章:まとまった内容を表す文のこと。自然言語処理では一文を指すことが多い。
文書:複数の文章から成るデータ一件分を指すことが多い。
コーパス:文書または音声データにある種の情報を与えたデータ。
シソーラス:単語の上位/下位関係、部分/全体関係、同義関係、類義関係などによって単語を分類し、体系づけた類語辞典・辞書。
形態素:意味を持つ最小の単位。「食べた」という単語は、2つの形態素「食べ」と「た」に分解できる。
単語:単一または複数の形態素から構成される小さな単位。
表層:原文の記述のこと。
原形:活用する前の記述のこと。
特徴:文章や文書から抽出された情報のこと。
辞書自然言語処理では、単語のリストを指す。