• tips = sns.load_dataset('tips')
  • sns.lmplot(x="total_bill", y="tip", data=tips, size=7)
  • sns.countplot(
    x=result_mol["mall"],
    data=result_mol,
    palette="RdYlGn",
    order=result_mol["mall"].value_counts().index
    )
  • icon
    prefix="fa"
    prefix="glyphicon"
    각 종류(fa,glyphicon)에 해당하는 아이콘 다름. (사이트 참고)
  • sns.despine(offset=10)
    (좌측 하단 모서리 약간 띄어지는 효과)

1. 데이터 수집 및 가공

  1. crime_raw_data
import pandas as pd
import numpy as np

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

# null값 제거
crime_raw_data = crime_raw_data[crime_raw_data["죄종"].notnull()]

# 확인
crime_raw_data[crime_raw_data["죄종"].isnull()]
  1. crime_station
# pivot_table 생성
crime_station = crime_raw_data.pivot_table(
    crime_raw_data,
    index="구분",
    columns=["죄종","발생검거"],
    aggfunc=[np.sum],
    fill_value=0
)

crime_station.columns = crime_station.columns.droplevel([0,1])

# crime_station에 구별, 위도, 경도 값 추가
import googlemaps

gmaps_key = "gmaps_key"
gmaps = googlemaps.Client(key=gmaps_key)

# 빈 값 컬럼 생성
crime_station["구별"] = np.nan
crime_station["lat"] = np.nan
crime_station["lng"] = np.nan

count=0
for idx, rows in crime_station.iterrows():
    station_name = "서울" + str(idx) + "경찰서"
    tmp = gmaps.geocode(station_name, language="ko")
    
    tmp_gu = tmp[0].get("formatted_address")
    
    lat = tmp[0].get("geometry")["location"]["lat"]
    lng = tmp[0].get("geometry")["location"]["lng"]
    
    # 값 채워주기
    crime_station.loc[idx, "lat"] = lat
    crime_station.loc[idx, "lng"] = lng
    crime_station.loc[idx, "구별"] = tmp_gu.split()[2]
    
    print(count)
    count += 1

# 컬럼 수정
lenCrime = len(crime_station.columns.get_level_values(0))

tmp = [
    crime_station.columns.get_level_values(0)[n] + crime_station.columns.get_level_values(1)[n]
    for n in range(0, lenCrime)
]

crime_station.columns = tmp

# 데이터 저장
crime_station.to_csv("../data/02. crime_in_Seoul_raw3.csv", sep=",", encoding="utf-8")
  1. crime_anal_gu
crime_anal_station = pd.read_csv("../data/02. crime_in_Seoul_raw3.csv", index_col=0, encoding="utf-8")

# crime_anal_gu pivot_table 생성
crime_anal_gu = pd.pivot_table(crime_anal_station, index="구별", aggfunc=np.sum)

crime_anal_gu.drop(["lat", "lng"], axis=1, inplace=True)

# 검거율
target = ["강간검거율", "강도검거율", "살인검거율", "절도검거율", "폭력검거율"]
num = ["강간검거", "강도검거", "살인검거", "절도검거", "폭력검거"]
den = ["강간발생", "강도발생", "살인발생", "절도발생", "폭력발생"]
crime_anal_gu[target] = crime_anal_gu[num].div(crime_anal_gu[den].values) * 100

crime_anal_gu.drop(["강간검거", "강도검거", "살인검거", "절도검거", "폭력검거"], axis=1, inplace=True)

crime_anal_gu[crime_anal_gu[target]>100] = 100

# 컬럼명 변경
crime_anal_gu.rename(
    columns={
        "강간발생":"강간",
        "강도발생":"강도",
        "살인발생":"살인",
        "절도발생":"절도",
        "폭력발생":"폭력"
    }, inplace=True
)
  1. crime_anal_nom
col = ["살인", "강도", "강간", "절도", "폭력"]
crime_anal_nom = crime_anal_gu[col] / crime_anal_gu[col].max()

# 검거율 추가
col2 = ["강간검거율", "강도검거율", "살인검거율", "절도검거율", "폭력검거율"]
crime_anal_nom[col2] = crime_anal_gu[col2]

# 인구수, cctv 개수 추가
result_CCTV = pd.read_csv("../data/01. CCTV_result_practice2.csv", index_col="구별", encoding="utf-8")
crime_anal_nom[["인구수", "CCTV"]] = result_CCTV[["인구수", "소계"]]

# 범죄 컬럼 추가
col = ["강간", "강도", "살인", "절도", "폭력"]
crime_anal_nom["범죄"] = np.mean(crime_anal_nom[col], axis=1)

# 검거 컬럼 추가
col = ["강간검거율", "강도검거율", "살인검거율", "절도검거율", "폭력검거율"]
crime_anal_nom["검거"] = np.mean(crime_anal_nom[col], axis=1)

# 데이터 저장
crime_anal_nom.to_csv("../data/02. crime_in_Seoul_final2.csv", sep=",", encoding="utf-8")

2. 시각화

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

plt.rcParams["axes.unicode_minus"] = False
rc("font", family="Arial Unicode MS")
%matplotlib inline
  1. 상관관계(pairplot)
# pairplot 강도, 살인, 폭력에 대한 상관관계 확인
sns.pairplot(
    data=crime_anal_nom,
    vars=["살인", "강도", "폭력"],
    kind="reg",
    height=2
);

# 인구수, cctv와 강도, 살인의 상관관계 확인
def drawGraph():
    sns.pairplot(
        data=crime_anal_nom,
        x_vars=["인구수", "CCTV"],
        y_vars=["강도", "살인"],
        kind="reg",
        height=2
    )
drawGraph()

# 인구수, cctv와 강도검거율, 폭력검거율의 상관관계 확인
def drawGraph():
    sns.pairplot(
        data=crime_anal_nom,
        x_vars=["인구수", "CCTV"],
        y_vars=["강도검거율", "살인검거율"],
        kind="reg",
        height=2
    )
drawGraph()



  1. heatmap
# 검거율 heatmap
# "검거" 컬럼을 기준으로 정렬

def drawGraph():
    target_col = ["강간검거율", "강도검거율", "살인검거율", "절도검거율", "폭력검거율", "검거"]
    crime_anal_nom_sort = crime_anal_nom.sort_values(by="검거", ascending=False)
    
    plt.figure(figsize=(10,10))
    sns.heatmap(
        data=crime_anal_nom_sort[target_col],
        annot=True,
        fmt="f",
        linewidths=0.5,
        cmap="RdPu") 
    plt.title("범죄 검거 비율(정규화된 검거의 합으로 정렬)")
    plt.show

drawGraph()

# 범죄발생 건수 heatmap
# "범죄" 컬럼을 기준으로 정렬

def drawGraph():
    target_col = ["살인", "강도", "강간", "절도", "폭력", "범죄"]
    crime_anal_nom_sort = crime_anal_nom.sort_values(by="범죄", ascending=False)
    
    plt.figure(figsize=(10,10))
    sns.heatmap(
        data=crime_anal_nom_sort[target_col],
        annot=True,
        fmt="f",
        linewidths=0.5,
        cmap="RdPu") 
    plt.title("범죄 비율(정규화된 발생건수로 정렬)")
    plt.show

drawGraph()


  1. folium
import folium
import pandas as pd
import json

crime_anal_norm = pd.read_csv("../data/02. crime_in_Seoul_final2.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"))

# 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

  1. CircleMarker
crime_anal_station = pd.read_csv("../data/02. crime_in_Seoul_raw2.csv")

col = ["살인검거", "강도검거", "강간검거", "절도검거", "폭력검거"]
tmp = crime_anal_station[col] / crime_anal_station[col].max()
crime_anal_station["검거"] = np.mean(tmp, axis=1)
# 검거에 값을 곱한 뒤 원의 넓이 적용
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

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

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_norm = crime_loc / crime_loc.max()
crime_loc_norm["종합"] = np.mean(crime_loc_norm, axis=1)
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()

profile
21세기 주인공

0개의 댓글