본문 바로가기
study/Python

[Python] 45. CCTV_in_Seoul.csv, crime_in_Seoul.csv, 경찰관서 위치.csv 파일 분석하기, 머신러닝, 알고리즘 선택 : LinearRegression, PolynomialFeatures., 다중회귀분석, seoul_5.csv 파일을 읽어 2022년 7월 6일 평균기온 ..

by 금이패런츠 2022. 7. 6.
728x90
반응형

1. CCTV_in_Seoul.csv, crime_in_Seoul.csv, 경찰관서 위치.csv 파일 분석하기

2. 머신러닝

3. 알고리즘 선택 : LinearRegression, PolynomialFeatures.

4. 다중회귀분석

5. seoul_5.csv 파일을 읽어 2022년 7월 6일 평균기온 예측하기

# -*- coding: utf-8 -*-
"""
Created on Wed Jul  6 08:56:48 2022

@author: p011v
"""

########## 1. CCTV_in_Seoul.csv, crime_in_Seoul.csv, 경찰관서 위치.csv 파일 분석하기.
import pandas as pd
import numpy as np
# 서울 구별 CCTV 정보 데이터 읽기
CCTV_Seoul = pd.read_csv("data/01. CCTV_in_Seoul.csv")
CCTV_Seoul.info()

# 서울 경찰서별 범죄율 정보 데이터 읽기
crime_Seoul = pd.read_csv("data/02. crime_in_Seoul.csv",
                          thousands=',', encoding='euc-kr')
crime_Seoul.info()

# 전국 경찰서 위치 데이터 읽기
police_state = pd.read_csv("data/경찰관서 위치.csv", encoding='euc-kr')
police_state.info()
police_Seoul = police_state[police_state["지방청"] == "서울청"]

# police_Seoul 데이터의 경찰서 컬럼의 내용을 xx서로 이름변경하여 
#           관서명 컬럼으로 생성하기
# crime_Seoul 관서명 컬럼과 같은 형식으로 변경하기
police_Seoul["관서명"] = \
    police_Seoul["경찰서"].apply((lambda x : str(x[2:] + '서')))

# 1. police_Seoul 데이터에 지방청, 경찰서, 구분 컬럼 제거하기
del police_Seoul["지방청"], police_Seoul["경찰서"], police_Seoul["구분"]
police_Seoul.info()
# 2. police_Seoul["관서명"] 중복행을 제거하기
police_Seoul = police_Seoul.drop_duplicates(subset=["관서명"])
police_Seoul
police_Seoul.info()

# police_Seoul 데이터의 주소 컬럼을 이용하여 구별 컬럼을 생성하기
# police_Seoul 데이터의 주소 컬럼제거하기
police_Seoul["구별"] = police_Seoul["주소"].apply(lambda x : str(x).split()[1])
del police_Seoul["주소"]    
police_Seoul["구별"]    

# 관서명 컬럼을 연결컬럼으로 crime_Seoul 데이터와 police_Seoul 데이터를 병합하기
# data_result 데이터에 저장하기
data_result = pd.merge(crime_Seoul, police_Seoul, on="관서명")
data_result.head()

# 구별 범죄의 합계를 출력하기
crime_sum = data_result.groupby("구별").sum()
crime_sum
# 범죄 종류(강간, 강도, 살인, 절도, 폭력)별 검거율 컬럼 추가하기
# 검거율 = 검거 / 발생 * 100
# 1.
crime_sum["강간검거율]"] = crime_sum["강간 검거"] / crime_sum["강간 발생"] * 100
# 2. 
col_list = ['강간', '강도', '살인', '절도', '폭력']
for col in col_list :
    crime_sum[col + "검거율"] = \
        crime_sum[col + " 검거"] / crime_sum[col + " 발생"] * 100
    print(crime_sum[col + "검거율"].tolist)
crime_sum.info()

# 검거율 데이터중 값이 100보다 큰값은 100으로 변경하기
for col in col_list :
    crime_sum.loc[crime_sum[col + "검거율"] > 100, col + "검거율"] = 100
    
for col in col_list :
    print(crime_sum.loc[crime_sum[col + "검거율"] >= 100, col + "검거율"])
# 구별 범죄데이터
crime_sum

# 구별 검거율과, CCTV 갯수를 산점도와 회귀선으로 출력하기.
# 오차가 큰 10개 구 이름을 그래프로 출력하기
# crime_sum 인덱스를 구별 컬럼으로 변경하기.
crime_sum.info()
crime_sum = crime_sum.reset_index()
crime_sum
# 구별 컬럼으로 CCTV_Seoul, crime_sum 데이터를 병합하여 data_result에 저장하기
CCTV_Seoul.info()
# CCTV_Seoul : 기관명->구별
CCTV_Seoul.rename(columns={"기관명":"구별"}, inplace=True)
CCTV_Seoul.drop(["2013년도 이전", "2014년", "2015년", "2016년"], inplace=True, axis=1)
# 구별 컬럼을 연결 컬럼으로 CCTV 데이터와 인구 데이터 합치기
data_result = pd.merge(CCTV_Seoul, crime_sum, on="구별")
data_result.info()
# 절도검거율과 CCTV의 회귀선과 산점도 출력하기
fp1 = np.polyfit(data_result['소계'], data_result['절도검거율'], 1) #기울기, y절편 상수 리턴
f1 = np.poly1d(fp1) # ax + b 함수. 회귀선을 위한 함수
fx = np.linspace(500, 4000, 100) # x축의값. 500 ~ 4000 값을 100개로 균등분할
# data_result 데이터에 오차 컬럼을 추가하기
# 실제검거율과 기대검거율의 차이의 절대값구해서 오차 컬럼에 저장하기
data_result["오차"] = np.abs(data_result["절도검거율"] - f1(data_result["소계"]))
# 오차의 내림차순으로 정렬하여 df_sort 데이터 저장하기
df_sort = data_result.sort_values(by="오차", ascending=(False))
df_sort

import matplotlib.pyplot as plt
plt.rc('font', family = 'Malgun Gothic')
plt.Figure(figsize=(14, 10)) # 그래프 크기
# 산점도 : x축 : 소계, y축 : 절도검거율, 색상 : 오차
plt.scatter(df_sort["소계"], df_sort["절도검거율"], c=df_sort["오차"], s=50)
# 회귀선
plt.plot(fx, f1(fx), ls='dashed', lw=3, color='g')
# 해당 구 이름을 출력
for n in range(10) :
    plt.text(df_sort['소계'][n]*1.001, df_sort['절도검거율'][n]*0.999,
             df_sort['구별'][n], fontsize=15)
plt.xlabel("CCTV 갯수")
plt.ylabel("절도 검거율")
plt.title("CCTV와 절도 검거율 분석")
plt.colorbar()
plt.grid()
plt.show()

'''
    경찰서별 범죄발생건수, CCTV 갯수를 산점도와 회귀선으로 출력하기.
    단, CCTV의 갯수는 구별로 지정한다.
    범죄발생컬럼 : 모든 범죄발생건수의 합.
                  강도발생+강간발생+절도발생+폭행발생+살인발생
'''
crime_Seoul
crime_Seoul["발생"] = crime_Seoul["살인 발생"] + \
                      crime_Seoul["강도 발생"] + \
                      crime_Seoul["강간 발생"] + \
                      crime_Seoul["절도 발생"] + \
                      crime_Seoul["폭력 발생"]
crime_Seoul.info()
police_Seoul.info()
crime_Seoul = pd.merge(crime_Seoul, police_Seoul, on="관서명")
data_result = pd.merge(CCTV_Seoul, crime_Seoul, on="구별")
data_result.info()
data_result.set_index("관서명", inplace=True)
fp1 = np.polyfit(data_result["소계"], data_result["발생"], 1) #기울기, y절편 상수 리턴

fx = np.linspace(500, 3000, 100) # x축의값. 500 ~ 4000 값을 100개로 균등분할
f1 = np.poly1d(fp1) # ax + b 함수. 회귀선을 위한 함수
data_result["오차"] = np.abs(data_result["발생"] - f1(data_result["소계"]))
df_sort = data_result.sort_values(by="오차", ascending=(False))
df_sort
plt.Figure(figsize=(14, 10)) # 그래프 크기
plt.scatter(df_sort["소계"], df_sort["발생"], c=df_sort["오차"], s=50)
plt.plot(fx, f1(fx), ls='dashed', lw=3, color='g')
# 해당 구 이름을 출력
for n in range(10) :
    plt.text(df_sort['소계'][n]*1.02, df_sort['발생'][n]*0.997,
             df_sort.index[n], fontsize=15)
plt.xlabel("CCTV 갯수")
plt.ylabel("범죄발생건수")
plt.title("범죄발생과 CCTV 분석")
plt.colorbar()
plt.grid()
plt.show()

########## 2. 머신러닝
# 컬럼 = 변수 = 피처
'''
    머신러닝 : 기계학습. 예측. AI(인공지능)
               변수(컬럼, 피처)들의 관계를 찾아가는 과정
        1. 지도학습 : 기계학습시 정답을 지정
               1-1. 회귀분석 : 가격, 매출, 주가 예측 등 연속성이 있는 데이터 예측에 사용
               1-2. 분류    : 데이터 선택. 평가 ex)사진을 보고 찾음
        2. 비지도학습 : 기계학습시 정답이 없음
               2-1. 군집 : 비슷한 데이터들끼리 그룹화함
        3. 강화학습 : 행동을 취할때마다 보상을 통해서 학습과정
    
    
    머신러닝 프로세스(과정)
        데이터 정리(전처리) -> 데이터 분리(훈련/검증/테스트) ->알고리즘준비
        -> 모형학습(훈련데이터를 이용) -> 예측(테스트데이터를 이용) -> 모형평가 -> 모형활용
'''

'''
    회귀분석(regression)
        단순회귀분석 : 독립변수, 종속변수가 한개씩 존재
            독립변수(설명변수) : 예측에 사용되는 데이터
            종속변수(예측변수) : 예측해야하는 데이터
'''
# 1. 데이터 정리(전처리) 
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv("data/auto-mpg.csv")
df.head()
df.info()
#  horsepower컬럼의 자료형을 float형으로 변경하기. ?로 변경 error 발생.
#   ?를 결측값으로 변경 -> 결측값 행을 삭제 -> float형으로 변경
df["horsepower"].unique()
#   1.?를 결측값으로 변경
df["horsepower"].replace("?", np.nan, inplace=True)
#   2. 결측값 행을 삭제
df.dropna(subset=["horsepower"], axis=0, inplace=True)
#   3. float형으로 변경
df["horsepower"] = df["horsepower"].astype(float)

# 머신러닝에 필요한 속성(열,컬럼,변수)을 선택하기
ndf = df[['mpg', 'cylinders', 'horsepower', 'weight']]
sns.pairplot(ndf)

# 변수별 상관계수 조회하기
ndf.corr()
# mpg, weight 컬럼의 상관계수 조회하기
ndf[['mpg', 'weight']].corr()
# 산점도 출력하기
#   1.
plt.Figure()
ndf.plot(kind='scatter', x='weight', y='mpg', c='coral', s=10, figsize=(10,5))
plt.show()
#   2.
fig = plt.figure(figsize=(10,5))
ax1 = fig.add_subplot(1,2,1)
ax2 = fig.add_subplot(1,2,2)
sns.regplot(x='weight', y='mpg', data=ndf, ax=ax1)
sns.regplot(x='weight', y='mpg', data=ndf, ax=ax2, fit_reg=False)
plt.show()
#   3.
fig = plt.figure(figsize=(10,5))
sns.jointplot(x='weight', y='mpg', data=ndf)


# 2. 데이터 분리(훈련/테스트)
# sklearn : 머신러닝 모듈
# pip install sklearn
'''
    train_test_split : 훈련/테스트로 분리를 해주는 함수. 임의의 순서로 데이터 분리
    
    train_test_split(독립변수, 종속변수, test_size=테스트데이터의 비율, random_state=seed값)
        test_size=0.3 : 70% 훈련데이터
                        30% 테스트데이터
'''
# 독립변수, 종속변수
X = ndf[["weight"]] #독립변수. DataFrame. 필수는 아님
Y = ndf["mpg"]    #종속변수. Series. 값이 한개이기때문에 Series로 많이 쓰임. 필수는 아님
X
Y
len(X) #392
len(Y) #392

from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=10)
len(X_train) #274. 독립변수 훈련데이터   392 * 0.7
len(X_test)  #118. 독립변수 테스트데이터 392 * 0.3
len(Y_train) #274. 종속변수 훈련데이터   392 * 0.7
len(Y_test)  #118. 종속변수 테스트데이터 392 * 0.3

# 3. 알고리즘준비 : 선형회귀분석 : LinearRegression
from sklearn.linear_model import LinearRegression
lr = LinearRegression() #알고리즘 선택

# 4. 모형학습
lr.fit(X_train, Y_train) #lr : 학습이 완료된 선형 회귀분석 객체

# 5. 예측(테스트데이터)
# X_test : 독립변수의 테스트 데이터
# y_hat : 예측 종속변수. 예측연비값
# Y_test : 실제 종속변수. 실제연비값
y_hat = lr.predict(X_test)

# 6. 모형평가
y_hat[:10]
Y_test[:10]
r_squeare = lr.score(X_test, Y_test)
r_squeare #결정계수. 값이 작을수록 성능이 좋다.
r_squeare = lr.score(X, Y)
r_squeare #결정계수. 값이 작을수록 성능이 좋다.

# 실제데이터와 예측데이터 시각화
y_hat = lr.predict(X) # 독립변수(weight) 전체 데이터 예측 => 예측된 종속변수(mpg)
y_hat # 예측된 연비(mpg) 데이터
# Y : 실제 연비(mpg) 데이터

plt.figure(figsize=(10, 5))
# 실제 연비(mpg) 데이터 밀도를 히스토그램으로 출력 그래프
ax1 = sns.kdeplot(Y, label="Y")
# 예측된 연비(mpg) 데이터 밀도를 히스토그램으로 출력 그래프
ax2 = sns.kdeplot(y_hat, label="y_hat", ax=ax1)
plt.legend()
plt.show()


########## 3. 알고리즘 선택 : PolynomialFeatures.
# LinearRegression : ax + b. 선형회기분석
# PolynomialFeatures : ax**2 + b + c. 다항식분석
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(2) # 2차항
X_train.shape
X_train[:5]
# 1. 데이터 전처리
# X_train 데이터를 다항식의 값으로 변환
X_train_poly = poly.fit_transform(X_train) #다항식에서 처리할 수 있도록 데이터 변환
X_train_poly.shape
X_train_poly[:5]
# 2. 학습하기
pr = LinearRegression() # 선형회귀분석
# Y_train : 정답. mpg 데이터
pr.fit(X_train_poly, Y_train) # 학습하기
X_poly = poly.fit_transform(X) # 전체데이터를 다항식처리
# 3. 예측하기
# y_hat : 예측된 데이터. 예측된 mpg값
y_hat = pr.predict(X_poly) # 예측하기
# 4. 그래프 출력
plt.figure(figsize=(10, 5)) # 그래프 크기
ax1 = sns.kdeplot(Y, label="Y") # 실제 mpg데이터 그래프
ax2 = sns.kdeplot(y_hat, label="y_hat", ax=ax1) # 예측된 mpg 데이터 그래프
plt.legend() # 주석
plt.show()

########## 4. 다중회귀분석
'''
    단순회귀분석 : 독립변수, 종속변수가 한개인 경우
        단항 : 직선의 형태로 예측
        다항 : 곡선의 형태로 예측
    다중회귀분석 : 독립변수가 여러개. 종속변수는 한개인 경우
        Y = b + a1X1 + a2X2 + a3X3 + ... anXn
'''
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
df = pd.read_csv("data/auto-mpg.csv")
df.head()
df.info()
# 1. 데이터 전처리
#  horsepower컬럼의 자료형을 float형으로 변경하기. ?로 변경 error 발생.
#   ?를 결측값으로 변경 -> 결측값 행을 삭제 -> float형으로 변경
df["horsepower"].unique()
df["horsepower"].replace("?", np.nan, inplace=True)
df.dropna(subset=["horsepower"], axis=0, inplace=True)
df.info()
df["horsepower"] = df["horsepower"].astype(float)
# 머신러닝에 필요한 속성(열,컬럼,변수)을 선택하기
ndf = df[['mpg', 'cylinders', 'horsepower', 'weight']]
ndf.info()
# 독립변수, 종속변수 설정
X = ndf[['cylinders', 'horsepower', 'weight']] # 독립변수
Y = ndf["mpg"]
X.shape
Y.shape
# 2. 데이터 분리
from sklearn.model_selection import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.3, random_state=10)
X_train.shape #독립변수. 훈련데이터
X_test.shape  #독립변수. 테스트데이터
Y_train.shape #종속변수. 훈련데이터
Y_test.shape  #종속변수. 테스트데이터
# 3. 알고리즘 준비 : 선형회귀분석
from sklearn.linear_model import LinearRegression
lr = LinearRegression() #알고리즘 선택
# 4. 학습하기
lr.fit( X_train, Y_train)
# 5. 예측하기
y_hat = lr.predict(X) # 예측하기
# 6. 평가
r_squeare = lr.score(X, Y)
r_squeare #결정계수. 값이 작을수록 성능이 좋다.
# 7. 모형활용. 예측된 데이터와 실제 데이터를 kdeplot으로 출력하기
plt.figure(figsize=(10, 5)) # 그래프 크기
ax1 = sns.kdeplot(Y, label="Y") # 실제 mpg데이터 그래프
ax2 = sns.kdeplot(y_hat, label="y_hat", ax=ax1) # 예측된 mpg 데이터 그래프
plt.legend() # 주석
plt.show()

# 단순회귀분석의 간단한 예
# 독립변수 1개, 종속변수 1개
x = [[10], [5], [9], [7]] # 공부시간 : 독립변수
y = [100, 50, 90, 77]     # 시험점수 : 종속변수
model = LinearRegression()
model.fit(x, y)
result = model.predict([[7], [8], [4], [6]])
result

# 다중회귀분석의 간단한 예
# 독립변수 여러개, 종속변수 1개
x = [[10, 3], [5, 2], [9, 3], [7, 3], [8, 2]] # 공부시간, 학년 : 독립변수
y = [100, 50, 90, 77, 85]     # 시험점수 : 종속변수
model = LinearRegression()
model.fit(x, y)
result = model.predict([[7, 2], [5, 3]])
result

########## 5. seoul_5.csv 파일을 읽어 2022년 7월 6일 평균기온 예측하기
# 1. 단순회귀분석
# 데이터전처리
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
plt.rc('font', family = 'Malgun Gothic')
seoul = pd.read_csv("data/seoul_5.csv", encoding="euc-kr")
seoul.head()
seoul.info()
# 년도컬럼 생성
seoul["년도"] = seoul["날짜"].apply(lambda x : x[:4])
seoul["년도"].head()
seoul.info()
# seoul0706 : 매년 7월 6일에 해당하는 정보 저장
seoul["날짜"].str[5:]
#seoul0706 = seoul.loc[seoul["날짜"].str[5:] == '07-06']
seoul0706 = seoul.loc[seoul["날짜"].apply(lambda x : x[5:]) == '07-06']
seoul0706.head()
seoul0706.info()
seoul0706.columns = ["날짜", "지점", "평균기온", "최저기온", "최고기온", "년도"]
seoul0706.loc[seoul0706["평균기온"].isnull()]
# 결측값 데이터 제거
seoul0706.dropna(subset=["평균기온"], axis=0, inplace=True)
# 알고리즘 준비 : 선형회귀분석
from sklearn.linear_model import LinearRegression
model = LinearRegression()
X = seoul0706[["년도"]]
Y = seoul0706["최고기온"]
# 학습하기
model.fit(X, Y)
# 예측하기
result = model.predict([[2022]])
print("단순회귀분석 : ", result)

# 2. 다중회귀분석
X = seoul0706[["년도", "최저기온"]]
Y = seoul0706["최고기온"]
# 학습하기
model.fit(X, Y)
# 예측하기
result = model.predict([[2022, 26]])
print("단순회귀분석 : ", result)

seoul_5.csv
1.13MB

728x90
반응형