통계 분석에 적합한 형태로 데이터를 다듬을 때 흔히 데이터 평활화(data smoothing)라는 방법을 사용합니다. 평활화 과정에서는 일정한 범위, 즉 빈(bin)을 정의하고, 해당 범위 안에 속하는 모든 데이터 값을 그 빈에 포함시킵니다. 이러한 방식을 비닝(binning)이라고 부릅니다. 이 글에서는 비닝의 기본 개념과 예시를 먼저 살펴본 뒤, Python 프로그램으로 비닝을 직접 구현하는 방법까지 단계별로 알아보겠습니다.
비닝 예제로 이해하기
먼저 일련의 숫자들을 준비합니다. 그다음 최댓값과 최솟값을 찾고, 분석에 필요한 데이터 포인트 수에 따라 몇 개의 빈을 만들지 결정합니다. 각 그룹을 생성한 뒤 숫자들을 그룹에 하나씩 할당하는데, 이때 상한값은 해당 그룹에 포함되지 않고 다음 그룹에 속한다는 점에 유의해야 합니다.
예제
주어진 숫자: 12, 32, 10, 17, 19, 28, 22, 26, 29, 16 그룹 수: 4 최댓값: 32 최솟값: 10 따라서 그룹은 다음과 같습니다 – (10-15), (15-21), (21-27), (27-32)
출력 결과
숫자들을 각 빈에 할당하면 다음과 같은 결과를 얻습니다 −
12 -> (10-15) 32 -> (27-32) 10 -> (10-15) 17 -> (15-21) 19 -> (15-21) 28 -> (27-32) 22 -> (21-27) 26 -> (21-27) 29 -> (27-32) 16 -> (15-21)
Python으로 비닝 프로그램 작성하기
이 프로그램에서는 두 개의 함수를 정의합니다. 첫 번째 함수는 하한(lower bound)과 폭(width)을 지정하여 빈을 생성하는 역할을 하고, 두 번째 함수는 입력값을 적절한 빈에 할당하는 역할을 합니다. 각 빈에는 고유한 인덱스가 부여되며, 어떤 입력값이 어느 빈에 들어가는지 확인하고 특정 빈에 몇 개의 값이 할당되었는지도 집계할 수 있습니다.
예제 코드
from collections import Counter
def Binning_method(lower_bound, width, quantity):
binning = []
for low in range(lower_bound, lower_bound + quantity * width + 1, width):
binning.append((low, low + width))
return binning
def bin_assign(v, b):
for i in range(0, len(b)):
if b[i][0] <= v < b[i][1]:
return i
the_bins = Binning_method(lower_bound=50,
width=4,
quantity=10)
print("The Bins: \n",the_bins)
weights_of_objects = [89.2, 57.2, 63.4, 84.6, 90.2, 60.3,88.7, 65.2, 79.8, 80.2, 93.5, 79.3,72.5, 59.2, 77.2, 67.0, 88.2, 73.5]
print("\nBinned Values:\n")
binned_weight = []
for val in weights_of_objects:
index = bin_assign(val, the_bins)
#print(val, index, binning[index])
print(val,"-with index-", index,":", the_bins[index])
binned_weight.append(index)
freq = Counter(binned_weight)
print("\nCount of values in each index: ")
print(freq)
실행 결과
위 코드를 실행하면 다음과 같은 결과를 얻을 수 있습니다 −
The Bins:
[(50, 54), (54, 58), (58, 62), (62, 66), (66, 70), (70, 74), (74, 78), (78, 82), (82, 86), (86, 90), (90, 94)]
Binned Values:
89.2 -with index- 9 : (86, 90)
57.2 -with index- 1 : (54, 58)
63.4 -with index- 3 : (62, 66)
84.6 -with index- 8 : (82, 86)
90.2 -with index- 10 : (90, 94)
60.3 -with index- 2 : (58, 62)
88.7 -with index- 9 : (86, 90)
65.2 -with index- 3 : (62, 66)
79.8 -with index- 7 : (78, 82)
80.2 -with index- 7 : (78, 82)
93.5 -with index- 10 : (90, 94)
79.3 -with index- 7 : (78, 82)
72.5 -with index- 5 : (70, 74)
59.2 -with index- 2 : (58, 62)
77.2 -with index- 6 : (74, 78)
67.0 -with index- 4 : (66, 70)
88.2 -with index- 9 : (86, 90)
73.5 -with index- 5 : (70, 74)
Count of values in each index:
Counter({9: 3, 7: 3, 3: 2, 10: 2, 2: 2, 5: 2, 1: 1, 8: 1, 6: 1, 4: 1})
마무리
이처럼 비닝은 연속형 데이터를 구간별로 묶어 노이즈를 줄이고 통계 분석에 적합한 형태로 만들어 주는 유용한 전처리 기법입니다. 위 예제처럼 빈 생성 함수와 값 할당 함수를 분리해 구현하면, 하한값·폭·빈 개수를 자유롭게 조정하며 다양한 데이터셋에 손쉽게 적용할 수 있습니다. 나아가 pandas의 cut() 함수나 numpy의 histogram()을 활용하면 더욱 간결하게 비닝을 처리할 수도 있으니, 실무에서 함께 활용해 보시길 권장합니다.