데이터를 분석할 때 제일 먼저 확인하는 것이 데이터를 대표하는 값, 대푯값입니다.
대푯값에는 평균, 중앙값, 최빈값을 비롯하여 사분위수와 분산, 표준 편차 등이 있습니다.
평균
평균은 데이터의 합을 데이터 개수로 나눈 값이죠.
파이썬에서는 sum 함수로 합계를 구할 수 있고 len 함수로 데이터 개수를 구할 수 있습니다.
*랜덤한 수를 사용하므로 실험 결과는 다를 수 있습니다.*
[In]
import random
data = [random.randint(1,100) for _ in range(100)] #1~100 사이의 랜덤한 100개의 수 발생
print(data)
[Out]
[94, 76, 73, 31, 56, 84, 18, 8, 75, 66, 76, 92, 85, 16, 58, 98, 83, 93, 49, 63, 26, 95, 69, 84, 83, 46, 81, 40, 5, 39, 49, 46, 18, 27, 10, 40, 53, 24, 71, 61, 64, 58, 37, 36, 39, 60, 27, 97, 82, 44, 95, 72, 35, 67, 68, 57, 41, 2, 66, 36, 75, 94, 57, 65, 44, 62, 20, 62, 93, 11, 38, 7, 82, 70, 46, 7, 37, 35, 47, 42, 43, 56, 58, 63, 88, 57, 83, 28, 53, 5, 51, 84, 10, 40, 10, 16, 85, 40, 22, 100]
[In]
print(f"합계:{sum(data)}, 개수:{len(data)}")
print("평균:",sum(data)/len(data))
[Out]
합계:5330, 개수:100
평균: 53.3
데이터의 참인 값이 있다고 가정했을 때 평균은 가장 적합한 값입니다.
평균은 모든 데이터와 차이의 합계가 최소인 값이기 때문이죠.
평균은 모든 데이터와 차이의 합계가 최소인 값
중앙값
중앙값은 데이터를 크기 순으로 나열하였을 때 가장 중앙에 위치한 값을 말합니다.
다음은 데이터의 개수가 홀수일 때와 짝수일 때 중앙값을 구하는 식입니다.
아래의 코드처럼 다른 값들과 확연한 차이가 나는 값(이상치)이 있을 때 평균은 이상치에 영향을 많이 받습니다.
*랜덤한 수를 사용하므로 실험 결과는 다를 수 있습니다.*
[Code]
import random
data = [random.randint(1,100) for _ in range(100)] #1~100 사이의 랜덤한 100개의 수 발생
data.append(12000) #다른 값들과 확연히 차이가 나는 값(12000)을 추가
print(data)
[Out]
[64, 8, 61, 51, 67, 7, 41, 47, 79, 70, 76, 75, 27, 26, 89, 10, 85, 80, 93, 80, 66, 26, 1, 100, 34, 9, 68, 4, 42, 34, 61, 77, 71, 73, 95, 84, 25, 69, 75, 25, 8, 79, 90, 44, 74, 86, 28, 44, 69, 44, 94, 75, 90, 87, 90, 90, 90, 79, 100, 44, 57, 29, 73, 36, 90, 65, 35, 72, 77, 79, 10, 47, 74, 67, 42, 33, 79, 24, 99, 64, 98, 94, 40, 64, 16, 40, 65, 38, 22, 32, 32, 81, 73, 34, 42, 45, 96, 94, 7, 59, 12000]
[Code]
print(f"합계:{sum(data)}, 개수:{len(data)}")
print("평균:",sum(data)/len(data))
[Out]
합계:17804, 개수:101
평균: 176.27722772277227
이상치를 포함하는 데이터는 중앙값도 같이 표현해 주는 것이 바람직합니다.
파이썬에서 리스트 등에서 인덱스는 0부터 시작하기 때문에 중앙값 구하는 식과 1 차이가 발생합니다.
[Code]
sdata = sorted(data)
dl = len(sdata)
if dl%2 ==0: #개수가 짝수일 때
print("중앙값:",(sdata[dl//2-1] + sdata[dl//2])/2)
else: #개수가 홀수일 때
print("중앙값:",sdata[dl//2])
[Out]
중앙값: 65
최빈값
최빈값은 가장 많이 발생하는 값을 말합니다.
파이썬의 collections 모듈의 Counter 클래스를 이용하면 최빈값을 쉽게 구할 수 있습니다.
[Code]
import random
data = [random.randint(1,10) for _ in range(100)] #1~10 사이의 랜덤한 100개의 수 발생
print(data)
[Out]
[7, 2, 2, 3, 4, 3, 6, 10, 10, 9, 4, 2, 9, 9, 5, 10, 9, 1, 9, 6, 8, 4, 4, 8, 10, 4, 7, 10, 9, 6, 1, 8, 7, 7, 1, 3, 3, 3, 4, 2, 1, 2, 9, 1, 3, 2, 10, 8, 5, 10, 1, 1, 9, 3, 8, 9, 4, 8, 6, 9, 9, 9, 2, 3, 4, 8, 3, 7, 4, 3, 1, 8, 8, 9, 6, 5, 5, 4, 9, 4, 3, 8, 9, 6, 6, 3, 8, 2, 6, 7, 4, 8, 9, 3, 7, 7, 7, 9, 1, 5]
[Code]
from collections import Counter
cnt_data = Counter(data) #카운터 개체 생성
print(cnt_data)
mc = cnt_data.most_common() #빈도수 순서로 배치
print("최빈값:", mc[0][0], " 빈도수:",mc[0][1]) #최빈값과 빈도수를 출력
[Out]
Counter({9: 17, 3: 13, 4: 12, 8: 12, 7: 9, 1: 9, 2: 8, 6: 8, 10: 7, 5: 5})
최빈값: 9 빈도수: 17
4분위수
분위수는 데이터를 크기 순으로 나열하였을 때 4개의 균등 분할하였을 때 1/4(Q1), 1/2(Q2), 3/4(Q3) 위치의 값을 말합니다.
1/2 위치의 값은 중앙값과 일치합니다.
3/4위치의 값과 1/4위치의 값의 차이는 IQR(사분 범위)라고 부르며 이상치를 찾을 때 자주 사용합니다.
다음 그림은 박스플롯으로 4분위값(Q1, Median, Q3)외에 이상치(Outlier)를 표현한 것입니다.
이상치는 Q1 에서 1.5IQR 뺀 값보다 작은 값과 Q3에서 1.5IQR 더한 값보다 큰 값입니다.
다음은 이상치를 포함하는 랜덤한 수를 발생하는 코드입니다.
[Code]
import random
data = []
for _ in range(100):
if random.randint(1,10)>1: #1~10 사이의 랜덤한 수가 1보다 크면(90% 확률)
data.append(random.randint(1,100)) #1~100사이의 랜덤한 수 발생
else: #10% 확률
data.append(random.randint(-500,500)) #-500~500사이의 랜덤한 수 발생(일부 값은 이상치가 발생함)
print(data)
[Out]
[18, 2, 6, 40, 4, 34, 11, 28, 89, 34, 9, 91, 13, 51, 9, 58, 62, 37, 7, 100, 50, 96, 70, 90, -303, 27, 54, 69, 28, 85, 31, -449, 20, 7, 41, 97, 20, 80, 49, 17, 59, 32, 85, 98, 13, 74, 98, 17, 33, 79, 51, 27, 42, 25, 82, 18, 84, 76, 50, 69, 53, 43, 31, 7, 37, 45, 49, 224, 28, -12, 24, 49, 34, 95, 27, 66, 77, 15, 50, 62, 21, 57, 19, 179, 49, 97, 82, 52, 51, 357, 422, 63, 268, 380, 59, 174, 97, 59, 69, 60]
다음 코드는 사분위수를 확인하는 코드입니다.
numpy 모듈의 percentile 함수를 이용하면 사분위수를 쉽게 구할 수 있어요.
[Code]
import numpy as np
Q1 = np.percentile(data,25)
Q3 = np.percentile(data,75)
IQR = Q3-Q1
print("1/4분위수:",Q1)
print("1/2분위수:",np.percentile(data,50))
print("3/4분위수:",Q3)
[Out]
1/4분위수: 26.5
1/2분위수: 50.0
3/4분위수: 77.5
다음은 이상치를 구하는 코드입니다.
[Code]
arr = np.array(data)
under_out = arr<(Q1- 1.5*IQR)
over_out = arr>(Q3 +1.5*IQR)
print("하위 이상치:",arr[under_out])
print("상위 이상치:",arr[over_out])
[Out]
하위 이상치: [-303 -449]
상위 이상치: [224 179 357 422 268 380 174]
분산과 표준편차
분산은 데이터가 얼마나 떨어져 분포하는 지를 나타내는 값입니다. 표준편차는 분산의 제곱근입니다.
numpy 모듈은 var 함수로 분산을 std 함수로 표준편차를 구해줍니다.
[Code]
import random
import numpy as np
data = [random.randint(1,100) for _ in range(100)] #1~100 사이의 랜덤한 100개의 수 발생
print(data)
print(f"분산:{np.var(data):.2f},표준편차:{np.std(data):.2f} ")
[Out]
[42, 16, 24, 48, 83, 43, 66, 48, 73, 61, 25, 36, 77, 56, 78, 67, 17, 85, 55, 62, 10, 13, 33, 25, 55, 56, 54, 89, 24, 82, 63, 24, 52, 86, 7, 91, 13, 24, 90, 85, 48, 56, 35, 100, 92, 69, 87, 26, 71, 95, 76, 7, 37, 53, 39, 41, 54, 3, 30, 28, 65, 61, 82, 29, 48, 96, 10, 73, 56, 48, 69, 22, 96, 99, 35, 27, 52, 59, 80, 95, 18, 75, 62, 38, 47, 20, 36, 99, 4, 78, 87, 22, 67, 29, 18, 87, 47, 45, 33, 19]
분산:720.85,표준편차:26.85