1. 기술통계 구하기
- 기술통계(descriptive statistics)는 자료의 내용을 압축하여 설명하는 방법을 말한다,
- ns_book6.csv 파일을 데이터프레임으로 불러 온 후 처음 다섯 개 행을 출력
import pandas as pd
ns_book6 = pd.read_csv('ns_book6.csv', low_memory=False)
ns_book6.head()
- 판다스는 데이터프레임에서 기본적인 몇 가지 기술통계를 자동으로 추출해주는 describe() 메서드를 제공한다.
ns_book6.describe()
- describe() 메서드는 기본적으로 수치형 열에 대한 요약 통계를 보여준다.
count | 누락된 값을 제외한 데이터 개수 |
mean | 평균 |
std | 표준편차 |
min | 최솟값 |
50% | 중앙값 |
25% | 순서대로 늘어 놓았을 때 25% 지점 |
75% | 순서대로 늘어 놓았을 때 75% 지점 |
max | 최댓값 |
- 이상한 점은 도서권수 최솟값이 0이다.
- 불리언 배열과 sum() 함수를 활용하면 도서권수가 0인 도서의 행 개수를 쉽게 카운트 할 수 있다.
sum(ns_book6['도서권수']==0)
- 실제로 없는 도서 대출 데이터는 의미가 없다고 생각하여 제외
ns_book7 = ns_book6[ns_book6['도서권수']>0]
- describe() 메서드는 기본적으로 데이터의 25%, 50%, 75%에 위치한 값을 보여준다.
- 원하는 위치의 값을 보고 싶다면 percentiles 매개변수에 위치를 지정하면 된다.
ns_book7.describe(percentiles=[0.3, 0.6, 0.9])
- 열의 데이터 타입이 수치가 아닌 다른 데이터 타입의 열의 기술 통계를 보고 싶다면 include 매개변수에 데이터 타입을 지정할 수 도 있다.
ex) object 타입의 열에 대한 통계
ns_book7.describe(include='object')
- count 행은 누락된 값을 제외한 데이터 개수를 나타내고, unique 행은 고유한 값의 개수를 나타낸다.
- top 행은 가장 많이 등장하는 값을 나타낸다.
- freq 행은 top 행에 등장하는 항목의 빈도수이다.
1) 평균 구하기
- 판다스 데이터프레임과 시리즈 객체는 평균을 계산하는 mean() 메서드를 제공한다.
ns_book7['대출건수'].mean()
2) 중앙값 구하기
- 중앙값(median)은 전체 데이터를 순서대로 늘어 놓았을 때 중앙에 위치한 값
- 판다스는 중앙값을 구하기 위한 메서드로 median() 메서드를 제공한다.
ns_book7['대출건수'].median()
- 데이터가 홀수일 때는 중앙값을 결정하기 슆다. 정확히 가운데 놓은 값을 찾으면 된다.
- 데이터가 짝수일 때는 가운데 두 개의 값을 평균하여 중앙값을 결정한다.
temp_df = pd.DataFrame([1,2,3,4])
temp_df.median()
중복값 제거하고 중앙값 구하기
- 같은 값의 대출건수를 모두 제외하고 중앙값을 계산할 수 있다.
- drop_duplicates() 메서드를 사용해 '대출건수'열에서 중복된 값을 가진 행을 제거한 후 중앙값 구하기
ns_book7['대출건수'].drop_duplicates().median()
3) 최솟값, 최댓값 구하기
- 판다스에서는 각각 min() 메서드와 max() 메서드를 제공한다.
ns_book7['대출건수'].max()
ns_book7['대출건수'].min()
4) 분위수 구하기
- 분위수(quantile)은 데이터를 순서대로 늘어 놓았을 때 이를 균등한 간격으로 나누는 기준점
- 사분위수(quartile)는 정렬된 데이터를 네 구간으로 나눈다.
quantile() 메서드
- 판다스에서 분위수 값을 계산할 때는 quantile() 메서드를 사용한다.
- 하위 25%에 위치한 값을 출력하려면 0.25를 입력한다.
ns_book7['대출건수'].quantile(0.25)
- quantile() 메서드에 여러 개의 분위수를 지정할 수도 있다.
ns_book7['대출건수'].quantile([0.25,0.5,0.75])
- 이처럼 quantile() 메서드에 여러 개의 분위수를 지정하면 각 분위수에 해당하는 값을 담은 시리즈 객체를 반환한다.
- 1,2,3,4,5 다섯 개의 숫자가 있을 때 90% 위치에 있는 값은 4.6이 나온다.
pd.Series([1,2,3,4,5]).quantile(0.9)
- quantile() 메서드는 interpolation 매개변수에서 중간 값을 계산하는 방법을 결정한다. 위 코드는 interpolation 매개변수를 따로 지정하지 않아서 기본값으로 계산되었다.
- 기본값은 'linear'로 양쪽 분위수에 비례하여 결정된다.
- 두 지점 사이에 놓인 특정 위치의 값을 구하는 방법을 보간(interpolation)이라고 한다.
백분위 구하기
- '대출건수' 열의 값이 10보다 작은지 비교하여 불리언 배열을 만든다.
borrow_10_flag = ns_book7['대출건수'] < 10
- 이렇게 변환한 borrow_10_flag 배열에서 True인 개수를 모두 헤아린 후 전체 데이터 개수로 나누면 10보다 작은 대출 건수의 비율을 얻을 수 있다.
- 판다스에서 불리언 자료를 산술 연산하면 True는 1, False는 0으로 취급한다. 따라서 다음처럼 borrow_10_flag 배열에서 mean() 메서드를 호출하여 평균을 구하면 10보다 작은 값이 차지하는 비율을 간단히 얻을 수 있다.
borrow_10_flag.mean()
- 10에 대한 백분위는 0.65 정도가 된다. quantile() 메서드의 백분위를 넣어 직접 확인해보면 기대했던 10이 출력된다.
ns_book7['대출건수'].quantile(0.65)
5) 분산 구하기
- 분산(variance)은 평균으로부터 데이터가 얼마나 퍼져있는지를 나타내는 통계량이다.
- 데이터가 가운데 모여 있다면 분산이 작고 넓게 펴져 있다면 분산이 크다.
- 분산은 데이터의 각 값에서 평균을 뺀 다음 제곱한 후 평균처럼 샘플 개수로 나누어 구할 수 있다.
- 데이터의 각 값에서 평균을 빼면 데이터가 서로 얼마나 멀리 떨어져 잇는지 알 수 있다. 또 제곱하면 음수가 되는 것을 막아서 평균을 중심으로 좌우의 값이 서로 상쇄되지 않도록 만들어 준다.
- 판다스에는 분산을 계산하는 var() 메서드가 있다.
ns_book7['대출건수'].var()
6) 표준편차 구하기
- 표준편차(standard deviation)는 분산에 제곱근을 한 것으로 수식 기호는 s를 사용한다.
- 분산을 계산했다면 표준편차는 제곱근만 씌우면 되기 때문에 간단하다.
- 판다스에서 표준편차를 계산할 때는 std() 메서드를 활용한다.
ns_book7['대출건수'].std()
7) 최빈값 구하기
- 최빈값(mode)는 데이터에서 가장 많이 등장하는 값을 의미한다.
- 판다스에서 mode() 메서드는 최빈값을 계산한다.
ns_book7['도서명'].mode()
- mode() 메서드는 텍스트뿐만 아니라 수치형에도 적용할 수 있다.
- 남산도서관 대출 데이터에서 가장 많이 등장하는 연도가 무엇인지 알아보기
ns_book7['발행년도'].mode()
2. 분포 요약하기
1) 산점도 그리기
- 산점도는 데이터를 화면에 뿌리듯 그리는 그래프이다.
- 두 변수(variable) 혹은 두 가지 특성(feature)값을 직교 좌표계에 점으로 나타내는 그래프이다.
- 2차원 데이터를 나타낼 때 수평축을 x축, 수직축을 y축이라고 한다.
- 파이썬에서 그래프를 그리는 데 사용하는 대표적인 패키지는 맷플롯립(matplotlib)이다.
import pandas as pd
ns_book7 = pd.read_csv('ns_book7.csv', low_memory=False)
ns_book7.head()
- 맷플롯립에서 제공하는 그래프 함수는 matplotlib.pyplot 패키지 아래에 있다.
scatter() 함수
- 산점도는 scatter() 함수로 그린다.
- 첫 번째 매개변수 4개 포인트의 x축 좌표를 전달하고 두 번째 매개변수에 y축 좌표를 전달한다.
- scatter() 함수를 호출한 다음에는 show() 함수를 호출하여 그래프를 출력한다.
import matplotlib.pyplot as plt
plt.scatter([1,2,3,4], [1,2,3,4])
plt.show()
- 남산도서관 대출 데이터를 사용해 산점도를 그리기
- 맷플롯립은 편리하게도 x축과 y축 값으로 데이터프레임의 열을 입력받을 수 있다.
- 남산도서관 대출 데이터 중에서 '번호' 열의 값을 x축에 넣고 '대출건수' 열의 값을 y축에 넣어보겠다.
plt.scatter(ns_book7['번호'], ns_book7['대출건수'])
plt.show()
- 대출건수(y축의 값)은 번호(x축의 값)을 따라 비교적 고르게 퍼져 있다.
- '도서권수'와 '대출건수' 열의 산점도
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'])
plt.show()
- 대부분의 도서가 1~2권이기 때문에 x축 0~10 범위인 왼쪽 아래 모서리 부분에 같은 값을 가진 데이터 포인트가 중첩되서 그려진다. 이럴 때는 산점도에 투명도를 주면 중첩된 데이터 포인트를 가늠하기 좋다.
투명도 조절하기
- 맷플롯립은 alpha 매개변수에 0~1 사이의 값으로 투명도를 지정할 수 있다.
plt.scatter(ns_book7['도서권수'], ns_book7['대출건수'], alpha=0.1)
plt.show()
- 도서권수가 대부분 작은 값이기 때문에 도서권수와 대출건수 사이의 관계를 파악하기 어렵다.
- '도서권수' 열 대신에 '대출건수' 열을 '도서권수'열로 나눈 값을 사용
- 도서권수 당 대출건수를 x축에 두고 대출건수를 y축에 놓는다.
average_borrows = ns_book7['대출건수']/ns_book7['도서권수']
plt.scatter(average_borrows, ns_book7['대출건수'], alpha=0.1)
plt.show()
- 출력된 그래프를 보면 x축(도서권수 당 대출건수)이 증가함에 따라 y축(대출건수)가 증가하는 것을 뚜렷하게 볼 수 있다.
- 두 특성 사이에는 '양의 상관관계가 있다'고 말할 수 있다.
2) 히스토그램 그리기
- 히스토그램은 수치형 특성의 값을 일정한 구간(bin)으로 나누어 구간 안에 포함된 데이터 개수를 막대 그래프로 그린것이다.
- 구간 안에 속한 데이터 개수를 도수(frequency)라고 부른다.
- 히스토그램은 하나의 특성에 대한 분포를 확인하기 좋다.
plt.hist([0,3,5,6,7,7,9,13], bins=5)
plt.show()
hist() 함수
- 맷플롯립으로 히스토그램으로 그릴 때는 hist() 함수를 사용한다. hist() 함수는 1차원 데이터를 입력받아 히스토그램을 그리며, 기본적으로 데이터를 10개의 구간으로 나눈다.
- 8개의 정수로 이루어진 간단한 데이터를 사용한다. bins 매개변수를 5로 지정하여 5개의 구간으로 그리기
plt.hist([0,3,5,6,7,7,9,13], bins=5)
plt.show()
- 히스토그램의 구간을 정확하게 확인하기 위해 넘파이에서 제공하는 histogram_bin_edges() 함수를 사용
- 다섯 구간의 경곗값을 출력
import numpy as np
np.histogram_bin_edges([0,3,5,6,7,7,9,13], bins=5)
- 랜덤한 실수 1000개 데이터를 만들어 히스토그램 그리기
- randn() 함수는 표준정규분포를 따르는 랜덤한 실수를 생성할 수 있다.
- seed() 함수를 사용하면 유사난수(pseudorandom number)를 생성할 수 있다.
np.random.seed(42)
random_samples = np.random.randn(1000)
- random_samples 배열이 표준정규분포를 따르고 있는지 확인하기 위해 평균과 표준편차 계산
print(np.mean(random_samples), np.std(random_samples))
- random_samples의 평균이 약 0.02, 표준편차가 약 0.98이므로 표준정규분포를 따르고 있다고 볼 수 있다.
- 평균이 0, 표준편차가 1에 가까울수록 표준정규분포를 따른다고 볼 수 있다.
- 히스토그램을 그려서 종 모양의 분포가 나오는지 확인해 보면, 다음과 같이 평균 0을 중심으로 볼록한 종 모양의 분포가 그려지는 것을 알 수 있다.
plt.hist(random_samples)
plt.show()
- '대출건수'열의 히스토그램
plt.hist(ns_book7['대출건수'])
plt.show()
구간 조정하기
- 한 구간의 도수가 너무 커서 다른 구간에는 도수가 표시되지 않은 현상이 발생하면 y축을 로그 스케일로 바꾸어 해결할 수 있다
- 로그 스케일(log scale)로 바꾼다는 것은 y축에 로그함수를 적용한다는 의미이다.
- 맷플롯립에서 y축을 로그 스케일로 바꾸려면 다음 처럼 yscale() 함수에 'log'를 지정하면 된다.
- 맷플롯립은 기본적으로 밑이 10인 로그함수를 사용
plt.hist(ns_book7['대출건수'])
plt.yscale('log')
plt.show()
- hist() 함수는 기본 10개 구간을 사용한다. bins 매개변수에서 이를 100으로 바꾸면 데이터 분포를 조금 더 세밀하게 관찰할 수 있다.
plt.hist(ns_book7['대출건수'], bins=100)
plt.yscale('log')
plt.show()
- 대출건수 0이 가장 많고 대출건수가 증가함에 따라 도수가 줄어든다.
- '도서명'열에 apply() 메서드를 사용하여 파이썬의 len() 함수를 적용하면 title_len 변수는 각 도서명의 길이가 저장된 판다스 시리즈 객체가 된다. 이를 100개의 구간을 가진 히스토그램으로 그려보기
title_len = ns_book7['도서명'].apply(len)
plt.hist(title_len, bins=100)
plt.show()
'
- y축에 로그 스케일을 적용했던 것처럼 x축에도 로그스케일을 적용할 수 있다. 이렇게 하면 x축을 따라 작은 값과 큰 값의 차이가 줄어들 것이다. y축에 로그 스케일을 적용하는 yscale() 함수와 비슷하게 xscale() 함수를 사용하면 된다.
plt.hist(title_len, bins=100)
plt.xscale('log')
plt.show()
3) 상자 수염 그림 그리기
- 상자 수염 그림은 최솟값, 세 개의 사분위수, 최댓값 이렇게 다섯 개의 숫자를 이용해 데이터를 요약하는 그래프를 그린다.
상자수염 그리는 방법
- 먼저 사분위수를 계산한다. 25%와 75% 지점을 밑면과 윗면으로 하는 직사각형을 그린다.
- 중간값 즉, 50%에 해당하는 지점에 수평선을 긋는다.
- 사각형의 밑면과 윗면에서 사각형의 높이의 1.5배만큼 떨어진 거리 안에서 가장 멀리 있는 샘플까지 수직선을 긋는다.
- 이 수직선 밖에서 최솟값과 최댓값까지 데이터를 점으로 표시한다. 이 영역의 데이터를 이상치(outlier)라고 부른다.
boxplot 함수
- 맷플롯립에서 상자 수염 그림은 boxplot() 함수로 그린다.
- 한 개 이상의 데이터프레임 열을 전달하여 그래프를 그린다.
temp = ns_book7[['대출건수','도서권수']]
plt.boxplot(temp)
plt.show()
- 상자 수염 그림을 조금 더 보기 좋게 y축을 로그 스케일로 바꾸기
plt.boxplot(ns_book7[['대출건수','도서권수']])
plt.yscale('log')
plt.show()
상자 수염 그림 수평으로 그리기
- boxplot() 함수의 vert 매개변수를 기본값 True에서 False로 바꾸면 되다.
- x-y축이 바뀌므로 로그 스케일도 x축에 지정해야 한다. 히스토그램과 마찬가지로 xscale() 함수를 사용한다.
plt.boxplot(ns_book7[['대출건수','도서권수']], vert=False)
plt.xscale('log')
plt.show()
수염 길이 조정하기
- boxplot() 함수의 whis 매개변수에서 수염 길이를 조정할 수 있다.
- 기본 값 1.5를 10으로 바꾸어서 IQR의 10배 범위 안에서 가장 멀리 떨어진 데이터까지 수염을 그리기
plt.boxplot(ns_book7[['대출건수','도서권수']], whis=10)
plt.yscale('log')
plt.show()
- whis 매개변수는 백분율로도 지정할 수 있다.
- 예를 들어 (10,90)으로 지정하면 10%, 90% 백분위수에 해당하는 데이터까지 수염을 그린다.
plt.boxplot(ns_book7[['대출건수','도서권수']], whis=(0,100))
plt.yscale('log')
plt.show()
'데이터 > 데이터 분석' 카테고리의 다른 글
[혼공] ch 6. 복잡한 데이터 표현하기 (0) | 2024.07.09 |
---|---|
[혼공] ch 5. 데이터 시각화하기 (0) | 2024.07.09 |
[혼공] ch 3. 데이터 정제하기 (0) | 2024.07.04 |
[혼공] ch 2. 데이터 수집하기 (0) | 2024.07.03 |
[혼공] ch 1. 데이터 분석을 시작하며 (1) | 2024.07.03 |