2 분 소요

서울시 범죄 현황에 대한 지도 시각화

crime_anal_norm.tail(2)
살인 강도 강간 절도 폭력 강간검거율 강도검거율 살인검거율 절도검거율 폭력검거율 인구수 CCTV 범죄 검거
구별
중구 0.214286 0.205128 0.383721 0.585671 0.407957 74.747475 87.5 100.0 42.511628 89.707865 134593 1023 0.359353 78.893394
중랑구 0.571429 0.358974 0.317829 0.460637 0.580125 91.463415 100.0 87.5 62.211709 85.714286 412780 916 0.457799 85.377882

살인발생 건수 지도 시각화

my_map = folium.Map(
    location=[37.5502, 126.982],
    zoom_start=11,
    tiles="Stamen Toner"
)

folium.Choropleth(
    geo_data=geo_str, # 우리나라 경계선 좌표값이 담긴 데이터
    data=crime_anal_norm["살인"],
    columns=[crime_anal_norm.index, crime_anal_norm["살인"]],
    key_on="feature.id",
    fill_color="PuRd",
    fill_opacity=0.7,
    line_opacity=0.2,
    legend_name="정규화된 살인 발생 건수"
).add_to(my_map)

my_map


성범죄 건수 지도 시각화

my_map = folium.Map(
    location=[37.5502, 126.982],
    zoom_start=11,
    tiles="Stamen Toner"
)

folium.Choropleth(
    geo_data=geo_str, # 우리나라 경계선 좌표값이 담긴 데이터
    data=crime_anal_norm["강간"],
    columns=[crime_anal_norm.index, crime_anal_norm["강간"]],
    key_on="feature.id",
    fill_color="PuRd",
    fill_opacity=0.7,
    line_opacity=0.2,
    legend_name="정규화된 강간 발생 건수"
).add_to(my_map)

my_map

5대 범죄 건수 지도 시각화


my_map = folium.Map(
    location=[37.5502, 126.982],
    zoom_start=11,
    tiles="Stamen Toner"
)

folium.Choropleth(
    geo_data=geo_str, # 우리나라 경계선 좌표값이 담긴 데이터
    data=crime_anal_norm["범죄"],
    columns=[crime_anal_norm.index, crime_anal_norm["범죄"]],
    key_on="feature.id",
    fill_color="PuRd",
    fill_opacity=0.7,
    line_opacity=0.2,
    legend_name="정규화된 5대 범죄 발생 건수"
).add_to(my_map)

my_map


인구 대비 범죄 발생 건수

tmp_criminal = crime_anal_norm["범죄"] / crime_anal_norm["인구수"]

my_map = folium.Map(
    location=[37.5502, 126.982],
    zoom_start=11,
    tiles="Stamen Toner"
)

folium.Choropleth(
    geo_data=geo_str, # 우리나라 경계선 좌표값이 담긴 데이터
    data=tmp_criminal,
    columns=[crime_anal_norm.index, tmp_criminal],
    key_on="feature.id",
    fill_color="PuRd",
    fill_opacity=0.7,
    line_opacity=0.2,
    legend_name="인구 대비 범죄 발생 건수"
).add_to(my_map)

my_map


경찰서별 정보 범죄발생과 함께 정리

crime_anal_station = pd.read_csv(
    "../data/02. crime_in_Seoul_1st.csv", encoding="utf-8"
)

crime_anal_station.tail(2)
구분 강간검거 강간발생 강도검거 강도발생 살인검거 살인발생 절도검거 절도발생 폭력검거 폭력발생 구별 lat lng
29 29 중부 96.0 141.0 3.0 3.0 2.0 2.0 485.0 1204.0 1164.0 1335.0 중구 37.563646 126.989580
30 30 혜화 64.0 101.0 6.0 6.0 2.0 2.0 379.0 988.0 842.0 972.0 종로구 37.571840 126.998856
col = ["살인검거", "강도검거", "강간검거", "절도검거", "폭력검거"]
tmp = crime_anal_station[col] / crime_anal_station[col].max() # 정규화
crime_anal_station["검거"] = np.mean(tmp, axis=1) # numpy axis=1 : 행(가로), pandas axis=1 : 열(세로)
crime_anal_station.tail(2)
구분 강간검거 강간발생 강도검거 강도발생 살인검거 살인발생 절도검거 절도발생 폭력검거 폭력발생 구별 lat lng 검거
29 29 중부 96.0 141.0 3.0 3.0 2.0 2.0 485.0 1204.0 1164.0 1335.0 중구 37.563646 126.989580 0.277182
30 30 혜화 64.0 101.0 6.0 6.0 2.0 2.0 379.0 988.0 842.0 972.0 종로구 37.571840 126.998856 0.240065

경찰서 위치 마커 표시

my_map = folium.Map(
    location=[37.5502, 126.982], zoom_start=11
)

for idx, rows in crime_anal_station.iterrows():
    folium.Marker(
        location=[rows["lat"], rows["lng"]]
    ).add_to(my_map)
    
my_map


경찰서 검거율 원에 적용

my_map = folium.Map(
    location=[37.5502, 126.982], zoom_start=11
)

folium.Choropleth(
    geo_data=geo_str,
    data=crime_anal_norm["범죄"],
    columns=[crime_anal_norm.index, crime_anal_norm["범죄"]],
    key_on="feature.id",
    fill_color="PuRd",
    fill_opacity=0.7,
    line_opacity=0.2,
    
).add_to(my_map)

for idx, rows in crime_anal_station.iterrows():
    folium.CircleMarker(
        location=[rows["lat"], rows["lng"]],
        radius=rows["검거"] * 50,
        popup=rows["구분"] + " : " + "%.2f" % rows["검거"],
        color="#3186cc",
        fill=True,
        fill_color="#3186cc"
    ).add_to(my_map)
    
my_map


서울시 범죄 현황 발생 장소 분석

추가 검증

crime_loc_raw = pd.read_csv(
    "../data/02. crime_in_Seoul_location.csv", thousands=",", encoding="euc-kr"
)

crime_loc_raw.tail(2)
범죄명 장소 발생건수
63 폭력 금융기관 42
64 폭력 기타 26382
crime_loc_raw.범죄명.unique()

=>

array(['살인', '강도', '강간.추행', '절도', '폭력'], dtype=object)
---------------------------------------------------------------
crime_loc_raw["장소"].unique()

=>

array(['아파트, 연립 다세대', '단독주택', '노상', '상점', '숙박업소, 목욕탕', '유흥 접객업소', '사무실',
       '역, 대합실', '교통수단', '유원지 ', '학교', '금융기관', '기타'], dtype=object)
--------------------------------------------------------------------------------------------------
crime_loc = crime_loc_raw.pivot_table(
    crime_loc_raw, index="장소", columns="범죄명", aggfunc=[np.sum]
)

crime_loc.columns = crime_loc.columns.droplevel([0, 1])
crime_loc.tail(2)
범죄명 강간.추행 강도 살인 절도 폭력
장소
유흥 접객업소 398 13 8 2035 2645
학교 33 0 0 400 203
col = ["살인", "강도", "강간", "절도", "폭력"]
crime_loc_norm = crime_loc / crime_loc.max() # 정규화
crime_loc_norm.head()
범죄명 강간.추행 강도 살인 절도 폭력
장소
교통수단 0.324718 0.000000 0.000000 0.021027 0.008415
금융기관 0.000940 0.011494 0.015385 0.049738 0.001592
기타 1.000000 0.770115 1.000000 1.000000 1.000000
노상 0.463346 1.000000 0.338462 0.429235 0.929990
단독주택 0.185620 0.172414 0.461538 0.103110 0.135661
crime_loc_norm["종합"] = np.mean(crime_loc_norm, axis=1)
crime_loc_norm.tail(2)
범죄명 강간.추행 강도 살인 절도 폭력 종합
장소
유흥 접객업소 0.187030 0.149425 0.123077 0.093632 0.100258 0.130684
학교 0.015508 0.000000 0.000000 0.018404 0.007695 0.008321

장소별 범죄 발생 장소

crime_loc_norm_sort = crime_loc_norm.sort_values("종합", ascending=False) # 내림차순

def drawGraph():
    plt.figure(figsize=(10, 10))
    sns.heatmap(
        crime_loc_norm_sort,
        annot=True,
        fmt="f",
        linewidths=0.5,
        cmap="RdPu")
    plt.title("범죄 발생 장소")
    plt.show()
drawGraph()