大阪市の犯罪発生情報でグラフを描く

http://www.city.osaka.lg.jp/shimin/page/0000298810.html からCSVのURLリストを生成

事前に

  1. python3 crawl_osaka_hanzai.py でURLリストを生成
  2. wget -i urllist.csv -w1 でダウンロード
  3. nkf -u --overwrite *.csv で文字コードを変換

でデータを生成しておく

In [1]:
import os
import re
import datetime as dt
import matplotlib
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

pd.options.display.mpl_style = 'default'
font = {'family':'TakaoGothic'}
matplotlib.rc('font', **font)

今回は 2013年と2014年 のひったくり情報を使う

まずCSVファイルからひったくりデータの読み込み

In [2]:
df_list = []
dir_path = './csvdata/'
for path in os.listdir(dir_path):
    if not re.match('^00[6].+shinai.csv', path):
        continue
    df_temp = pd.read_csv(dir_path + path)
    df_list.append(df_temp)

df = pd.concat(df_list)

concated = df.loc[:, '年'] + df.loc[:, '月'] + df.loc[:, '日'] + df.loc[:, '時間']
df.loc[:, 'datetime'] = concated.map(lambda x: dt.datetime.strptime(x, '%Y年%m月%d日%H時頃'))

df.head()
Out[2]:
市区町村 町名 丁番 罪名 既遂未遂別 手口 ひったくり区分 時間 被害者の性別 被害者の年齢 datetime
0 大阪市北区 曾根崎 2丁目付近 窃盗 既遂 ひったくり 自動二輪 2013年 2月 24日 2時頃 女性 30代 2013-02-24 02:00:00
1 大阪市北区 中崎 3丁目付近 窃盗 既遂 ひったくり 自動二輪 2013年 3月 6日 1時頃 女性 30代 2013-03-06 01:00:00
2 大阪市北区 中崎 2丁目付近 窃盗 既遂 ひったくり 自動二輪 2013年 4月 19日 20時頃 女性 30代 2013-04-19 20:00:00
3 大阪市北区 堂山町 付近 窃盗 既遂 ひったくり 徒歩 2013年 4月 5日 10時頃 女性 70代 2013-04-05 10:00:00
4 大阪市北区 曾根崎 1丁目付近 窃盗 既遂 ひったくり 自動二輪 2013年 4月 22日 15時頃 女性 20代 2013-04-22 15:00:00

月ごとの発生件数の棒グラフ

In [3]:
ts = df.datetime
ts = pd.Series(1, index=ts)
ts.resample('M', how='sum').plot(kind='bar')
Out[3]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f29d1aba8d0>

ひったくりに関する情報を見てみる

ひったくり被害にあわないために :警視庁 (以下,「警視庁の資料」と呼ぶことにする)と比較しながら色々プロットしたりしてみる

まず,被害者の性別を見てみる.

In [4]:
df.loc[:, '被害者の性別'].value_counts()
Out[4]:
女性    1386
dtype: int64

被害者は全員女性だった.

曜日によってひったくり発生件数に違いがあるか見てみる

In [5]:
num2wd = dict(zip(range(7), tuple('月火水木金土日')))
ts = df.datetime.map(lambda x: x.weekday()).map(lambda x: num2wd[x])
vcount = ts.value_counts()
vcount.loc[list('月火水木金土日')].plot(kind='bar')
Out[5]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f29daed5e10>

グラフを描いてみると,大阪市の場合は火曜日の発生件数が多め,日曜日が少なめに見える.

ところで警視庁の資料にも同様の図がある.

次に「ひったくり区分」,つまりひったくり犯の移動手段について見てみる.

In [6]:
df.loc[:, 'ひったくり区分'].value_counts()
Out[6]:
自動二輪    839
自転車     375
徒歩       93
自動車      79
dtype: int64

自動二輪が圧倒的に多いということがわかる.

自動車によるひったくりもそれなりに発生していることをはじめて知った.

次に区別の発生件数を見てみる.

In [7]:
df.loc[:, '市区町村'].value_counts()
Out[7]:
大阪市中央区     147
大阪市北区      120
大阪市淀川区     102
大阪市住吉区      90
大阪市浪速区      79
大阪市都島区      74
大阪市西成区      73
大阪市東淀川区     73
大阪市生野区      72
大阪市東住吉区     68
大阪市平野区      67
大阪市城東区      58
大阪市阿倍野区     56
大阪市西区       49
大阪市天王寺区     48
大阪市東成区      39
大阪市住之江区     38
大阪市福島区      34
大阪市西淀川区     31
大阪市旭区       22
大阪市鶴見区      14
大阪市港区       14
大阪市此花区      10
大阪市大正区       8
dtype: int64

よくわからなかった

次に時刻別の発生件数を調べてみる.

In [8]:
vcount = df.loc[:, '時間'].value_counts()
vcount.sort_index()
vcount_time = vcount[[str(n)+'時頃' for n in range(24)]]
vcount_time.plot(kind='bar', title='')
Out[8]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f29dbd34ef0>

夜に発生件数が増加するのはいいとして,17時頃だけ不自然に多いのが気になった.

中高生が帰宅する時間帯?を狙っての犯行か,あるいは報告する際に何らかのバイアスがかかったか

ちなみに警視庁の資料中に同様のグラフがあるので比較してみる.

時間帯によって,ひったくりに合うの被害者の年齢は変化しそうである.(例えば夕方は10代の被害者が多そう)

これを見るためにひったくりの発生時間帯の棒グラフを年代別積み上げ棒グラフに変更してみる

In [9]:
df.loc[:, 'one'] = 1
df2 = df.pivot_table(values='one', aggfunc=np.sum, index='時間', columns='被害者の年齢')
df2 = df2.loc[[str(n)+'時頃' for n in range(23)], :]  # indexで並び替え
df2 = df2.fillna(0)
df2.plot(kind='bar', stacked=True)
plt.legend(loc='center left', bbox_to_anchor=(1, 0.5))
Out[9]:
<matplotlib.legend.Legend at 0x7f29d139d240>

月別発生件数を見てみる

In [10]:
vcount = df.loc[:, '月'].value_counts()
vcount.sort_index()
vcount_time = vcount[[str(n)+'月' for n in range(1,13)]]
vcount_time.plot(kind='bar', title='')
Out[10]:
<matplotlib.axes._subplots.AxesSubplot at 0x7f29d127c908>

4月から8月の期間に発生件数が少し多い気がする.

11月だけ発生件数が極端に少ないように見えるが,理由が全く予想できない.

実行環境

In [11]:
%load_ext version_information
%version_information pandas,matplotlib
Out[11]:
SoftwareVersion
Python3.4.2 64bit [GCC 4.8.2]
IPython2.4.1
OSLinux 3.13.0 55 generic x86_64 with debian jessie sid
pandas0.15.2
matplotlib1.4.3
Sat Jun 27 14:58:47 2015 JST

参考文献