도찐개찐

[데이터분석] 02. 통계와 데이터 본문

PYTHON/데이터분석

[데이터분석] 02. 통계와 데이터

도개진 2023. 1. 2. 12:17
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