【Python3 系対応】 PDFMiner3k で PDF ファイルからデータ抽出して分析しよう!(前編) | SiTest (サイテスト) ブログ

メニューボタン閉じるボタン

【Python3 系対応】 PDFMiner3k で PDF ファイルからデータ抽出して分析しよう!(前編)

現在、国際的にオープンデータと呼ばれる取り組みがあり、日本では総務省指導の元各省庁や、地方自治体などが様々なデータの公開を行っています。

オープンデータとは

リンク先で総務省による、オープンデータの説明を見ることができます。

http://www.soumu.go.jp/menu_seisaku/ictseisaku/ictriyou/opendata/index.html
http://www.soumu.go.jp/menu_seisaku/ictseisaku/ictriyou/opendata/opendata01.html

オープンデータとは「組織や業界内等でのみ利用されているデータを社会で効果的に利用できる環境(オープンデータ流通環境)」の整備のため、「機械判読に適した」「二次利用が可能な利用ルールで公開された」データです。

しかし、公開されたオープンデータには PDF 形式のものが多く存在します。これは、それを利用した第三者によるデータ分析という観点から考えると非常に扱いづらいもので、とても「機械判読に適したデータ形式」とはいえません。

ですが、実際に公開されているデータの多くが PDF 形式である事実は変わりません。Python を使って、PDFで作られたデータを何とかして「機械判読に適したデータ形式」に変換してみます。
(以下の記事は Python の3系、OS は MacOS 、もしくは他 UNIX 系OSを前提としております)

今回は pdfminer(python2系 対応)の3系対応版、pdfminer3k というツールを使ってテキスト抽出を行います。

pdfminer3k のインストールと使い方

以前は Github からソースコードを取得する必要や、日本語を扱うためのモジュールをインストールする必要があったのですが、現在は pip を使って簡単にインストールできます。

$ pip install pdfminer3k

ドキュメントを見ればわかるように、pdfminer には様々な機能があります。ひとまず、PDF からテキストを抽出するコマンドラインツールである pdf2txt.py を使ってみます。

例えば、変換対象の PDF ファイルが data.pdf の場合、以下のようにファイルパスを引数に渡すだけで、PDF の内容をテキストへと変換できます。

$ pdf2txt.py  data.pdf

pdf2txt.py の出力先は標準出力なので以下のようにすると、ファイルに書き込みできます

$ pdf2txt.py  data.pdf > converted_data.txt

PDF データをテキストファイルに変換する

さて、試しに弊社、グラッドキューブの所在地である、大阪市のオープンデータから

『年次別に見た人口動態総覧(出生)実数・率(数値表+グラフ)』
https://data.city.osaka.lg.jp/data/dataset/data-0000277916-00004/resource/c54677b2-7181-4d24-8d55-b30310956959

http://www.city.osaka.lg.jp/kenko/cmsfiles/contents/0000277/277916/H27-02-01nenjitoukei_jinkou_02_syussei01.pdf

を見てみましょう。1960年から2015年までの毎年の出生数、及び出生率を、大阪市、大阪府、全国と並べて表示されたものです。他のデータとの相関関係を調べたいのですが、 PDF 形式なのでこのままだと、手でコピペなどしないと、分析できません。できれば利用を避けたいのですが、見る限り、残念ながら PDF 以外の形式は見当たらないようなので頑張ってこれを分析してみましょう。

ダウンロードを行い、先ほど紹介したコマンドを実行してみます。
出来上がったファイルは以下のようになります

年次別に見た人口動態総覧(出生)実数・率 (出生数÷人口×1,000)


(西暦)

大阪市

出生
大阪府

年間 単位:人

全国

実数

率(人口千対)

実数

率(人口千対)

実数

率(人口千対)

1960 昭和35年
1961
36年
1962
37年
1963
38年
1964
39年
1965
40年
1966
41年
1967
42年
1968
43年
1969
44年
1970
45年
1971
46年
1972
47年
1973
48年
1974
49年
1975
50年
1976
51年
1977
52年
1978
53年
1979
54年
1980
55年
1981
56年
1982
57年
1983
58年
1984
59年
1985
60年
1986
61年
1987
62年
1988
63年
1989 平成元年
1990 平成2年
1991
3年
1992
4年
1993
5年
1994
6年
1995
7年
1996
8年
1997
9年
1998
10年
1999
11年
2000
12年
2001
13年
2002
14年
2003
15年
2004
16年
2005
17年
2006
18年
2007
19年
2008
20年
2009
21年
2010
22年
2011
23年
2012
24年
2013
25年
2014
26年
2015
27年

51,632
53,351
57,682
58,000
59,035
62,003
44,869
59,298
56,758
54,525
53,165
52,003
50,068
47,647
43,839
39,197
35,951
33,946
31,775
30,192
28,919
28,415
28,406
28,564
28,607
28,369
28,125
27,600
27,446
26,077
25,065
25,297
24,810
24,008
24,124
24,467
24,862
24,994
24,898
24,203
24,136
24,132
23,635
23,228
22,794
21,913
22,949
22,892
23,290
22,738
23,061
22,992
22,763
22,626
21,940
22,351

資料…厚生労働省「人口動態統計」

17.1
17.3
18.3
18.1
18.4
19.6
14.3
19.6
19.1
18.5
17.8
17.7
17.3
16.8
15.6
14.1
13.1
12.5
11.8
11.3
11.0
10.8
10.8
10.9
10.9
10.7
10.6
10.4
10.4
9.9
9.6
9.7
9.5
9.3
9.8
9.8
9.6
10.1
9.6
9.3
9.6
9.2
9.0
8.8
8.7
8.3
8.7
8.7
8.8
8.5
8.7
8.6
8.5
8.4
8.2
8.6

95,012
101,318
114,469
121,396
131,994
147,249
111,099
158,482
159,740
163,995
169,880
175,049
176,094
174,330
165,560
150,653
140,032
132,172
124,711
115,990
111,956
106,456
106,098
105,432
103,595
100,328
97,693
94,828
93,315
88,468
86,840
86,795
86,658
84,151
88,419
86,076
89,291
89,043
90,324
88,385
88,163
86,000
83,883
81,001
79,719
76,111
77,641
76,914
77,400
75,248
75,080
73,919
73,012
72,054
69,968
70,596

17.3
17.7
19.2
19.6
20.6
22.1
16.3
23.2
22.7
22.7
22.8
23.0
22.6
22.1
20.7
18.6
17.1
16.1
15.1
13.9
13.5
12.8
12.7
12.5
12.2
11.8
11.4
11.1
10.9
10.3
10.1
10.1
10.1
9.8
10.4
10.0
10.3
10.3
10.5
10.2
10.2
9.9
9.7
9.4
9.2
8.8
9.0
8.9
9.0
8.7
8.6
8.5
8.4
8.3
8.1
8.1

1,606,041
1,589,372
1,618,616
1,659,521
1,716,761
1,823,697
1,360,974
1,935,647
1,871,839
1,889,815
1,934,239
2,000,973
2,038,682
2,091,983
2,029,989
1,901,440
1,832,617
1,755,100
1,708,643
1,642,580
1,576,889
1,529,455
1,515,392
1,508,687
1,489,780
1,431,577
1,382,946
1,346,658
1,314,006
1,246,802
1,221,585
1,223,245
1,208,989
1,188,282
1,238,328
1,187,064
1,206,555
1,191,665
1,203,147
1,177,669
1,190,547
1,170,662
1,153,855
1,123,610
1,110,721
1,062,530
1,092,674
1,089,818
1,091,156
1,070,035
1,071,304
1,050,806
1,037,231
1,029,816
1,003,539
1,005,677

17.2
16.9
17.0
17.3
17.7
18.6
13.7
19.4
18.6
18.5
18.8
19.2
19.3
19.4
18.6
17.1
16.3
15.5
14.9
14.2
13.6
13.0
12.8
12.7
12.5
11.9
11.4
11.1
10.8
10.2
10.0
9.9
9.8
9.6
10.0
9.6
9.7
9.5
9.6
9.4
9.5
9.3
9.2
8.9
8.8
8.4
8.7
8.6
8.7
8.5
8.5
8.3
8.2
8.2
8.0
8.0

出生率(人口千対)の年次推移<大阪市・大阪府・全国>

25.0

20.0

15.0

10.0

5.0




(人



大阪市

大阪府

全国

0.0
昭和35年 38年

41年

44年

47年

50年

53年

56年

59年

62年 平成2年 5年

8年

11年

14年

17年

20年

23年

26年

さて、出来上がったテキストはなかなかどうして、悲惨な感じです。 PDF ファイルのデータには表組みなどの構造を指定する部分が存在しないので、全てが直列化されて出力されてしまいます。

しかも、 PDF の元となった Excel ファイルの時点で、「セルの結合」をしているため、ヘッダー周りが特にグチャグチャですね(これなら Excel ファイルのまま出してくれた方が助かるのですが…)。

さらに、ファイルの後半部分では、表のおまけとして付いていたグラフのテキスト部分だけのゴミも混じってしまっています。これをどうにかして、分析できる形に変換していきます。このときも Python を使っていきます。

その方法については、後編(8/15配信)にて解説していきます。
それでは。