본문 바로가기
프로그래밍/AI

서울시 범죄현황 통계자료 분석 및 시각화

by slowin 2024. 11. 19.

교육일: 24.11.19(화)

강사님: 조대연

  • 서울시 범죄현황 통계자료 분석 및 시각화
    • 데이터 입력 및 전처리
    • 데이터 탬색
      • 검거율 기준으로 데이터 정렬하기
      • 범죄별 발생건수 정규화 하기
      • 한글 데이터 시각화
      • 구별 살인/절도 발생 건수 순위 살펴보기
      • [ 인구수 대비 ] 구별 살인 발생 순위 살펴보기
      • [ 인구수 대비 ] 구별 5대 범죄 수치 평균 계산하기
      • [ 인구수 대비 5대 범죄 발생 수치 평균 ] 구별 순위 비교하기
    • 데이터 시각화
      • 구별 살인사건 발생 건수 지도 시각화
        • 지도 시각화: Folium Lib 활용
        • 지도 데이터: Geo Json 데이터 활용

코드

def load_and_preprocess_data():  
    """예시 데이터 구조 로드"""
    crime_data = pd.DataFrame({  
        '구별': ['강남구', '강동구', '강북구', '강서구', '관악구'],  
        '살인': [10, 5, 8, 7, 6],  
        '절도': [1000, 800, 600, 900, 750],  
        '폭력': [500, 400, 350, 450, 380],  
        '강간': [30, 25, 20, 28, 22],  
        '강도': [15, 10, 12, 14, 11],  
        '검거율': [85, 82, 88, 80, 83],  
        '인구수': [500000, 450000, 320000, 480000, 420000]  
    })  
    return crime_data  


# 2. 데이터 탐색 함수들  
def sort_by_arrest_rate(df):  
    """
        검거율 기준으로 데이터 정렬
        검거율 기준 정렬:
                구별  검거율
            2  강북구   88
            0  강남구   85
            4  관악구   83
            1  강동구   82
            3  강서구   80

    """  
    return df.sort_values('검거율', ascending=False)  


def normalize_crime_counts(df):  
    """범죄별 발생건수 정규화"""  
    """
    정규화된 범죄 발생건수:
       살인_정규화  절도_정규화    폭력_정규화  강간_정규화  강도_정규화
    0     1.0   1.000  1.000000     1.0     1.0
    1     0.0   0.500  0.333333     0.5     0.0
    2     0.6   0.000  0.000000     0.0     0.4
    3     0.4   0.750  0.666667     0.8     0.8
    4     0.2   0.375  0.200000     0.2     0.2
    """
    crime_columns = ['살인', '절도', '폭력', '강간', '강도']  
    df_normalized = df.copy()  
    for col in crime_columns:  
        df_normalized[f'{col}_정규화'] = (df[col] - df[col].min()) / (df[col].max() - df[col].min())  
    return df_normalized  


def get_crime_rankings(df, crime_type):  
    """특정 범죄 유형의 구별 순위"""  
    """
    구별 살인 발생 순위:
        구별  살인
    0  강남구  10
    2  강북구   8
    3  강서구   7
    4  관악구   6
    1  강동구   5
    """
    return df[['구별', crime_type]].sort_values(crime_type, ascending=False)  


def calculate_per_capita_crime(df, crime_type):  
    """인구수 대비 범죄 발생률 계산"""  
    """
    인구수 대비 살인 발생률:
        구별   살인_인구비율
    2  강북구  2.500000
    0  강남구  2.000000
    3  강서구  1.458333
    4  관악구  1.428571
    1  강동구  1.111111
    """
    return df.assign(**{  
        f'{crime_type}_인구비율': df[crime_type] / df['인구수'] * 100000  
    }).sort_values(f'{crime_type}_인구비율', ascending=False)  


def calculate_average_crime_rate(df):  
    """인구수 대비 5대 범죄 평균 계산"""  
    """
    5대 범죄 평균 (인구수 대비):
        구별    5대범죄_평균
    0  강남구  62.200000
    2  강북구  61.875000
    3  강서구  58.291667
    4  관악구  55.666667
    1  강동구  55.111111
    """
    crime_types = ['살인', '절도', '폭력', '강간', '강도']  
    df_copy = df.copy()  

    # 각 범죄별 인구 대비 비율 계산  
    for crime in crime_types:  
        df_copy[f'{crime}_인구비율'] = df[crime] / df['인구수'] * 100000  

    # 평균 계산  
    crime_rate_columns = [f'{crime}_인구비율' for crime in crime_types]  
    df_copy['5대범죄_평균'] = df_copy[crime_rate_columns].mean(axis=1)  

    return df_copy.sort_values('5대범죄_평균', ascending=False)  


# 3. 시각화 함수들  
def plot_crime_stats(df, title):  
    """범죄 통계 막대 그래프"""  
    plt.figure(figsize=(12, 6))  
    df.plot(kind='bar')  
    plt.title(title)  
    plt.xticks(rotation=45)  
    plt.tight_layout()  
    plt.show()  


def create_crime_map(df, crime_type, geojson_file):  
    """범죄 발생 건수 지도 시각화"""  
    # 서울 중심 좌표  
    seoul_center = [37.5665, 126.9780]  

    # 지도 생성  
    m = folium.Map(  
        location=seoul_center,  
        zoom_start=11,  
        tiles='CartoDB positron'  
    )  

    # Choropleth 레이어 추가  
    folium.Choropleth(  
        geo_data=geojson_file,  
        name='choropleth',  
        data=df,  
        columns=['구별', crime_type],  
        key_on='feature.properties.name',  
        fill_color='YlOrRd',  
        fill_opacity=0.7,  
        line_opacity=0.2,  
        legend_name=f'{crime_type} 발생건수'  
    ).add_to(m)  

    return m  

def calculate_crime_ratio(df):  
    """범죄 발생 비율 계산 및 정규화"""  
    crime_columns = ['살인', '절도', '폭력', '강간', '강도']  
    df_ratio = df.copy()  

    # 각 범죄별 인구 대비 비율 계산 및 정규화  
    for crime in crime_columns:  
        # 인구 대비 비율 계산  
        raw_ratio = df[crime] / df['인구수'] * 100000  
        # 정규화  
        df_ratio[f'{crime}_비율'] = (raw_ratio - raw_ratio.min()) / (raw_ratio.max() - raw_ratio.min())  

    # 전체 발생비율 계산 (평균)  
    ratio_columns = [col for col in df_ratio.columns if col.endswith('_비율')]  
    df_ratio['전체발생비율'] = df_ratio[ratio_columns].mean(axis=1)  

    # 필요한 컬럼만 선택  
    result = df_ratio[['구별'] + ratio_columns + ['전체발생비율']]  
    return result.set_index('구별')  

def plot_crime_heatmap(df):  
    """범죄 발생 비율 히트맵"""  
    plt.figure(figsize=(10, 10))  
    crime_ratio = calculate_crime_ratio(df)  
    sns.heatmap(crime_ratio.sort_values(by='전체발생비율', ascending=False),  
                annot=True,  
                fmt='.2f',  
                linewidths=.5,  
                cmap='Reds')  
    plt.title('범죄 발생(전체발생비율로 정렬) - 각 항목을 정규화한 후 인구로 나눔')  
    plt.tight_layout()  
    plt.show()


# 메인 실행 함수  
def main():  
    # 데이터 로드  
    df = load_and_preprocess_data()  

    # 1. 검거율 기준 정렬  
    df_sorted = sort_by_arrest_rate(df)  
    print("검거율 기준 정렬:")  
    print(df_sorted[['구별', '검거율']])  

    # 2. 범죄별 발생건수 정규화  
    df_normalized = normalize_crime_counts(df)  
    print("\n정규화된 범죄 발생건수:")  
    print(df_normalized.filter(like='정규화'))  

    # 3. 구별 살인 발생 순위  
    murder_rankings = get_crime_rankings(df, '살인')  
    print("\n구별 살인 발생 순위:")  
    print(murder_rankings)  

    # 4. 인구수 대비 살인 발생률  
    murder_per_capita = calculate_per_capita_crime(df, '살인')  
    print("\n인구수 대비 살인 발생률:")  
    print(murder_per_capita[['구별', '살인_인구비율']])  

    # 5. 5대 범죄 평균  
    crime_averages = calculate_average_crime_rate(df)  
    print("\n5대 범죄 평균 (인구수 대비):")  
    print(crime_averages[['구별', '5대범죄_평균']])  

    # 시각화 예시  
    plot_crime_stats(df[['살인', '강도']], '구별 살인/강도 발생 현황')  

    # 2. 히트맵  
    plot_crime_heatmap(df)
    # 지도 시각화 (실제 geojson 파일 필요)  
    # geojson_file = json.load(open('seoul_geo.json'))    # crime_map = create_crime_map(df, '살인', geojson_file)  
    # crime_map.save('seoul_crime_map.html')  

if __name__ == "__main__":  
    main()

 

 

히트맵

 

지도시각화

'프로그래밍 > AI' 카테고리의 다른 글

유튜브 인기동영상 시각화  (0) 2024.11.24
아나콘다란?  (1) 2024.11.22
Pandas 기본 문법  (1) 2024.11.19
머신러닝을 위한 데이터 - 종류, 수집, 활용  (2) 2024.11.19
python 기초 문법  (3) 2024.11.18