티스토리 뷰

2단원 서울시 범죄 현황 분석 - 복사본 (4)

제 2장 서울시 범죄 현황 분석

구성 및 블로깅 진행과정

2-1 데이터 획득하기
2-2 pandas를 이용하여 데이터 정리하기
2-3 지도 정보를 얻을 수 있는 Google Maps
2-4 Google Maps를 이용해서 주소와 위도, 경도 정보 얻기
-------------------------------------------------------
2-5 pandas의 pivot_table 학습하기
2-6 pivot_table을 이용해서 데이터 정리하기
2-7 데이터 표현을 위해 다듬기
-------------------------------------------------------
2-8 좀 더 편리한 시각화 도구 - Seaborn
2-9 범죄 데이터 시각화하기
-------------------------------------------------------
2-10 지도 시각화 도구 - folium
2-11 서울시 범죄율에 대한 지도 시각화
2-12 서울시 경찰서별 검거율과 구별 범죄 발생율을 동시에 시각화하기

출처: 파이썬으로 데이터 주무르기 by 민형기

2-10 지도 시각화 도구 - folium

In [69]:
# folium import
import folium
import matplotlib.pyplot as plt
In [70]:
#위도와 경도를 보여주면 지도를 그려준다.
map_osm = folium.Map(location=[45.5236, -122.6750])
map_osm
Out[70]:
In [71]:
# zoom_start를 이용하여 확대 비율 조정가능
stamen = folium.Map(location=[45.5236, -122.6750], zoom_start=13)
map_osm
Out[71]:
In [72]:
# 타일 옵션을 사용하여 지도를 만든다.
stamen = folium.Map(location=[45.5236, -122.6750], tiles='Stamen Toner',
                    zoom_start=13)
stamen
Out[72]:
In [73]:
map_1 = folium.Map(location=[45.372, -121.6972], zoom_start=12,
                   tiles='Stamen Terrain')
folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows', 
              icon=folium.Icon(icon='cloud')).add_to(map_1)
folium.Marker([45.3311, -121.7113], popup='Timberline Lodge', 
              icon=folium.Icon(icon='cloud')).add_to(map_1)
map_1
Out[73]:
In [74]:
map_1 = folium.Map(location=[45.372, -121.6972], zoom_start=12, 
                   tiles='Stamen Terrain')
folium.Marker([45.3288, -121.6625], popup='Mt. Hood Meadows', 
              icon=folium.Icon(icon='cloud')).add_to(map_1)
folium.Marker([45.3311, -121.7113], popup='Timberline Lodge', 
              icon=folium.Icon(color='green')).add_to(map_1)
folium.Marker([45.3300, -121.6823], popup='Some Other Location', 
              icon=folium.Icon(color='red',icon='info-sign')).add_to(map_1)
map_1
Out[74]:
In [75]:
# 지도를 그리고 그 상태에서 원하는 좌표에 Marker 명령으로 마크를 찍는다.
# CircleMarker 명령으로 반경과 색상을 지정하여 원을 그린다.
map_2 = folium.Map(location=[45.5236, -122.6750], tiles='Stamen Toner',
                   zoom_start=13)
folium.Marker([45.5244, -122.6699], popup='The Waterfront').add_to(map_2)
folium.CircleMarker([45.5215, -122.6261], radius=50,
                            popup='Laurelhurst park', color='#3186cc',
                            fill_color='#3186cc', ).add_to(map_2)
map_2
Out[75]:
In [76]:
map_3 = folium.Map(location=[45.5236, -122.6750], zoom_start=13)
folium.RegularPolygonMarker([45.5012, -122.6655], 
                            popup='Ross Island Bridge', fill_color='#132b5e', 
                            number_of_sides=3, radius=10).add_to(map_3)
folium.RegularPolygonMarker([45.5132, -122.6708], 
                            popup='Hawthorne Bridge', fill_color='#45647d', 
                            number_of_sides=4, radius=10).add_to(map_3)
folium.RegularPolygonMarker([45.5275, -122.6692], 
                            popup='Steel Bridge', fill_color='#769d96', 
                            number_of_sides=6, radius=10).add_to(map_3)
folium.RegularPolygonMarker([45.5318, -122.6745], 
                            popup='Broadway Bridge', fill_color='#769d96', 
                            number_of_sides=8, radius=10).add_to(map_3)
map_3
Out[76]:
In [77]:
import folium
import pandas as pd

https://github.com/PinkWink/DataScience/tree/master/data
여기서

  1. folium_US_Unemployment_Oct2012.csv
  2. folium_us-states.json
    받을것
In [78]:
state_unemployment = 'pydata/02. folium_US_Unemployment_Oct2012.csv'

state_data = pd.read_csv(state_unemployment)
state_data.head()
Out[78]:
State Unemployment
0 AL 7.1
1 AK 6.8
2 AZ 8.1
3 AR 7.2
4 CA 10.1
In [79]:
# state_geo라는 변수에 json 파일 경로를 담고, 
#folium에서 choropleth 명령으로 json 파일과 지도에 표현하고 싶은 데이터를 입력하고
#key_on 옵션으로 지도의 id를 알려주면 된다.(id 중복되면 안됨)

state_geo = 'pydata/02. folium_us-states.json'

map = folium.Map(location=[40,-98], zoom_start=4)
map.choropleth(geo_data=state_geo, data=state_data,
               columns=['State', 'Unemployment'],
               key_on='feature.id',
               fill_color='YlGn',
               legend_name='Unemployment Rate (%)')
map
C:\Users\whanh\AppData\Local\Continuum\anaconda3\lib\site-packages\folium\folium.py:415: FutureWarning: The choropleth  method has been deprecated. Instead use the new Choropleth class, which has the same arguments. See the example notebook 'GeoJSON_and_choropleth' for how to do this.
  FutureWarning
Out[79]:

실업률을 colormap으로 표현된 결과를 얻을 수 있다.

2-11 서울시 범죄율에 대한 지도 시각화

우리가 열심히 다듬은 자료를 시각화 해보기 위해서는 서울시 '구'별 경계선을 그릴 수 있는 json 파일이 있어야 한다.
https://github.com/southkorea/southkorea-maps
kostat > 2013 > json > skorea_municipalities_geo_simple.json 에서 받아올 수 있다.
하지만 이것을 우리가 아직 편집할수는 없으므로
https://github.com/PinkWink/DataScience/tree/master/data
에서 편집된 02. skorea_municipalities_geo_simple.json을 받아준다.

In [80]:
# json파일 로딩
import json
geo_path = 'pydata/02. skorea_municipalities_geo_simple.json'
geo_str = json.load(open(geo_path, encoding='utf-8'))
In [81]:
# 서울시의 중심의 위도와 경도 정보를 먼저 입력하고 경계선을 그리자.
# 컬러맵은 살인 발생 건수로 지정하자.

map = folium.Map(location=[37.5502, 126.982], zoom_start=11,
                 tiles='Stamen Toner')
map.choropleth(geo_data = geo_str,
               data = crime_anal_norm['살인'],
               columns = [crime_anal_norm.index, crime_anal_norm['살인']],
               fill_color = 'PuRd', #puRd, YlGnBu
               key_on = 'feature.id')
map
Out[81]:

결과를 보면 살인 발생 건수에서 강남 3구가 안전하다고 보기는 어려울 것 같다.

In [82]:
# 강간 발생 건수로 다시 그려보자.

map = folium.Map(location=[37.5502, 126.982], zoom_start=11,
                 tiles='Stamen Toner')
map.choropleth(geo_data = geo_str,
               data = crime_anal_norm['강간'],
               columns = [crime_anal_norm.index, crime_anal_norm['강간']],
               fill_color = 'PuRd', #puRd, YlGnBu
               key_on = 'feature.id')
map
Out[82]:

강간도 강남 3구가 안전한지 의심이 든다.

In [83]:
# 범죄 발생건수

map = folium.Map(location=[37.5502, 126.982], zoom_start=11,
                 tiles='Stamen Toner')
map.choropleth(geo_data = geo_str,
               data = crime_anal_norm['범죄'],
               columns = [crime_anal_norm.index, crime_anal_norm['범죄']],
               fill_color = 'PuRd', #puRd, YlGnBu
               key_on = 'feature.id')
map
Out[83]:

역시 강남 3구와 강서구 주변이 범죄 발생 건수가 높은 것으로 나타나고 있다. 그러나 인구수를 고려해야 할 것 같다. 즉 인구 대비 범죄 발생 비율을 알아보는 것이다.

In [84]:
# 범죄 전체 발생건수에 인구수를 나누고 소수점 밑으로 가서 적절한 값을 곱한다.
tmp_criminal = crime_anal_norm['살인']/ crime_anal_norm['인구수'] *1000000

map = folium.Map(location=[37.5502, 126.982], zoom_start=11,
                 tiles='Stamen Toner')
map.choropleth(geo_data = geo_str,
               data = tmp_criminal,
               columns = [crime_anal.index, tmp_criminal],
               fill_color = 'PuRd', #puRd, YlGnBu
               key_on = 'feature.id')
map
Out[84]:

결과를 보면 인구 대비 범죄 발생 건수로 보면 강남 3구가 1위는 아니지만 안전도가 제일 높다고 말할 수는 없을 것 같다. 그런데 중구와 종로구의 범죄율이 엄청 높아졌다. 아마 거주 인구는 적고, 관광지여서 그런게 아닐까 추측해 본다.

2-12 서울시 경찰서별 검거율과 구별 범죄 발생율을 동시에 시각화하기

이번에는 경찰서별 검거율과 방금 전까지 수행한 범죄 발생율을 동시에 표현해보자.

In [85]:
#검거만 따로 모아두고 앞에서 수집해둔 경찰서의 위도와 경도 정보를 이용하자.
crime_anal_raw['lat'] = station_lat
crime_anal_raw['lng'] = station_lng

col = ['살인 검거', '강도 검거', '강간 검거', '절도 검거', '폭력 검거']
tmp = crime_anal_raw[col] / crime_anal_raw[col].max()

crime_anal_raw['검거'] = np.sum(tmp, axis=1)

crime_anal_raw.head()
Out[85]:
관서명 살인 발생 살인 검거 강도 발생 강도 검거 강간 발생 강간 검거 절도 발생 절도 검거 폭력 발생 폭력 검거 구별 lat lng 검거
0 중부서 2 2 3 2 105 65 1395 477 1355 1170 중구 37.563646 126.989580 1.275416
1 종로서 3 3 6 5 115 98 1070 413 1278 1070 종로구 37.575558 126.984867 1.523847
2 남대문서 1 0 6 4 65 46 1153 382 869 794 중구 37.554758 126.973498 0.907372
3 서대문서 2 2 5 4 154 124 1812 738 2056 1711 서대문구 37.564785 126.966776 1.978299
4 혜화서 3 2 5 4 96 63 1114 424 1015 861 종로구 37.571853 126.998914 1.198382
In [86]:
#경찰서 위치를 확인하자.
map = folium.Map(location=[37.5502, 126.982], zoom_start=11)

for n in crime_anal_raw.index:
    folium.Marker([crime_anal_raw['lat'][n],
                   crime_anal_raw['lng'][n]]).add_to(map)
    
map
Out[86]:
In [87]:
# 검거에 적당한 값 10을 곱해서 원 넓이를 정하고, 경찰서의 검거율을 원의 넓이로 표현하자.
map =folium.Map(location=[37.5502, 126.982], zoom_start=11)

for n in crime_anal_raw.index:
    folium.CircleMarker([crime_anal_raw['lat'][n], crime_anal_raw['lng'][n]],
                        radius = crime_anal_raw['검거'][n]*10,
                        color='#3186cc', fill_color='#3186cc').add_to(map)
map
Out[87]:

이러면 이제 각 경찰서의 위치에서 넓은 원을 가지면 검거율이 높다고 보면 된다

In [88]:
# 색상을 붉은 색으로 해서 범죄 발생 건수를 넣자.
map = folium.Map(location=[37.5502, 126.982], zoom_start=11)

map.choropleth(geo_data = geo_str,
               data = crime_anal_norm['범죄'],
               columns = [crime_anal_norm.index, crime_anal_norm['범죄']],
               fill_color = 'PuRd', #PuRd, YlGnBu
               key_on='feature.id')

for n in crime_anal_raw.index:
    folium.CircleMarker([crime_anal_raw['lat'][n], crime_anal_raw['lng'][n]],
                        radius = crime_anal_raw['검거'][n]*10,
                        color='#3186cc', fill_color='#3186cc').add_to(map)
map
Out[88]:

계속 강서구가 검은색으로 나오길래 확인해 봤더니 데이터 안에 강서구 정보가 없다.........

서울 서부는 범죄는 많이 발생하지만 검거율 또한 높습니다. 서울 강북의 중앙부( 중구, 중랑구 등)는 경찰서의 검거율도 범죄 발생 건수도 높지 않다.

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함