作者の分類をするプログラム。
前提として事前に青空文庫から取得した文書データを使用してDoc2Vecでモデルの作成を行っている。そのモデルを使用して作者の分類を行っていく。
import urllib.request as req
import zipfile
import os.path
from gensim import models
#保存したDoc2Vec学習モデルを読み込み --- (*7)
model = models.Doc2Vec.load('aozora.model')
#分類用のZipファイルを開き、中の文書を取得する --- (*8)
def read_book(url, zipname):
if not os.path.exists(zipname):
req.urlretrieve(url, zipname)
with zipfile.ZipFile(zipname,"r") as zf:
for filename in zf.namelist():
with zf.open(filename,"r") as f:
return f.read().decode("shift-jis")
def split_words(text):
node = mecab.parseToNode(text)
wakati_words =
while node is not None:
hinshi = node.feature.split(",")[0]
if hinshi in ["名詞"]:
elif hinshi in ["動詞", "形容詞"]:
wakati_words.append(node.feature.split(",")[6])
node = node.next
return wakati_words
#引数のタイトル、URLの作品を分類する --- (*9)
def similar(title, url):
zipname = url.split("/")[-1]
words = read_book(url, zipname)
wakati_words = split_words(words)
print("--- 「" + title + '」 と似た作品は? ---')
print(model.docvecs.most_similar([vector],topn=3))
print("")
#各作家の作品を1つずつ分類 --- (*10)
similar("芥川 龍之介:犬と笛",
similar("ポー エドガー・アラン:マリー・ロジェエの怪事件",
実行結果
結果としてモデルに学習させたものと類似度の高いものを出力している。
モデルの読み込み
model = models.Doc2Vec.load('aozora.model')
関数呼び出し、各作家の作品を一つずつ分類
similar("芥川 龍之介:犬と笛",
similar("ポー エドガー・アラン:マリー・ロジェエの怪事件",
引数のタイトル、URLの作品を分類する
def similar(title, url):
zipname = url.split("/")[-1]
words = read_book(url, zipname)
wakati_words = split_words(words)
print("--- 「" + title + '」 と似た作品は? ---')
print(model.docvecs.most_similar([vector],topn=3))
print("")
ここではread_book()関数で中身の文書を取得し、split_words()関数で引数で受け取った文章を分かち書きにして配列にして返している。
model.infer_vector()では分かち書きデータを渡すことでベクトルを作成している。
model.docvecs.most_similar()では引数に渡したデータの類似度の高いものから3作品を出力している。topn=N(トップからN番目までを出力)model.docvecs[文書名]で文書のベクトル。model.docvecs.most_similar(文書名(ベクトルデータ))で文書の類似度を確認できる。
read_bok()関数、zipファイルを開き、中の文書を取得
def read_book(url, zipname):
if not os.path.exists(zipname):
req.urlretrieve(url, zipname)
with zipfile.ZipFile(zipname,"r") as zf:
for filename in zf.namelist():
with zf.open(filename,"r") as f:
return f.read().decode("shift-jis")
if not os.path.exists(zipname):で引数に指定したファイル名が存在しなければ関数の引数で受け取ったurlにアクセスしアクセス先のファイルをダウンロードする処理をしている。
with zipfile.ZipFile()ではzipファイルを解凍しfor文で解凍したzipファイルの中身のファイル名を取得してwith zf.open()でファイルを開きf.read().decode(:shift-jis)でファイルの中身を読み込み、Shift-JISでデコードして文書を呼び出し元に返している。
split_word()関数、分かち書きにして配列にする
def split_words(text):
node = mecab.parseToNode(text)
wakati_words =
while node is not None:
hinshi = node.feature.split(",")[0]
if hinshi in ["名詞"]:
elif hinshi in ["動詞", "形容詞"]:
wakati_words.append(node.feature.split(",")[6])
node = node.next
return wakati_words
mecab.parseToNode()で文章を渡し、単語、品詞情報を持ったオブジェクトを変数に代入。
while文のなかのif文でストップワードの除去を行い、新しい配列に追加していく。
最後に作成した配列を呼び出し元に返している。