기술통계는 자료의 내용을 압축하여 설명하는 방법을 의미하며 다른 말로는 요약 통계라고도 부릅니다.
정량적인 수치로 전체 데이터의 특징을 요약하거나 이해하기 쉬운 간단한 그래프를 사용하며 대표적인 통계량에는 평균
, 표준편차
등이 존재
데이터 시각화를 아우르는 이러한 데이터 분석 방법을 탐색적 데이터 분석
이라고 합니다.
3주차에서 만든 ns_book6.csv 파일을 다운로드
import gdown
gdown.download('https://bit.ly/3736JW1', 'ns_book6.csv', quiet=False)
판다스는 기본적은 몇가지 기술통계를 자동으로 추출하는 함수를 제공
import pandas as pd
ns_book6 = pd.read_csv('ns_book6.csv', low_memory=False)
ns_book6.head()
ns_book6.describe()
3천개가 넘는 도서권수가 0이므로 이를 데이터 분석에서 제외할지를 판단해야함, 이때 처리 기준은 해결할 문제에 따라 다르며 이러한 결정이 분석 결과에 큰 영향을 미칠 수도 있다.
// 도서권수 열의 값이 0인 행 개수
sum(ns_book6['도서권수'] == 0)
// 출력
3206
// 도서권수 열의 값이 0인 행 제외
ns_book7 = ns_book6[ns_book6['도서권수'] > 0]
// 30%, 60%, 90% 위치한 값을보고 싶을때
ns_book7.describe(percentiles=[0.3, 0.6, 0.9])
// 열의 타입이 수치가 아닌 다른 데이터 타입의 열의 기술통계 출력
ns_book7.describe(include='object')
ns_book7['대출건수'].mean()
홀수일때 1, 2, 5, 9, 10중에 중앙값은 5, 짝수일때 중앙값은 가운데 두개의 값의 평균을 구하여 중앙값을 결정 1, 2, 3, 4의 중앙값은 2.5
ns_book7['대출건수'].median()
// 출력
11
중복값을 제거한 중앙값이 높아진것을 보아 작은 대출건수가 많음을 확인
ns_book7['대출건수'].drop_duplicates().median()
// 출력
183
ns_book7['대출건수].min()
ns_book7['대출건수].max()
분위수는 데이터를 순서대로 늘어 놓았을 때 이를 균등한 간격으로 나누는 기준점
ns_book6['대출건수'].quantile(0.25)
ns_book6['대출건수'].quantile([0.25, 0.5, 0.75])
1, 2, 3, 4, 5의 90% 위치 값구하기
두 지점 사이에 놓인 특정위치의 값을 구하는 방법을 보간
이라함
// linear 보간 방식
pd.Series([1,2,3,4,5]).quantile(0.9)
// 출력
4.6
// midpoint 보간 방식
pd.Series([1,2,3,4,5]).quantile(0.9, interpolation='midpoint')
// 출력
4.5
// nearest 두 수중에서 가까운 값 선택
pd.Series([1,2,3,4,5]).quantile(0.9, interpolation='nearest')
// 출력
5
// 대출건수 10이 위치한 백분위
borrow_10_flag = ns_book7['대출건수'] < 10
borrow_10_flag.mean()
// 출력
0.6402712530190833
// 확인
ns_book7['대출건수'].quantile(0.65)
평균으로부터 데이터가 얼마나 퍼져있는지를 나타내는 통계량
데이터가 가운데 모여있다면 분산이 작고
, 퍼져있다면 분산이 크다
.
ns_book7['대출건수'].var()
// 출력
371.69563042906674
참고 : 책에서 1,2,3,4,5의 분산을 구하면 2가 나온다고 되어있는데 실제로 코드로 돌려보면 2.5가 나옴….. 찾아보니 분산은 2개의 종류가 있는데 모분산과 표본분산이 있는데 var함수는 표본분산을 이용한것임
책뒤쪽에 나오네..?
데이터 개수가 충분하다면 판다스와 넘파이 계산 결과에 차이가 크지 않기 때문에 분산을 나타날때 모분산인지 표본분산인지 고려할 필요가 없음
표준편차는 분산에 제곱근을 한 것으로 평균을 중심으로 데이터가 대략 얼만큼 떨어져 분포해 있는지 표현하는 값
해석 : 어떤 도서의 대출건수를 확인했을 때 평균보다 19만큼 더 많거나 적을 수 있다는 의미
ns_book6['대출건수'].std()
// 출력
19.241925726324574
데이터에서 가장 많이 등장하는 값을 의미하며 ns_book7.describe(include='object')
의 출력중 top행을 의미
ns_book7['도서명'].mode()
함수 | 기능 |
---|---|
DataFrame.describe() | 데이터프레임의 기술통계량을 출력 |
Series.mean() | 데이터에서 평균 계산 |
numpy.mean() | 입력된 배열의 평균 계산 |
Series.median() | 데이터에서 중앙값을 찾음 |
numpy.median() | 입력된 배열의 중앙값을 찾음 |
Series.quantile() | 데이터에서 분위수를 계산 |
numpy.quantile() | 입력된 배열의 분위수 계산 |
Series.var() | 데이터의 분산을 계산 |
numpy.var() | 입력된 배열의 분산을 계산 |
Series.std() | 데이터의 표준편차를 계산 |
numpy.std() | 입력된 배열의 표준편차를 계산 |
Series.mode() | 데이터에서 최빈값을 찾음 |
데이터를 그림으로 요약할 수 있는 대표적인 그래프 산점도
, 히스토그램
, 상자 수염 그래프
그래프를 그리는데 사용하는 대표적인 패키지
데이터를 화면에 뿌리듯이 그리는 그래프로 두 변수 혹은 두 가지 특성 값을 직교 좌표계에 점으로 나타내는 그래프
변수/특성 : 각 데이터의 열을 의미함
import matplotlib.pyplot as plt
plt.scatter([1,2,3,4], [1,2,3,4])
plt.show()
// alpha는 투명도를 의미 1: 불투명
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
대부분의 도서권수가 작음을 확인할 수 있어서 도서권수와 대출건수 사이의 관계를 파악하기 어려움 즉 도서권수가 많으면 대출건수도 많다던가, 도서권수가 적으면 대출건수가 많다는 식으로 전자는 양의 상관관계
후자는 음의 상관관계
가 있다고 말함
average_borrows = ns_book7['대출건수']/ns_book7['도서권수']
plt.scatter(average_borrows, ns_book7['대출건수'], alpha=0.1)
plt.show()
양의 상관관계(도서권수 당 대출건수)
수치형 특성의 값을 일정한 구간으로 나누어 구간 안에 포함된 데이터 개수를 막대 그래프로 그린것 구간 안에 속한 데이터 개수를 도수(계급)
이라하며 이 구간과 도수를 요약한 것을 도수분포표라고 함
// 데이터를 5개의 구간으로 나눔
plt.hist([0,3,5,6,7,7,9,13], bins=5)
plt.show()
// 구간을 수치로 표현
import numpy as np
np.histogram_bin_edges([0,3,5,6,7,7,9,13], bins=5)
// 출력
array([ 0. , 2.6, 5.2, 7.8, 10.4, 13. ])
// 남산도서관 대출 데이터 히스토그램
plt.hist(ns_book7['대출건수'])
plt.show()
한 구간의 도수가 너무 커서 다른 구간에는 도수가 표시되지 않는 현상이 발생하면 y축을 로그 스케일로 바꾸어 해결할 수 있음, 즉 y축에 로그 함수를 적용함
// hist는 기본적으로 구간을 10개로 나눔
plt.hist(ns_book7['대출건수'])
plt.yscale('log')
plt.show()
plt.hist(ns_book7['대출건수'], bins=100)
plt.yscale('log')
plt.show()
도서명 길이는 정규분포에 가까운지 확인
title_len = ns_book7['도서명'].apply(len)
plt.hist(title_len, bins=100)
plt.show()
왼쪽에 편중된 그래프로 x축에 데이터가 골고루 그려지려면 x축에 로그스케일을 적용
plt.hist(title_len, bins=100)
plt.xscale('log')
plt.show()
최솟값, 세개의 사분위수, 최대값 이렇게 다섯개의 숫자를 사용해 데이터를 요약하는 그래프를 생성
이상치
라고 부름plt.boxplot(ns_book7[['대출건수', '도서권수']])
plt.show()
사분위수가 작아서 직사각형이 거의 보이지 않음, 중간값은 붉은 수평선으로 표시
Y축을 로그 스케일로 변경
// vert가 True면 수직, False면 수평
plt.boxplot(ns_book7['대출건수', '도서권수']], vert=True)
plt.yscale('log')
plt.show()
boxplot메서드의 wish를 이용해 변경
plt.boxplot(ns_book7['대출건수', '도서권수']], whis=10)
plt.yscale('log')
plt.show()
함수 | 기능 |
---|---|
Matplotlib.pyplot.scatter() | 2차원 평면에 산점도 생성 |
Mayplotlib.pyplot.hist() | 히스토그램 생성 |
Mayplotlib.pyplot.boxplot() | 상자 수열 그림 생성 |
Mayplotlib.pyplot.xscale() | x축의 스케일 지정 |
Mayplotlib.pyplot.yscale() | y축의 스케일 지정 |
numpy.random.seed() | 원하는 임의의 정수를 입력하면 난수 발생을 동일하게 재현 |
numpy.random.randn() | 표준정규분포를 따르는 난수 생성 |