기술통계 :: 통계 - mindscale
Skip to content

기술통계

이번 시간에는 기술 통계(descriptive statistics)에 대해서 알아보도록 하겠습니다. 기술 통계는 말 그대로 데이터를 기술하는 통계라고 할 수 있습니다. 여기서 기술은 기록한다, 서술한다라는 의미의 기술입니다.

기술통계에는 대표적으로 중심경향치, 분위수, 변산성 측정치가 있습니다.

  • 중심경향치: 데이터가 어디에 몰려 있는가? 데이터의 중심이 어디인가?
  • 분위수: 어떤 값의 데이터에서 상대적 위치가 어디인가?
  • 변산성 측정치: 데이터가 달라지고(변), 흩어진(산) 정도. 데이터가 얼마나 들쭉날쭉한가?

실습 데이터 열기

중고차 데이터를 다운받아, 작업 폴더에 옮긴 후 다음과 같이 엽니다.

import pandas as pd  # (1)!
df = pd.read_excel('car.xlsx')
  1. pandas 모듈을 임포트한다. 자세한 사용법은 pandas 기초 참고.
df = readxl::read_excel('car.xlsx') # (1)!
  1. readxlread_excel 함수로 파일을 불러온다. readxl이 설치되어 있지 않은 경우 install.packages('readxl')로 설치

범주별 빈도

df.model.value_counts()

중심경향치

평균

평균 같은 경우는 여러분들 다 아시죠. 데이터가 N개도 있으면, 그 합계를 N으로 나눈 것이 평균입니다.

보통 $X$의 평균은 그 위에 줄을 하나 그어서 표기합니다. 읽을 때는 "X 바(bar)"라고 읽습니다.

$$ \bar X $$

예제 데이터에서 price의 평균을 구해봅시다.

df.price.mean()
mean(df$price)

엑셀에서는 AVERAGE 함수로 구할 수 있습니다.

평균은 굉장히 크거나 작은 극단값(outlier)에 영향을 많이 받는 특징이 있습니다. 모든 값을 다 더하니까 굉장히 큰 값이 있으면 합계도 커지고, 굉장히 작은 값이 있으면 합계도 줄어서 결과적으로 평균도 거기에 따라서 커지고 작아지고 하겠죠.

어떤 회사에 직원들이 5명인데 월급을 100만원, 200만원, 300만원, 400만원, 500만원 이렇게 받는다. 평균 내면 300만 원이 되겠죠. 어느 날 이 회사가 돈을 많이 벌었어요. 그런데 500만원 받던 사장님이 직원들은 안 나눠주고 자기만 5천만 원 가져갔어요. 그러면 평균 월급이 1200만원으로 확 뛰겠죠. 하지만 직원들 월급에는 아무 차이도 없습니다. 평균은 굉장히 많이 올라갔지만 실제로 극단값 하나가 탁 튄 것이지 실질적으로는 별 차이가 없습니다. 이것이 평균의 함정입니다.

1986년에 미국의 노스캐롤라이나 대학, UNC라는 대학에서 학과 별로 대졸 초봉을 조사를 했습니다. 여기서 문화지리학과가 평균 25만 달러로 1등을 합니다. 당시 미국 대졸 평균 초봉이 2만 2천 달러 수준이었습니다. 지리학과 졸업생들이 다른 과보다 10배 넘게 많이 받는 것이었습니다. 그런데 사실은 전설적인 농구 선수인 마이클 조던이 그해에 UNC 지리학과를 졸업하고 NBA로 진출을 했습니다. 농구 선수니까 연봉이 어마어마했을 거 아니에요. 지리학과 학생들 연봉에다가 마이클 조던 연봉을 다 더한 다음에 사람 숫자로 나누니까 평균이 크게 나온 것이죠.

중간값

이런 이유로 중심경향치에서 평균과 함께 중간값(median)을 사용합니다. 중간값은 자료를 한줄로 정렬했을 때, 딱 중간에 위치하는 값을 말합니다. 다른 말로는 중위수라고도 합니다. 중간에 위치하는 수. 이런 뜻입니다.

앞의 회사에서 직원들을 월급 순서대로 한 줄로 세우면 300만원 받는 직원이 5명 중에 3번째로 중간에 섭니다. 만약 사장님이 월급을 500만원에서 5000만원으로 더 받아간다고 해도 줄은 그대로이기 때문에 중간값도 똑같습니다. 중간값은 이렇게 극단값에 영향을 받지 않는다는 장점이 있습니다.

가격이나 소득의 경우에는 극단값이 있기 쉽기 때문에, 중간값을 많이 봅니다. 소득의 경우 보통 사람은 몇 백 만원 정도를 받지만 연예인이라든지 기업 임원 같은 분들은 엄청난 돈을 벌죠. 그래서 평균을 내면은 평균 소득은 상당히 높게 잡히게 됩니다. 그래서 소득 통계의 경우에는 평균과 함께 중간값도 같이 봅니다. 신문에서는 흔히 중위소득이라고 표현합니다.2020년 통계로 임금근로자 평균 소득은 월 320만원이고, 중위 소득은 월 242만원입니다. 중위 소득이 더 낮죠? 이런 이유입니다.

그러면 예제 데이터에서 price의 중간값, 중위수를 구해봅시다.

df.price.median()
median(df$price)

엑셀에서 중간값은 MEDIAN 함수로 구할 수 있습니다.

Question

safety.xlsx를 다운로드 받아 width의 평균과 중간값을 구해보세요.

분위수

우리가 보통 어떤 값의 상대적 위치를 나타낼 때는 등수를 사용합니다. 1등, 2등, 3등 이런 식이죠. 그런데 똑같은 10등도 100명 중에 10등과 10명 중에 10등은 의미가 전혀 다릅니다.

그래서 통계에서는 보통 분위수(quantile)를 씁니다. 데이터의 구간을 나누는 위치의 수라는 말입니다. 분위수가 0이면 최소값, 0.5이면 중간값, 1이면 최대값이 됩니다.

소수점이 나오면 읽기가 어려우니까 퍼센타일(percentile)로 표기하기도 합니다. 분위수에 100을 곱하면 됩니다. 0퍼센타일이면 최소값, 50퍼센타일이면 중간값, 100퍼센타일이면 최대값이 됩니다.

우리가 흔히 하위 몇 퍼센트, 상위 몇 퍼센트라고 말하죠. 그 비율을 자르는 선이 퍼센타일이라고 생각하시면 됩니다. 즉, 하위 20퍼센트를 자르는 선이 20퍼센타일입니다. 반대로 상위 10퍼센트면 어떨까요? 90퍼센타일 이상이면 상위 10퍼센트가 됩니다.

통계에서 많이 쓰는 것으로 사분위수(quartile)라는 것이 있습니다. 데이터를 4등분하는 점을 말합니다. 이들 각각의 관계는 아래 표와 같습니다.

분위수 퍼센타일 사분위수
0.25 25퍼센타일 제1사분위수
0.5 50퍼센타일 제2사분위수
0.75 75퍼센타일 제3사분위수

분위수와 사분위수는 영어로 비슷하니까 헷갈리시지 않는 것이 중요합니다. 분위수는 quantile, 사분위수는 quartile로 한 글자가 다릅니다.

사분위수 이외에도 오분위수, 십분위수도 많이 씁니다.

Question

오분위수는 모두 몇 개입니까? 제1오분위수, 제2오분위수, ..는 각각 몇 퍼센타일에 해당합니까?

df.price.max() # 최대값
df.price.min() # 최소값
df.price.quantile(.75)  # 제3사분위수 = 75퍼센타일
max(df$price) # 최대값
min(df$price) # 최소값
quantile(df$price, .75)  # 제3사분위수 = 75퍼센타일

엑셀 함수:

  • 최대값: MAX
  • 최소값: MIN
  • 백분위: PERCENTILE
  • 사분위: QUARTILE

Question

다음 중 값이 다른 것은?

  • 평균
  • 중간값
  • 50퍼센타일
  • 제2사분위수

Question

safety.xlsx에서 width의 최소, 최대, 제3사분위수를 구해보세요.

변산성 측정치

이번 시간에는 데이터의 변산성, 데이터가 얼마나 흩어져 있느냐, 데이터가 얼마나 다양한가를 나타내는 방법을 알아보도록 하겠습니다.

범위

범위(range)는 것은 데이터의 최대값에서 최소값을 뺀 차이입니다. 어떤 회사에서 월급을 가장 많이 받는 사람이 500만원, 가장 적게 받는 사람이 100만원이면 범위는 400만원입니다.

통상적으로 '범위'라고하면 "최소값 ~ 최대값" 이런 식으로 표기를 하는데요, 통계에서는 둘의 차이를 말합니다. 헷갈리시지 않도록 주의하시기 바랍니다.

범위는 극단값이 있으면 굉장히 커집니다. 월급의 예에서 500만원 받던 사람이 5000만원을 받게 되면 범위가 400에서 4900으로 늘어납니다. 이러면 범위가 과장이 되기가 쉽죠.

df.price.max() - df.price.min()
max(df$price) - min(df$price)

IQR

극단값은 아주 크거나 작은 값이기 때문에, 데이터의 양쪽 끝을 어느 정도 잘라내고 범위를 구하면 이런 문제가 완화됩니다. 어느 정도 잘라낼지는 정하기 나름입니다만, 보통 많이 쓰는 방법으로 작은 쪽에서 1/4, 큰쪽에서 1/4씩 잘라내는 방법이 있습니다. 그러면 최소에서 최대까지 범위가 아니라 제1사분위수에서 제3사분위수 간의 범위가 되겠죠. 이것을 사분위간 범위(Inter-Quartile Range), 줄여서 IQR이라고 합니다.

df.price.quantile(.75) - df.price.quantile(.25)
IQR(df$price)

상자 수염 그림

사분위수를 시각화해서 표현한 것을 상자-수염 그림(box and whisker plot)이라고 합니다. 데이터의 제1사분수에서 제3사분위수까지를 상자로 그리고, 제2사분위수인 중간값을 상자 가운데 굵은 선으로 표시합니다. 이 상자의 옆면의 길이는 IQR이 되겠죠.

상자 바깥쪽으로는 제1사분위수까지 최소값까지, 그리고 제3사분위수에서 최대값까지 수염을 그립니다. 그런데 최소값이 너무 작거나, 최대값이 너무 클 경우에는 이를 따로 표시하기 위해서 수염은 IQR의 최대 1.5배까지만 그립니다. 그리고 수염보다 바깥쪽에 있는 값들은 모두 점으로 찍어서 표시합니다.

import seaborn as sns
sns.boxplot(y='price', data=df)
boxplot(df$price)

모델별 가격

sns.boxplot(x='price', y='model', data=df)

분산과 표준편차

통계에서 변산성을 나타낼 때 가장 많이 사용하는 방법은 분산(variance)입니다.

분산은 기본적으로 편차(deviation)에 기반하는데요. 어떤 값과 평균의 차이를 말합니다.

$$ X - \bar X $$

그래서 우리가 원 데이터가 10, 20, 30, 40 이렇게 있면 평균은 25입니다. 그러면 10의 경우 편차는 -15가 됩니다. 30의 경우에는 편차가 +5입니다.

그러면 편차가 전반적으로 얼마나 큰지, 작은지를 하나의 수치로 표현하면 데이터의 변산성을 알 수 있습니다. 편차가 전반적으로 크다는 것은 값들이 평균에서 멀리 떨어져 있다는 것이고, 편차가 전반적으로 작다는 것은 값들이 평균 근처에 몰려있다는 뜻입니다.

Question

값과 평균의 차이를 무엇이라 합니까?

  • 편차
  • 오차
  • 잔차

문제는 편차를 평균 내면 항상 0이 된다는 것입니다. 그래서 편차는 그냥 평균 낼 수는 없습니다. ± 부호를 떼버리면 되는데요, 쉽게 생각할 수 있는 방법이 두 가지가 있죠. 하나는 편차에서 절대값을 씌우는 것입니다.

$$ \vert X - \bar X \vert $$

이렇게 해서 부호를 뗀 편차를 평균 내면 평균절대편차(Mean Absolute Deviation: MAD)라고 합니다. 10, 20, 30, 40의 경우 MAD는 10이 됩니다. 이 방법은 언뜻 보기에는 좋아보이지만 수학적으로 조금 복잡한 문제들이 생겨서 잘 쓰지는 않습니다.

또 하나는 편차를 제곱하는 것입니다. 그러면 모두 +가 되죠.

$$ (X - \bar X)^2 $$

이것을 평균 낸 것을 분산이라고 합니다. 겉보기에는 제곱을 하니까 좀 번잡해보이지만 수학적으로는 오히려 더 좋은 여러 가지 성질이 생깁니다. 사실 제곱도 어차피 컴퓨터가 하는 거니까 우리가 신경쓸 필요는 없어요.

다만 분산은 편차를 제곱해서 평균 낸 것이므로, 전반적으로 크기가 커져 있습니다. 10, 20, 30, 40의 경우 분산은 125나 됩니다. 값이 좀 크죠. 그래서 여기에 루트를 씌워서 제곱근을 구합니다. 분산의 제곱근을 표준편차(Standard Deviation)이라고 합니다.

$$ \text{표준편차} = \sqrt{\text{분산}} $$

10, 20, 30, 40의 표준편차는 $\sqrt 125$으로 11 정도 됩니다.

분산 또는 표준편차는 직관적으로 잘 와닿는 수치는 아닙니다. 쉽게 이해하는 한 가지 방법은 보통 표준편차의 ±2~3배 정도에 대부분의 데이터가 포함됩니다. 10, 20, 30, 40의 경우에도 평균 25에서 표준편차 11의 2배를 하면 22를 더하거나 빼보면 3~47이 됩니다. 이 안에 모두 들어가죠? 그런데 이것은 반드시 성립하는 규칙은 아니기 때문에, 대략 이런 정도라는 느낌으로만 이해하시면 됩니다.

df.price.var() # 분산
df.price.std() # 표준편차
var(df$price) # 분산
sd(df$price) # 표준편차

엑셀 함수:

  • 분산: VAR
  • 표준편차: STDEV

Question

safety.xlsx에서 width의 IQR과 표준편차를 구해보세요.

Question

데이터 A는 10, 20, 30, 40, 50이고 데이터 B는 10, 30, 30, 30, 50라고 할 때 둘의 변산성측정치에는 어떤 차이가 있겠습니까?

  • A의 범위가 B의 범위보다 작다
  • A의 범위가 B의 범위보다 크다
  • A의 분산이 B의 분산보다 작다
  • A의 분산이 B의 분산보다 크다

기술통계 한 번에 구하기

df.price.describe()

히스토그램

import seaborn as sns
sns.histplot(x='price', data=df)

막대의 개수를 30개로

sns.histplot(x='price', data=df, bins=30)

200 간격으로

import matplotlib.pyplot as plt
xs = list(range(100, 2100, 200))
sns.histplot(x='price', data=df, bins=xs)
plt.xticks(xs)

커널밀도추정

sns.histplot(x='price', data=df, kde=True)