12
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Python 自然言語処理の前処理

Last updated at Posted at 2017-12-01

概要

自然言語処理の前処理を行う例。形態素解析と簡単なデータのクレンジングを行うもの。新聞記事の文章を前提とし、処理後のデータはWord2Vecに投入することを想定しています。

前段のデータ収集はこちらの記事参照。
Python Webスクレイピング実装例

環境

  • Python3
  • MeCab
  • NEologd

実装

1
import sqlite3
import MeCab
import unicodedata

tagger = MeCab.Tagger(' -d /usr/lib/mecab/dic/mecab-ipadic-neologd/')
tagger.parse("")#バグ回避

MeCabを準備します。neologdのパスは環境に合わせてください。
最初に空文字をパースするのはおまじないです。

2
dbtext = sqlite3.connect("file:text.db", uri=True)
dbtext.row_factory = sqlite3.Row
dbword = sqlite3.connect("file:words.db", uri=True)
dbword.row_factory = sqlite3.Row

dbtextには元文章が入っている状態とします。dbwordには形態素解析後のデータを書き込むためのテーブルを事前に定義しておきます。
row_factoryを記載のように設定しておくと、select結果をdictのように参照できて便利です。

3
lasttime = ""
row = dbword.execute("select time from wordstbl order by time desc limit 1").fetchone()
if row is not None:
	lasttime = row["time"]

バッチ処理としてcronでまわすことを想定しているので、処理済レコードを峻別するためのタイムスタンプを取得しておきます。

4
for row in dbtext.execute("select * from rawtext where time > ? order by time", (lasttime,)):
	node = tagger.parseToNode(unicodedata.normalize("NFKC", row["rawtext"]))
	separated_text = ""
	while node:
		features = node.feature.split(",")
		if features[0] in ["名詞"] and features[1] not in ["接尾", "", "接続詞的", "非自立", "代名詞"]:
			separated_text = separated_text + " " + node.surface
		node = node.next
	
	insert = "INSERT INTO wordstbl(id, source, time, words) VALUES(?, ?, ?, ?)"
	args = (row["id"], row["source"], row["time"], separated_text)

	try:
		dbword.execute(insert, args)
	except sqlite3.Error as e:
		print ('sqlite3:', e.args[0])

dbword.commit()
dbword.close()
dbtext.close()

生文章を取り出し、まずnormalizeで表記揺れを取り除きます。
形態素解析後、品詞でフィルタします。今回は名詞以外は除外し、かつ名詞の中でも接尾や非自立といった意味の薄いものは除外します。

SQLiteの全文検索

sql1
CREATE VIRTUAL TABLE wordstbl USING fts3(
  id VARCHAR(36) NOT NULL PRIMARY KEY,
  source VARCHAR(20),
  time VARCHAR(20),
  words VARCHAR(1024));

参考に書き込み先のテーブル定義です。
fts3により分かち書きされたテキストに対して効率的な全文検索が可能になります。
なお、ftsを使用する場合、全ての列が文字列型扱いになります。

sql2
SELECT * FROM wordstbl WHERE words MATCH 'hoge'

所見

生文章・分かち書き文章・単語ベクトルそれぞれ使いどころがあるので、中間データも利用しやすい形で保管しておくと後で後悔しません。再度集めるのも大変です。

12
15
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
12
15

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?