Notice
Recent Posts
Recent Comments
Link
헬창 개발자
1. 서울시 cctv 현황 분석 본문
시작전 환경설정 필수!!!!!!!!!!!!!!!!!!!!!!!!!
https://health-coding.tistory.com/31?category=997153
------------------------------------------------------------------------------------------------------------------------------
학습 목표
- Pandas와 Matplotlib를 이용한 데이터 분석 및 시각화
- 단순한 그래프 표현에서 한 단계 더 나아가 경향을 확인하고 시각화하는 기초 확인\
- https://health-coding.tistory.com/33 실습 먼저 진행하는거 추천
1. Pandas
판다스(Pandas)는 파이썬 데이터 처리를 위한 라이브러리입니다. 파이썬을 이용한 데이터 분석과 같은 작업에서 필수 라이브러리로 알려져있습니다.
pip install pandas # 아나콘다를 설치하지 않았다면 다음 명렁어로 설치
import pandas as pd
Pandas는 총 두 가지의 데이터 구조를 사용합니다.
- 시리즈(Series)
- 데이터프레임(DataFrame)
- 시리즈(Series) 시리즈 클래스는 1차원 배열의 값(values)에 각 값에 대응되는 인덱스(index)를 부여할 수 있는 구조를 갖고 있습니다.
- 시리즈(Series) 데이터프레임은 2차원 리스트를 매개변수로 전달합니다. 2차원이므로 행방향 인덱스(index)와 열방향 인덱스(column)가 존재합니다.
2. Matplotlib
- 파이썬의 대표 시각화 도구
- import matplotlib.pyplot as plt 로 많이 사용
- Juypter NoteBook의 경우 결과가 out session에 나타난다.
- %matplotlib inline 옵션을 사용 : 결과창을 새 창에 열지 않고 현재 Jupyter Notebook 창에 출력
import matplotlib.pyplot as plt
from matplotlib import rc
# 마이너스 부호 때문에 한글이 깨질 수 있기 때문에 설정
plt.rcParams["axes.unicode_minus"] = False
# 한글 폰트 설정
rc('font', family='Malgun Gothic')
3. 데이터 읽기
<데이터 설명>
- 서울시 자치구 년도별 CCTV 설치 현황 데이터: "01. CCTV_in_Seoul.csv"
<변수 설명>
기관명: 강남구, 강동구, 강북구, ...
소계: 설치된 CCTV 개수의 총합
2013년도 이전: 2013년도 이전에 설치된 CCTV 개수
2014년: 2014년에 설치된 CCTV 개수
2015년: 2015년에 설치된 CCTV 개수
2016년: 2016년에 설치된 CCTV 개수
- 서울시 인구 통계 현황 데이터: "01. population_in_Seoul.xls"
<변수 설명>자치구: 강남구, 강동구, 강북구, ...
계: 인구 총 합계
계.1: 한국인 인구 총 합계
계.2: 외국인 인구 총 합계
65세이상고령자: 65세 이상 고령자 인구 수
- read_csv : csv 파일을 읽는 명령
- 한글이 포함되어 있을 경우 encoding='utf-8' 옵션을 사용
import pandas as pd
# .. : 부모 디렉터리
# . : 현재 디렉터리
CCTV_Seoul = pd.read_csv("../data/01. Seoul_CCTV.csv", encoding="utf-8")
# 데이터의 상위 5개 데이터
# 데이터의 개수를 입력하여 원하는 만큼 볼 수 있다.
CCTV_Seoul.head()
# 데이터의 하위 5개 데이터
# 데이터의 개수를 입력하여 원하는 만큼 볼 수 있다.
# CCTV_Seoul.tail()
- read_excel : 엑셀 파일을 읽는 명령
pop_Seoul = pd.read_excel("../data/01. Seoul_Population.xls")
pop_Seoul.head()
- inplacerename, drop등의 메서드를 사용할 때, 변경 값(변경될 데이터 프레임)을 저장 할 때 사용inplace = True (저장함)
- inplace = False (저장 안 함)
4. 데이터 분석
- 경향을 파악할 필요
- 단순 CCTV 수
- 인구대비 CCTV 수
- 전체 경향을 함께 보지 않으면 데이터를 제대로 이해하기 어렵다
- CCTV 증가율 데이터 추출
CCTV_Seoul = pd.read_csv("../data/01. Seoul_CCTV.csv", encoding="utf-8")
CCTV_Seoul.rename(columns={CCTV_Seoul.columns[0] : "구별"}, inplace=True)
CCTV_Seoul['최근증가율'] = (CCTV_Seoul['2016년'] + CCTV_Seoul['2015년'] + \
CCTV_Seoul['2014년']) / CCTV_Seoul['2013년도 이전'] * 100
CCTV_Seoul.sort_values(by='최근증가율', ascending=False).head(5)
- 인구 데이터 추출
pop_Seoul = pd.read_excel(
"../data/01. Seoul_Population.xls", header=2, usecols="B, D, G, J, N"
)
pop_Seoul.rename(
columns={
pop_Seoul.columns[0] : "구별",
pop_Seoul.columns[1] : "인구수",
pop_Seoul.columns[2] : "한국인",
pop_Seoul.columns[3] : "외국인",
pop_Seoul.columns[4] : "고령자",
},
inplace=True,
)
pop_Seoul.head()
- 첫 행인 '합계' 행은 필요없으므로 삭제
pop_Seoul.drop([0], axis=0, inplace=True)
pop_Seoul.head()
- 외국인, 고령자 비율 추가
pop_Seoul["외국인 비율"] = pop_Seoul["외국인"] / pop_Seoul["인구수"] * 100
pop_Seoul["고령자 비율"] = pop_Seoul["고령자"] / pop_Seoul["인구수"] * 100
pop_Seoul.head()
- 데이터 병합
data_result = pd.merge(CCTV_Seoul, pop_Seoul, on='구별')
data_result.head()
- 상관분석(Correlation Analysis) 확률론과 통계학에서 두 변수 간에 어떤 선형적 관계를 갖고 있는 지를 분석하는 방법이다. 두 변수는 서로 독립적인 관계이거나 상관된 관계일 수 있으며 이때 두 변수간의 관계의 강도를 상관관계라 한다. 단, 상관관계가 있다하여 두 변량이 인과관계인 것은 아니다.
- 이 프로젝트의 주제는 인구대비 상대적으로 CCTV가 적은 구를 찾는 것corr() : correlation의 축약형으로 상관관계를 계산하는 함수
- 상관계수를 조사해 0.2 이상의 데이터를 비교
del data_result["2013년도 이전"] del data_result["2014년"] del data_result["2015년"] del data_result["2016년"] data_result.corr()
- Pandas에서 상관관계를 계산하는 함수
- 인구 데이터와 CCTV는 상관관계가 있는가?
- 인구수 대비 CCTV 비율 추가, 인덱스 삭제
4. 데이터 시각화
- 구별 CCTV 비율 바
def drawGraph(): data_result["CCTV 비율"].sort_values().plot( kind = "barh", grid = True, title = "구별 CCTV 비율", figsize=(10, 10) ) drawGraph()
데이터 경향 직선으로 표현
Linear Regression(선형회귀) 이라고도 한다.
경향선을 그리기 위해 X 데이터 생성
- fx = np.linspace(a, b, n) : a부터 b까지 n개의 동간격 데이터 생성
- p = polyfit(x,y,n)은 y의 데이터에 대한 최적의 피팅(최소제곱 관점에서)인 n차 다항식 p(x)의 계수를 반환
- poly1d : 1차원 방정식 형태 반환
import numpy as np
fp1 = np.polyfit(data_result["인구수"], data_result["소계"], 1)
f1 = np.poly1d(fp1)
fx = np.linspace(100000, 700000, 100)
def drawGraph():
plt.figure(figsize=(14,10))
plt.scatter(data_result["인구수"], data_result["소계"], s = 50)
plt.plot(fx, f1(fx), ls="dashed", lw=3, color="g")
plt.xlabel("인구수")
plt.ylabel("CCTV")
plt.grid()
plt.show()
drawGraph()
- 강조를 위해 color map 사용자 정의로 설정
fp1 = np.polyfit(data_result['인구수'], data_result['소계'], 1)
f1 = np.poly1d(fp1)
fx = np.linspace(100000, 700000, 100)
data_result['오차'] = np.abs(data_result['소계'] - f1(data_result['인구수']))
df_sort = data_result.sort_values(by='오차', ascending=False)
plt.figure(figsize=(14,10))
plt.scatter(data_result['인구수'], data_result['소계'],
c=data_result['오차'], 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.98,
df_sort['구별'][n], fontsize=15)
plt.xlabel('인구수')
plt.ylabel('인구당비율')
plt.colorbar()
plt.grid()
plt.show()
- 서울시에서 다른 구와 비교했을 때, 강남구, 양천구, 서초구, 은평구는 CCTV가 많지만,
- 송파구, 강서구, 도봉구, 마포구는 다른 구에 비해 CCTV 비율이 낮다
- 특히 주의깊게 살펴볼 점은 '강남구'는 다른 구들에 비해 월등히 많은 CCTV가 설치되었지만, '송파구'의 경우에는 많은 인구 수에 비해 CCTV가 굉장히 적게 설치되어 있다
- '송파구'에 CCTV가 적게 설치되어 있는 특별한 이유라도 있는 것일까?
5. 결과
- 상관관계를 파악해 인구수 대비 CCTV의 수가 의미있음을 확인
- 인구수 대비 CCTV 수의 비율을 계산해 scaater로 표현
- 경향선을 계산해 각 구별 경향 파악 및 시각화
- 완성한 데이터 저장
- to_csv : DataFrame을 csv파일로 저장
'데이터 분석' 카테고리의 다른 글
2. 서울시 범죄 현황 분석 (0) | 2022.02.15 |
---|---|
카카오 API, Folium 다루기 (0) | 2022.02.15 |
판다스 매트플롯 다루기 (0) | 2022.02.15 |
환경 설정 (0) | 2022.02.15 |
카카오 지도 API 발급 받는 방법 (0) | 2022.01.16 |
Comments