Skip to content

Instantly share code, notes, and snippets.

@masatoi
Last active March 3, 2019 07:00
Show Gist options
  • Select an option

  • Save masatoi/fdbdb154e0e5a520a3c5fd674d07aebd to your computer and use it in GitHub Desktop.

Select an option

Save masatoi/fdbdb154e0e5a520a3c5fd674d07aebd to your computer and use it in GitHub Desktop.

Webスクレイピングと文書分類

この章でやること、意義

インターネット上を流れるトラフィックは量的な意味では動画データが過半数を占めるようになりつつあるが、依然としてテキストデータの重要性は変わらない。テキストデータは日々ものすごいスピードで増え続けており、一人の人間の目で追い続けるのはもはや不可能である。また、それらのテキストデータは大抵の場合構造化されておらず、そのままでは使えないことが多い。そこでデータ分析が必要になる。テキストデータをデータ分析し、意味ある構造を取り出す行為をテキストマイニングと呼ぶ。

本章では、Common Lispのライブラリを用いて、インターネットをクローリングし、必要な情報を収集した上で構造化するためのいくつかの方法を紹介する。

Webスクレイピング

Webスクレイピングに必要なライブラリ

Webスクレイピングとはウェブサイトから必要な情報を取り出す行為のことである。 Webスクレイピングでは、(1)Webからデータを取得し、(2)これを解析し、(3)そこから必要な情報を探索していくというプロセスを踏む。 Common Lispにはこの各段階について対応したライブラリがあるので、以下ではそのインストール方法と基本的な使用例を解説する。

HTTPクライアント: Dexador

ウェブサイトからデータを取得するためにはHTTPクライアントのDexadorを使用する。Common Lispには古くからDrakmaというHTTPクライアントがあるが、Dexadorの方が(特に同じホストに複数回アクセスする場合において)速く動作する。

インストール

インストールはQuicklispから行なえる。

(ql:quickload :dexador)

使い方

最も基本的かつ重要なのはdex:getで、GETメソッドで指定のURLからデータを取得する関数である。これは(1)本体データの文字列、(2)ステータスコード、(3)レスポンスヘッダーのハッシュテーブル、(4)URI構造体、(5)読み出し元ソケットのストリームの5つを多値で返す。

(dex:get "http://lisp.org/")

"<HTML>
<HEAD>
  <title>John McCarthy, 1927-2011</title>
  <STYLE type=\"text/css\">
    BODY {text-align: center}
  </STYLE>
</HEAD>
<BODY>
<h1>John McCarthy</h1>
<img src=\"jmccolor.jpg\" alt=\"a picture of John McCarthy, from his website\"/>
<h3>1927-2011</h3>
<br><br>
<a href=\"http://www-formal.stanford.edu/jmc/\">John McCarthy's Home Page</a><br>
<a href=\"http://news.stanford.edu/news/2011/october/john-mccarthy-obit-102511.html\">Obituary</a>
</BODY>
</HTML>
"
200
#<HASH-TABLE :TEST EQUAL :COUNT 10 {1003B35F73}>
#<QURI.URI.HTTP:URI-HTTPS https://lisp.org/>
#<CL+SSL::SSL-STREAM for #<FD-STREAM for "socket 192.168.11.253:47632, peer: 144.76.156.38:443" {100361BC23}>>

このうち特に重要なのは最初の2つで、データ本体は次節で扱うHTMLパーサへの入力として用い、ステータスコードはデータの取得に成功したか失敗したか、さらにその理由を調べるのに用いる。

XML/HTMLパーサ: Plump

ここで紹介するPlumpと次節で紹介するCLSSは同じ作者のプロダクトで、セットで使われる。 PlumpはXML/HTMLデータを文字列として受け取り、CLOSオブジェクトのノードから構成されるDOMの木構造を生成し、その木構造のルートノードのオブジェクトを返すパーサである。

例えば以下のようにして、前述のDexadorのgetの結果をパースすると、ルートノードのオブジェクトが返る。

(plump:parse (dex:get "http://lisp.org/"))

;; => #<PLUMP-DOM:ROOT {1008638843}>

各ノードの子ノードのベクタはplump:childrenで、親ノードはplump:parentでそれぞれ得られる。

(defparameter root (plump:parse (dex:get "http://lisp.org/")))
(plump:children root)
;; => #(#<PLUMP-DOM:ELEMENT HTML {1008AE94D3}> #<PLUMP-DOM:TEXT-NODE {1008AF2EF3}>)

(plump:parent (aref (plump:children root) 0))
;; => #<PLUMP-DOM:ROOT {1008AE8F93}>

DOMの木構造を走査し、各ノードに対して関数を適用する高階関数plump:traverseが用意されている。 例えば、テキストノードから文字列を取り出して連結して返す関数は以下のようになる。

(defun concat-node-text (node)
  (let ((text-list nil))
    (plump:traverse node
                    (lambda (node) (push (plump:text node) text-list))
                    :test #'plump:text-node-p)
    (apply #'concatenate 'string (nreverse text-list))))

(concat-node-text root)

"

  John McCarthy, 1927-2011
  
    BODY {text-align: center}
  


John McCarthy

1927-2011

John McCarthy's Home Page
Obituary


"

同様にして、DOM木構造に対して変更を加えることもできる。例えばテキストノードの文字列を全て大文字に変更するには、

(plump:traverse root
                (lambda (node)
                  (setf (plump:text node)
                        (string-upcase (plump:text node))))
                :test #'plump:text-node-p)

(concat-node-text root)

"

  JOHN MCCARTHY, 1927-2011
  
    BODY {TEXT-ALIGN: CENTER}
  


JOHN MCCARTHY

1927-2011

JOHN MCCARTHY'S HOME PAGE
OBITUARY


"

このように、DOM木構造から情報を取り出したり変更を加えることができる。

CSSセレクタ: CLSS

(clss:select “img” (plump:parse “<div><p>A beautiful image: <img src=”//example.com/image.png” alt=”image” /></p></div>”))

スクレイピングの実際

ログインを必要とするサイト

サイトを取得する

HTMLをパースする

必要な情報を見つける

番外編: Twitterのクローリング

文書分類/文書クラスタリング

文書分類に必要なライブラリ

形態素解析 mecab

教師あり学習、線形分類器: cl-online-learning

教師なし学習、NMF、テンソル分解: clml

データセットの作成

TF-IDF

word2vec

スパースなデータの取り扱い

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment