検索
連載

ログを分析するには? XMLデータを分析するには? pandasでデータを分析できる状態にするITエンジニアのためのデータサイエンティスト養成講座(4)(3/3 ページ)

データと情報は似て非なるもの。意味のある情報を取り出すために、データを「使える」状態にするには意外と地道な手続きが必要です。手短に実行するために必要なスキルを紹介していきます。

PC用表示 関連情報
Share
Tweet
LINE
Hatena
前のページへ |       

Apacheのログを分析してみる

 ここではWebのアクセスログとしてApacheの標準フォーマットを例にデータを分析できるように構造化していく方法を説明します。

 まずデータの準備ですが、Apacheのオンラインマニュアルの「ログファイル」(リンク)にある「Common Log Format」のサンプルを使いたいと思います。

 同じデータを5行コピー(1行でもよいですが)して、「apache_log.txt」というファイル名で保存しておきます。

127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326
127.0.0.1 - frank [10/Oct/2000:13:55:36 -0700] "GET /apache_pb.gif HTTP/1.0" 200 2326

正規表現モジュール:re

 データの整形やテキストの抽出には正規表現モジュール(re)を用います。Pythonに標準で付属する正規表現モジュールをインポートし(In [1])、ログファイルを読み取りようにオープンします。

 ファイルのデータを1行ずつ読み込んで(In [5])正規表現のsub関数を使ってログを8つのパートに分割し、書き込み用のファイル(In [3])にCSV形式で書き込みます。

In [1]: import re
In [2]: fr = open('apache_log.txt')
In [3]: fw = open('formated.csv', 'w')
In [4]: line = fr.readline()
In [5]: while line:
   ...:         fline = re.sub(r'^(\S+) (\S+) (\S+) \[([^\]]+)\] "([A-Z]+) ([^ "]+)? HTTP/[0-9.]+" ([0-9]{3}) ([0-9]+|-)', r'\1,\2,\3,\4,\5,\6,\7,\8', line)
   ...:         fw.write(fline)
   ...:         line = fr.readline()
   ...:
In [6]: fr.close()
In [7]: fw.close()

 CSV形式のデータができてしまえば、いつものようにread_csv関数でDataFrameに読み込んで処理することが可能になります。ここでは先に8つのパートに分割したデータを表のように項目名を付けて読み込んでいます(In [2])。

項目名 説明
ip サーバへリクエストをしたクライアント(リモートホスト)の IP アドレス
identd クライアントのマシンのidentdにより決まRFC 1413のクライアントの アイデンティティ
user HTTP 認証による、ドキュメントをリクエストした人のユーザーID
datetime サーバがリクエストを受け取った時刻
method クライアントが使ったメソッド
request クライアントから要求されたリソース
status サーバがクライアントに送り返すステータスコード
size クライアントに送信されたオブジェクトの、応答ヘッダを除いたサイズ

 4列目の日付と時刻のデータはタイムゾーン(-07:00)が指定されていて、日本標準時(+09:00)ではないのでタイムゾーンを変換します。(In [3]〜In [5])これで日本標準時に基づいた日付と時刻を持つデータセットが完成です。

In [1]: import pandas as pd
In [2]: df = pd.read_csv('formated.csv', header=None, names=['ip', 'identd', 'user', 'datetime', 'method', 'request', 'status', 'size'])
In [3]: df.index = pd.to_datetime(df['datetime'], format='%d/%b/%Y:%H:%M:%S -0700')
In [4]: df = df.tz_localize('US/Arizona')
In [5]: df = df.tz_convert('Asia/Tokyo')
In [6]: df['ip']
Out[6]:
datetime
2000-10-11 05:55:36+09:00    127.0.0.1
2000-10-11 05:55:36+09:00    127.0.0.1
2000-10-11 05:55:36+09:00    127.0.0.1
2000-10-11 05:55:36+09:00    127.0.0.1
2000-10-11 05:55:36+09:00    127.0.0.1
Name: ip, dtype: object

XML形式のデータを取り込む: xml.etree.ElementTree

 続いて、XML形式のデータをDataFrameに取り込んで分析できる状態にしてみましょう。XMLを取り扱う時には、XMLモジュール(xml)を利用します。サンプルデータとして@ITのRSS(http://rss.rssad.jp/rss/itmatmarkit/rss.xml)データを使用します。

 前回もご紹介したurllib2モジュールを使ってRSSデータを取り込みtreeに格納します。ここではタイトル(title)と公開時刻(pubDate)を取り出して2列のデータセットをもつDataFrameを生成しています。

In [1]: import pandas as pd
In [2]: from xml.etree import ElementTree
In [3]: import urllib2
In [4]: link = 'http://rss.rssad.jp/rss/itmatmarkit/rss.xml'
In [5]: socket = urllib2.urlopen(link)
In [6]: tree = ElementTree.parse(socket)
In [7]: title = tree.findall(".//item/title")
In [8]: titlelist = [i.text for i in title]
In [9]: pubdate = tree.findall(".//item/pubDate")
In [10]: pubdatelist = [i.text for i in pubdate]
In [11]: index = range(len(pubdatelist))
In [12]: df = pd.DataFrame(index=index, columns=('pubdate', 'title'))
In [13]: df['pubdate'] = pd.to_datetime(pubdatelist)
In [14]: df['title'] = titlelist

今回のまとめ

 今回は「データを分析できる状態にする」をテーマに、ビジネスデータの分析で欠かすことのできない時系列データを中心にデータの取り扱いについて紹介しました。また、正規表現を用いてWebなどのログを分析できるフォーマットに成型する方法も紹介しました。

 正規表現は非常にパワフルでこういったデータの整形には必須のツールですが非常の奥が深く難しい面もあるので、これを機に慣れ親しんでください。

 次回は、「データ分析の方法についての検討」というテーマで、データが分析できる状態になったら、次はどのような分析手法を用いるかを検討します。まずはデータを視覚化して全体像や傾向を把握し、目的に応じた分析手法を検討します。

Copyright © ITmedia, Inc. All Rights Reserved.

前のページへ |       
ページトップに戻る