도찐개찐
[데이터분석] 02. 통계와 데이터 본문
import numpy as np
import pandas as pd
import scipy.stats as sp
변동성 이해하기
- 값들이 서로 얼마나 다른지 여부 파악
nums1 = [7,6,3,3,1]
nums2 = [3,4,4,5,4]
nums3 = [4,4,4,4,4]
print(np.mean(nums1)
,np.mean(nums2)
,np.mean(nums3))
nums_df = pd.DataFrame({'a':nums1, 'b':nums2, 'c': nums3})
nums_df.mean()
4.0 4.0 4.0
a 4.0
b 4.0
c 4.0
dtype: float64
분산경향
- 기술통계의 또 다른 관점 - 분산, 산포
- 데이터가 어떻게 분포되어 있는지 설명하는 통계치
- 자료의 흩어지거나 밀집되는 정도를 나타내는 척도
- 범위
- 사분위수
- 분산
- 표준편차
범위
- 수집한 자료의 가장 큰 값과 작은 값의 차이
- 수집한 자료가 어느정도 흩어져 있는지 살펴볼 수 있는 통계치
- 계산하기 쉽다
- 특이값에 영향을 많이 받는다
- 범위가 동일해도 분산정도는 크게 다를 수 있다
$r = h - l$
$R = x_{(n)} - x_{(1)}$
nums4 = [5,3,2,0,4,0,3,1,1,2]
r = max(nums4) - min(nums4)
print(r)
# nums4 = sorted(nums4)
nums4.sort()
r = nums4[len(nums4) - 1] - nums4[0]
print(r)
5
5
# 조선조 왕들 수명의 범위를 조사
kings = [73,62,45,53,38,16,51,28,37,30,56,30,33,56,
66,54,40,33,59,36,82,48,44,22,32,67,52,]
kings2 = sorted(kings)
r = kings2[len(kings2) - 1] - kings2[0]
r
66
# 대학생 나이의 범위를 조사
studs = [19,18,19,21,20,24,19,19,20,18,21,22,23,21,19,18,22,24,21,18,19,]
r = np.max(studs) - np.min(studs)
r
6
분산
- 평균을 중심으로 밀집되거나 퍼짐 정도를 나타내는 척도
- 모분산 $ \sigma^2 $ : 모집단을 구성하는 모든 자료값과 모평균의 편차제곱에 대한 평균
- 표본분산 $ s^2 $: 표본을 구성하는 모든 자료값과 표본평균의 편차의 제곱합을 n-1로 나눈 수치
- 편차
$(x_{i} - \bar{x})$
- 편차제곱
$(x_{i} - \bar{x})^2$
- 모분산
$ \frac {\sum(x_{i} - \bar{x})^2}{N} $
- 표본분산
$ \frac {\sum(x_{i} - \bar{x})^2}{n-1} $
nums1 = [7,6,3,3,1]
# 평균 계산
mean = np.mean(nums1)
print(mean)
# 편차계산
devi = nums1 - mean
print(devi, np.sum(devi)) # 편차의 합은 0 - 차이가 없어짐
# 편차 제곱
devi = (nums1 - mean) ** 2
print(devi, np.sum(devi)) # 편차의 제곱합은 양수 - 차이가 있음
# 편차의 제곱합을 데이터 갯수로 나눔 분산
print(np.sum(devi) / len(nums1))
4.0
[ 3. 2. -1. -1. -3.] 0.0
[9. 4. 1. 1. 9.] 24.0
4.8
# numpy 에서는 var 함수로 분산 계산
print(np.var(nums1)) # 모분산
print(np.var(nums1, ddof=1)) # 표본분산
4.8
6.0
nums2 = [3,4,4,5,4]
mean = np.mean(nums2)
print(mean)
devi = nums2 - mean
print(devi)
devi **= 2
print(devi)
print(sum(devi) / len(nums2))
print(np.var(nums2))
#
4.0
[-1. 0. 0. 1. 0.]
[1. 0. 0. 1. 0.]
0.4
0.4
nums3 = [4,4,4,4,4]
mean = np.mean(nums3)
devi = nums3 - mean
devi **= 2
print(sum(devi) / len(nums3))
print(np.var(nums3))
0.0
0.0
# 조선조 왕들 수명의 분산 조사
k_age_mean = np.mean(kings)
devi = kings - k_age_mean
devi **= 2
print(sum(devi) / len(kings))
print(np.var(kings))
251.88751714677642
251.88751714677642
# 대학원생들 나이의 분산 조사
st_mean = np.mean(studs)
devi = studs - st_mean
print(devi)
devi **= 2
print(sum(devi) / len(studs))
np.var(studs)
[-1.23809524 -2.23809524 -1.23809524 0.76190476 -0.23809524 3.76190476
-1.23809524 -1.23809524 -0.23809524 -2.23809524 0.76190476 1.76190476
2.76190476 0.76190476 -1.23809524 -2.23809524 1.76190476 3.76190476
0.76190476 -2.23809524 -1.23809524]
3.5147392290249435
3.5147392290249426
# A부서와 B부서 사원의 비상금 분산 조사
def calc_mean(lists):
return sum(lists) / len(lists)
def calc_devi(lists, mean):
return (lists - mean) ** 2
a = [30, 26, 40, 28, 26]
b = [35, 20, 60, 15, 20]
a_mean = np.mean(a)
b_mean = np.mean(b)
a_devi = calc_devi(a, a_mean)
b_devi = calc_devi(b, b_mean)
# b_devi = calc_devi(b, b_mean)
print(sum(a_devi) / len(a))
print(sum(b_devi) / len(b))
print(np.var(a))
print(np.var(b))
27.2
270.0
27.2
270.0
표준편차
- 분산값에 제곱근을 취한 값
- 분산은 편차를 제곱했기 때문에 결과값의 단위 역시 제곱이 됨
- 분산의 단위를 원래 자료의 단위로 전환하기 위해 만든 값
- 모표준편차 $\sigma$
$ \sqrt \frac {\sum(x_{i} - \bar{x})^2}{N} $
- 표본 표준편차 $s$
$ \sqrt \frac {\sum(x_{i} - \bar{x})^2}{n-1} $
nums1 = [7,6,3,3,1]
print(np.sqrt(np.var(nums1)))# 분산된 값의 제곱근을 적용 함으로써 표준 편차를 계산함
print(np.var(nums1))
print(np.std(nums1))
2.1908902300206643
4.8
2.1908902300206643
nums2 = [3,4,4,5,4]
print(np.sqrt(np.var(nums2)))# 분산된 값의 제곱근을 적용 함으로써 표준 편차를 계산함
print(np.var(nums2))
print(np.std(nums2))
0.6324555320336759
0.4
0.6324555320336759
nums3 = [4,4,4,4,4]
print(np.sqrt(np.var(nums3)))# 분산된 값의 제곱근을 적용 함으로써 표준 편차를 계산함
print(np.var(nums3))
print(np.std(nums3))
0.0
0.0
0.0
# 조선조 황들 수명의 표준편차 조사
# 대학원생들 나이의 표준편차 조사
# A부서와 B부서의 표준편차 조사
사분위수
- 데이터를 가장 작은수부터 가장 큰수까지 정렬하였을때 1/4, 2/4, 3/4 위치에 있는 수를 의미
- 이 각각의 수를
1사분위수
,2사분위수
,3사분위수
라고 하는데2사분위수
는 중앙값과 같음- $Q_1$ : 25% 지점
- $Q_2$ : 50% 지점 (중앙값)
- $Q_3$ : 75% 지점
- 때로 위치를 1/100단위로 나눈 경우도 있는데, 이때
백분위수
를 사용함 - 한편, 사분위수를 구하는 방법은 크게 9가지가 존재하는데 대상 데이터의 유형에 따라 적용방법이 다름
- numpy의 percentile함수의 interpolation 속성으로 계산방법을 지정할 수 있음 (nearst, lower, higher, linear, midpoint)
사분위 범위
(IQR, InterQuartile Range)는 제3사분위수에서 제1사분위수 간의 범위사분위 범위
사이의 구간에는 항상 전체 데이터의 '50%'가 포함됨
# numpy 에서는 quantile함수로 사분위수 계산
# quantile(대상, 분위수)
nums = [1,1,2,3,3,3,4,5,5,7,]
print('1사분위수', np.quantile(nums, .25, method='nearest'))
print('2사분위수', np.quantile(nums, .5, method='nearest'))
print('3사분위수', np.quantile(nums, .75, method='nearest')) # 5가 두개 이므로 한개로 판단 후 중앙 계산 3,4 | 5,7
# 먼저, 중앙값(Q2) 계산
# 자료의 갯수가 10이므로 가운데 있는 2개의 3의 평균이 중앙값임 3,3
print(3+3 / 2)
# 중앙값(Q2)을 기준으로 Q1 계산
print(5+5 / 2)
# 중앙값(Q2)을 기준으로 Q3 계산
print(5 - 1.5)
# 사분위수 범이 IQR
1사분위수 2
2사분위수 3
3사분위수 5
4.5
7.5
3.5
nums = [1,3,3,3,4,4,4,6,6]
pos = int((len(nums) + 1) / 2) - 1
q1 = nums[int(pos / 2)]
q2 = nums[pos]
q3 = nums[pos * 2 - int(pos / 2)]
print(q1, q2, q3)
q1 = np.quantile(nums, .25)
q2 = np.quantile(nums, .5)
q3 = np.quantile(nums, .7)
print(q1, q2, q3)
3 4 4
3.0 4.0 4.0
nums = [5,9,1,3,4,1,5,7,6,4,5]
nums_sort = sorted(nums)
print(nums_sort)
pos = int((len(nums_sort) + 1) / 2) - 1
q1 = nums_sort[int(pos / 2)]
q2 = nums_sort[pos]
q3 = nums_sort[pos * 2 - int(pos / 2)]
print(q1, q2, q3)
q1 = np.quantile(nums, .25, method='nearest')
q2 = np.quantile(nums, .5, method='nearest')
q3 = np.quantile(nums, .7, method='nearest')
print(q1, q2, q3)
[1, 1, 3, 4, 4, 5, 5, 5, 6, 7, 9]
3 5 6
3 5 5
변동성을 이용한 특이값 진단
- 대부분의 자료는 중심경향치 주변에 몰려있음
- 변동성 측정치를 이용하면 중심에서 벗어난 정도를 파악할 수 있음
- 평균에서 벗어난 정도를 판단할 때는 표준편차를 사용
- 평균에서 표준편차의 n배 떨어져 있으면 "n 표준편차"와 같이 표현
- 중간값에서 벗어난 정도를 판단할 때는 IQR을 사용
- 중심경향치에서 크게 벗어났다면 특이값으로 의심할 수 있음
# 어떤 카푸치노 판매점들의 5일 동안 오후 4~5시 사이의 판매량 데이터를 보고
# 어느 지점이 판매를 잘하였는지 파악하시오
A = [20,40,50,60,80]
B = [20,45,50,55,80]
sales = pd.DataFrame({'a': A, 'b': B})
print(sales.mean())
print(sales.std())
# print('A평균 :', np.mean(A))
# print('B평균 :', np.mean(A))
# dict_std = {'A': np.std(A), 'B': np.std(B)}
# print('A표준편차 :', dict_std['A'])
# print('B표준편차 :', dict_std['B'])
# min(dict_std, key=dict_std.get)
# if np.std(A) < np.std(B): print('A')
# else: print('B')
a 50.0
b 50.0
dtype: float64
a 22.360680
b 21.505813
dtype: float64
# 사원들의 연봉의 표준편차, 사분위수
emps = pd.read_csv('../data/employees.csv');
# emps = list(emps['SALARY'])
# emps_mean = np.mean(emps)
# emps_devi = (emps - emps_mean) ** 2
# print(np.sqrt(sum(emps_devi) / len(emps)))
# print(np.std(emps))
emps_df = pd.DataFrame(emps['SALARY'])
emps_df.mean()
SALARY 6461.831776
dtype: float64
emps_df.std()
SALARY 3909.579731
dtype: float64
q1, q2, q3 = np.quantile(emps_df, [.25, .5, .75], method='nearest')
q1, q2, q3, q3 - q1
(3100, 6200, 9000, 5900)
728x90
'PYTHON > 데이터분석' 카테고리의 다른 글
[데이터시각화] 04. 막대그래프 (0) | 2023.01.02 |
---|---|
[데이터분석] 03. 데이터 시각화 (0) | 2023.01.02 |
[데이터 분석] 01. 통계와 데이터 (0) | 2023.01.02 |
[Python] 선형회귀 (2) | 2022.12.26 |
인공지능 개념 (0) | 2022.12.26 |
Comments