
Advent Calendar 2013 - 24
今回は、実際のデータを探ってみたい。ここまでのデータ操作を使って、簡単にできるところまで。
一応、これが Advent Calendar 2013 の最後。技術系の Advent Calendar では 25 までやるのが慣例のようだが、 Wikipedia で調べたら、 24 までと書いてあったからね!
1. 実データの取得
実データの取得がなかなか難しい…。ブログのネタ用に、データを探してみたのだが、なかなか都合のいいのが見つからない。ネタ的に、野球やサッカーなんかがよかったのだが、 PDF だったり、グラフ化された Web の記事だったり…で、 Pandas を試してみるのに、ちょうどいいのがなかなか見つからない。
政府系の Open Data の取り組みも、 Excel にレポート形式でまとめられてて、ちょっと加工してやらないと…といった感じで、軽いブログ記事でサクッと使うには、なかなか難しい。"DATA GO JP" ってのがあるのだが、フォーマットでは PDF が 4891 件でダントツの一位。う〜む、使えん…。CSV も 389 件あるが、放射濃度のデータがたくさんあって、クリスマスイブに取り上げるのもなぁ…。
そんな中でも、レッドリストが使いやすくて、 Pands の練習にはちょうどいい感じ。クリスマスイブなのに…とは思うが、探しまわるのに疲れたので、これで行くことにする。
import pandas as pd
df = pd.read_csv('http://www.sizenken.biodic.go.jp/va2007/va_2007.csv', encoding='Shift-JIS')
こんな感じで、 URL から直接 DataFrame が作れるのが便利。これで、クリスマスイブっぽいのが、見つかれば良かったのだが…。
2. 概要の把握
まずは、全体像を。
df
<class 'pandas.core.frame.DataFrame'>
Int64Index: 13498 entries, 0 to 13497
Data columns (total 11 columns):
種コード 13498 non-null values
科名 13498 non-null values
和名 13498 non-null values
学名 13498 non-null values
都道府県コード 13498 non-null values
都道府県 13498 non-null values
平成12年レッドデータブック刊行時のランク 13498 non-null values
平成19年レッドリスト選定時のランク 13498 non-null values
2万5千地形図名 13315 non-null values
メッシュコード 13498 non-null values
生育状況 13498 non-null values
dtypes: float64(1), int64(2), object(8)
11 項目あって、13,497 件のレコードがあることが分かる。ほとんどの項目に値が入っているが、"2万5千地形図名" には欠損があるようだ。"2万5千地形図名" を詳しくは知らないが、市町村名ぐらいで位置情報を特定できるものだと思われる。
軽く各項目の値も見ておく。
df.head()
種コード 科名 和名 \
0 9240 ヒノキ リシリビャクシン
1 60990 ヒルムシロ リュウノヒゲモ
2 9240 ヒノキ リシリビャクシン
3 9240 ヒノキ リシリビャクシン
4 9240 ヒノキ リシリビャクシン
学名 都道府県コード \
0 Juniperus communis var. montana 1
1 Potamogeton pectinatus 1
2 Juniperus communis var. montana 1
3 Juniperus communis var. montana 1
4 Juniperus communis var. montana 1
都道府県 平成12年レッドデータブック刊行時のランク 平成19年レッドリスト選定時のランク \
0 北海道 EN VU
1 北海道 VU NT
2 北海道 EN VU
3 北海道 EN VU
4 北海道 EN VU
2万5千地形図名 メッシュコード 生育状況
0 鷹泊貯水池 654270 現存(生育)
1 鵡川 634167 現存(生育)
2 布部岳 644272 現存(生育)
3 胆振福山 644222 現存(生育)
4 神居古潭 654241 現存(生育)
11 項目もあるので、横には並べられなくて、分割して表示されている。横に並べて綺麗に見るには、 Excel とか…を使う方がいいだろう。
3. 欠損データの傾向調査
試しに、"2万5千地形図名" が入っていない都道府県を調べてみる。
df[pd.isnull(df[u"2万5千地形図名"])][u'都道府県'].value_counts()
トップ 5 はこうなった。
鹿児島県 58
東京都 19
静岡県 18
熊本県 13
大分県 8
きっと、生息地域の偏りと同じに違いない…と思って、全体の都道府県を調べてみる。
df[u'都道府県'].value_counts()
北海道 798
岡山県 674
大分県 596
愛知県 537
山形県 533
宮城県 527
千葉県 519
長野県 453
三重県 437
鹿児島県 380
こっちはトップ 10 まで掲載してみたが、関連があるようには見えない。 念のため、統計的に調べてみる。
s1 = df[u'都道府県'].value_counts()
s2 = df[pd.isnull(df[u"2万5千地形図名"])][u'都道府県'].value_counts()
df1 = pd.DataFrame({u'都道府県1': s1})
df2 = pd.DataFrame({u'都道府県2': s2})
tmp = df1.join(df2)
tmp[u'都道府県2'] = tmp[u'都道府県2'].fillna(0) # 欠損データがなかったところに 0 を補完する。
tmp.corr() # 相関係数
都道府県1 都道府県2
都道府県1 1.000000 0.163086
都道府県2 0.163086 1.000000
相関係数 0.16 ってことで、生息地域の偏りとはなんら関係なさそうだ。
品種によって生息地が特定しにくい…とかあるのだろうか?
s1 = df[u'科名'].value_counts()
s2 = df[pd.isnull(df[u"2万5千地形図名"])][u'科名'].value_counts()
df1 = pd.DataFrame({u'科名1': s1})
df2 = pd.DataFrame({u'科名2': s2})
tmp = df1.join(df2)
tmp[u'科名2'] = tmp[u'科名2'].fillna(0) # 欠損データがなかったところに 0 を補完する。
tmp.corr() # 相関係数
科名1 科名2
科名1 1.000000 0.778866
科名2 0.778866 1.000000
相関係数 0.78 ってことで、正の相関があるようなのだが、納得するのは、もう一歩…。
df1.head(10)
科名1
キク 1605
カヤツリグサ 909
ゴマノハグサ 850
シソ 838
タヌキモ 801
タデ 628
ガガイモ 582
トチカガミ 533
ヒルムシロ 460
ミクリ 386
df2.head(10)
科名2
カヤツリグサ 23
キク 20
シソ 12
アカネ 10
ゴマノハグサ 9
ガガイモ 8
ヤブコウジ 7
セリ 6
ミクリ 5
メシダ 5
科名の重複状況から考えて、品種によって…というよりも、品種の多いものが "2万5千地形図名" の欠損が多いということなのだろう。まあ、妥当な欠損状況のようだ。
…と、こんな感じで Pandas を活用して、データを調べられる訳だ。
4. 歯切れの悪い終わり方だが…
まだ、調査開始したばかりで、いきなり終わるのも気が引けるが、Advent Calendar の目的が Pandas の機能調査なので、ここまでとしたい。
あわよくば "マクドナルド対コンビニの垣根を越えた戦争が始まっている" みたいなレポートが出せれば良かったのだが、そう簡単には行かない。深堀してゆくには、それなりに時間がかかる (そして、実際のデータマイニングも、こーゆー地道な作業の積み重ねだったりするのだけど) …。
今回はこんなところで。