LoginSignup

This article is a Private article. Only a writer and users who know the URL can access it.
Please change open range to public in publish setting if you want to share this article with other users.

More than 5 years have passed since last update.

【読書会】入門自然言語処理_3章

Last updated at Posted at 2016-11-30

入門自然言語処理_3章

生テキストの処理

コーパスの様な既存のテキスト集合はあるが、そうではないテキスト資源を解析したい場合には、そういった生テキストの処理方法を知る必要がある。

本章の目的

  1. テキスト資源を得るためにローカルファイルやweb上のテキストへアクセスする方法
  2. 分析を行うために、ドキュメントのここの単語と句読点に分割するにはどうすればよいか
  3. 処理結果を整形し、それをファイルへ保存するようなプログラムはどのように書けばよいか

これらができるようになる

この章で扱う自然言語処理の一連の流れはこんな感じですよ(図3_1)

1. テキスト資源を得るためにローカルファイルやweb上のテキストへアクセスする方法

■webページのテキストにアクセスする

#最初にインポートしておく
from __future__ import division
import nltk, re, pprint

#webページのhtmlを取得する
from urllib.request import urlopen
url = 'http://news.bbc.co.uk/2/hi/health/2284783.stm'
html = urlopen(url).read()

#これでそのHTMLコンテンツ全てを出力することができる
#次にHTMLからテキストだけを取り出す。

#htmlを取得してトークン化する
from bs4 import BeautifulSoup
nltk.download('punkt')
raw = BeautifulSoup(html, "lxml").get_text()
tokens = nltk.word_tokenize(raw)
tokens

>>> ['BBC',
 'NEWS',
 '|',
 'Health',
 '|',
 'Blondes',
 "'to",
 'die',
 'out',
 'in',
 '200',
 "years'",
 'NEWS', …

■ローカルファイルにアクセスする


f = open('document.txt')#開く
raw = f.read()#読み込む

■pdfやMSwordなどから読み込む

サードパーティ製のライブラリを使う事で実現可能
・pypdf
・pywin32

※でも結構大変な事が多いので少ない数の文章であれば
メモ帳とかにコピペして保存するのがはやい

2. 分析を行うために、ドキュメントを単語と句読点に分割する

■テキストのトークン化のための正規表現

トークン化:文字列を分割し、トークンと呼ばれる言語データの一部を構成する識別可能な単位に変換する事
正規表現:いくつかの文字列を一つの形式で表現するための表現方法「パターンマッチ」

今回は「不思議の国のアリス」のテキストについて考えてみる。

#不思議の国のアリスのテキスト
raw = """'When I'M a Duchess,' she said to herself, (not in a very hopeful tone
... though), 'I won't have any pepper in my kitchen AT ALL. Soup does very
... well without--Maybe it's always pepper that makes people hot-tempered,'..."""

この文章を単語と文章に変換する

まず空白文字で分割してみる

#空白文字で分割
re.split(r' ', raw) 

これだと改行文字「\n」が含まれたりしている
そこで連続した空白文字、タブ、改行に対応させる

#空白文字、タブ、改行に対応させる
#正規表現<<[ \t\n]+>>は一つ以上の空白文字、タブ、改行にマッチする
re.split(r'[ \t\n]+', raw)

「(not」や「herself,」などを解決するため、\wという文字クラスを利用する

#\wという文字クラスを利用する
#これは<<[a-zA-Z0-9_]>>と投下である
re.split(r'\W+', raw)

\Wを用いる事で、簡単に単語文字以外の全ての文字で入力を分割できる

正規表現がより多くの状況に対応できるよう拡張してみる

正規表現<<\w+|\S\w*>>は
まず一続きの単語文字のマッチを試みる
もしマッチするものが無ければ非空白文字に続いて単語文字が続くもののマッチを試みている

#拡張したもの
re.findall(r'\w+|\S\w*', raw)

単語内部にハイフンとアポストロフィがあっても一つのトークンとして認識されるように<<\w+>>を<<\w+(?:[-']\w+)|'|[-.(]+|\S\w>>tと拡張してみる
こうすると「hot-tempered」「it's」にもマッチするようになる
さらに引用符文字にもマッチするようなパターンを加えることで、それらもテキストから切り離されるようになる

re.findall(r"\w+(?:[-']\w+)*|'|[-.(]+|\S\w*", raw)

3. 処理結果を整形し、それをファイルへ保存する

■データを整形する:リストから文字列への変換

テキスト処理に用いるもっともシンプルな構造化されたオブジェクトは、単語のリストである
よってリストを文字列に変換する必要がある

#変換するリスト
silly = ['We', 'called', 'him', 'Tortoise', 'because', 'he', 'taught', 'us', '.']

join()メソッドを用いて変換する

' '.join(silly)
>>'We called him Tortoise because he taught us .'

';'.join(silly)
>>'We;called;him;Tortoise;because;he;taught;us;.'

''.join(silly)
>>'WecalledhimTortoisebecausehetaughtus.'

■結果ファイルへ出力する

webやファイルからテキストを抜き出したが、最後にファイルに書き出す処理も行う

#output.txtというファイルを書き込み用に開き、プログラムの出力をそのファイルへ保存する
>>> output_file = open('output.txt', 'w')
>>> words = set(nltk.corpus.genesis.words('english-kjv.txt'))
>>> for word in sorted(words):
...     print(word, file=output_file)
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