[EDA] 서울시 범죄 현황 데이터 분석2 - 시각화

박미영·2023년 4월 2일
0

DataSchool StudyNote - EDA

목록 보기
10/19
post-thumbnail

📌서울시 범죄현황 데이터 시각화

  • 시각화 패키지 불러오기
import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib import rc

plt.rcParams["axes.unicode_minus"] = False
get_ipython().run_line_magic("matplotlib", "inline")
rc("font", family="Malgun Gothic")
  • 마지막 작업 데이터



📍pairplot

  • 강도, 살인, 폭력에 대한 상관관계()
sns.pairplot(data=crime_anal_norm, vars=["살인", "강도", "폭력"], kind="reg", height=3); # kind="reg" 회기분석



kind option

  1. scatter

  2. reg

  3. kde

  4. hist



  • "인구수", "CCTV"와 "살인", "강도"의 상관관계
def drawGraph():
    sns.pairplot(data=crime_anal_norm, 
                 x_vars=["인구수", "CCTV"],
                 y_vars=["살인", "강도"],
                 kind="reg",
                 height=4)
    plt.show()
    
drawGraph()



  • "인구수", "CCTV"와 "살인검거율", "폭력검거율"의 상관관계
def drawGraph():
    sns.pairplot(data=crime_anal_norm, 
                 x_vars=["인구수", "CCTV"],
                 y_vars=["살인검거율", "폭력검거율"],
                 kind="reg",
                 height=4)
    plt.show()
    
drawGraph()



  • "인구수", "CCTV"와 "절도검거율", "강도검거율"의 상관관계
def drawGraph():
    sns.pairplot(data=crime_anal_norm, 
                 x_vars=["인구수", "CCTV"],
                 y_vars=["절도검거율", "강도검거율"],
                 kind="reg",
                 height=4)
    plt.show()
    
drawGraph()



📍heatmeap

- 검거율

  • "검거" 컬럼을 기준으로 정렬
def drawGraph():
    
    # 데이터 프레임 생성
    target_col = ["강간검거율", "강도검거율", "살인검거율", "절도검거율", "폭력검거율", "검거"]    
    crime_anal_norm_sort = crime_anal_norm.sort_values(by="검거", ascending=False) #내림차순 정렬
    
    # 그래프 설정
    plt.figure(figsize=(10, 10))
    sns.heatmap(
        data=crime_anal_norm_sort[target_col], 
        annot=True, # 데이터값 표현
        fmt="f", # d: 정수, f: 실수
        linewidths=0.5, # 간격설정
        cmap="RdPu",
    )
    plt.title("범죄 검거 비율(정규화된 검거의 합으로 정렬)")
    plt.show()
    
drawGraph()   

  • linewidths=5인 경우 (default = 0)



- 범죄발생 건수

  • 범죄" 컬럼을 기준으로 정렬
def drawGraph():
    
    # 데이터 프레임 생성
    target_col = ["살인", "강도", "강간", "절도", "폭력", "범죄"]    
    crime_anal_norm_sort = crime_anal_norm.sort_values(by="범죄", ascending=False) #내림차순 정렬
    
    # 그래프 설정
    plt.figure(figsize=(10, 10))
    sns.heatmap(
        data=crime_anal_norm_sort[target_col], 
        annot=True, # 데이터값 표현
        fmt="f", # d: 정수, f: 실수
        linewidths=0.5, # 간격설정
        cmap="RdPu",
    )
    plt.title("범죄 비율(정규화된 발생 건수로 정렬)")
    plt.show()
    
drawGraph()    



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

import json
import folium
import pandas as pd
crime_anal_norm = pd.read_csv(
    "../data/02. crime_in_Seoul_final.csv", index_col=0, encoding="utf-8"
)

geo_path = "../data/02. skorea_municipalities_geo_simple.json"
geo_str = json.load(open(geo_path, encoding="utf-8"))
crime_anal_norm.tail(2)

📍살인발생 건수 지도 시각화

  • folium.Map 지도 표시
my_map = folium.Map(
    location=[37.5502, 126.982],
    zoom_start=11,
    tiles="Stamen Toner",
)

my_map


  • Choropleth 경계선 표시
# 살인발생 건수 지도 시각화

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대 범죄 건수 지도 시각화

# 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_raw.csv", encoding="utf-8"
)

crime_anal_station.tail(2)

📍정규화

col = ["살인검거", "강도검거", "강간검거", "절도검거", "폭력검거"]
tmp = crime_anal_station[col] / crime_anal_station[col].max() # 정규화 0 - 1
crime_anal_station["검거"] = np.mean(tmp, axis=1)  # numpy axis=1 행(가로), pandas axis=1 열(세로)
crime_anal_station.tail()

📍경찰서 위치 마커 표시 - Marker

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



📍CircleMarker

검거에 값을 곱한 뒤 원의 넓이 적용

# 검거에 값을 곱한 뒤 원의 넓이 적용

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

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

원이 클수록 검거율이 높다.


  • 경계선
# 검거에 값을 곱한 뒤 원의 넓이 적용

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()

crime_loc_raw.info()

crime_loc_raw.범죄명.unique()

crime_loc_raw["장소"].unique()


📍피벗 테이블 생성

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)

📍정규화

col = ["살인", "강도", "강간", "절도", "폭력"]
crime_anal_norm = crime_loc / crime_loc.max() # 정규화
crime_anal_norm.head()

📍컬럼 추가

crime_anal_norm["종합"] = np.mean(crime_anal_norm, axis=1)
crime_anal_norm.tail(2)

📍matplotlib

import matplotlib.pyplot as plt
import seaborn as sns
from matplotlib import rc

rc("font", family="Malgun Gothic")             # 한글 폰트 사용 
%matplotlib inline
crime_anal_norm_sort = crime_anal_norm.sort_values("종합", ascending=False) #내림차순

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




"이 글은 제로베이스 데이터 취업 스쿨 강의 자료 일부를 발췌한 내용이 포함되어 있습니다."

0개의 댓글