본문 바로가기
Python/데이터 분석

(1) 척도 조절

by 지식광부키우기 2019. 8. 22.

대다수의 데이터 과학 기법은 데이터의 척도(scale)에 민감하게 반응합니다.

 

데이터 과학자 수백 명의 키와 몸무게가 주어졌고, 이를 통해 체형을 군집화해야 한다고 가정해봅시다.

 

직관적으로, 서로 가까운 데이터는 같은 군집에 포함되어야 하고 그러기 위해서는 데이터 간의 거리를 정의할 필요가 있습니다. 

 

사람 키(인치) 키(cm) 몸무게(파운드)
A 63 160 150
B 67 170.2 160
C 70 177.8 171

 

유클리드 거리 함수를 사용하여 비슷한 체형을 구해보면

 

1. 키(인치)를 사용하면, B와 가장 비슷한 체형을 갖고 있는 사람은 A입니다.

 

a_to_b = distance(63, 150, 67, 160) # 10.77
a_to_c = distance(63, 150, 70, 171) # 22.14
b_to_c = distance(67, 160, 70, 171) # 11.40

하지만 키(cm)를 사용하면, B와 가장 비슷한 체형을 갖고 있는 사람은 C입니다.

a_to_b = distance(160, 150, 170.2, 160) # 14.28
a_to_c = distance(160, 150, 177.8, 171) # 27.53
b_to_c = distance(170.2, 160, 177.8, 171) # 13.37

이렇게 각 차원(열)의 수치가 크게 다른 경우, 각 차원의 평균을 0, 표준편차를 1로 변한시켜 척도를 조절해 주어야 합니다. 척도를 조절해 주면 단위는 제거되며, 각 차원은 "평균으로부터 몇 표준편차만큼 떨어져 있는지"로 변환됩니다.

def scale(data_matrix):
    """각 열의 평균과 표준편차를 반환"""
    num_rows, num_cols = shape(data_matrix)
    means = [mean(get_column(data_matrix,j))
             for j in range(num_cols)]
    stdevs = [standard_deviation(get_column(data_matrix,j))
              for j in range(num_cols)]
    return means, stdevs
def rescale(data_matrix):
    """각 열의 평균을 0, 표준편차를 1로 변환하면서
    입력되는 데이터의 척도를 조절
    편차가 없는 열은 그대로 유지"""
    means, stdevs = scale(data_matrix)

    def rescaled(i, j):
        if stdevs[j] > 0:
            return (data_matrix[i][j] - means[j]) / stdevs[j]
        else:
            return data_matrix[i][j]

    num_rows, num_cols = shape(data_matrix)
    return make_matrix(num_rows, num_cols, rescaled)

위의 표에서의 data를 적용해보겠습니다.

data_matrix = [[63, 160, 150], [67, 170.2, 160], [70, 177.8, 171]]
print(scale(data_matrix))
# ([66.66666666666667, 169.33333333333334, 160.33333333333334], [3.511884584284246, 8.931591870060647, 10.503967504392486])
print(rescale(data_matrix))
#[[-1.0440737953277504, -1.0449798276855173, -0.9837552647618352], [0.09491579957524855, 0.09703384114222419, -0.03173404079876975], [0.9491579957524977, 0.9479459865432901, 1.0154893055606022]]

data_matrix2 = rescale(data_matrix)
a_to_b = distance(data_matrix2[0][0], data_matrix2[0][2], data_matrix2[1][0], data_matrix2[1][2]) # 1.48
a_to_c = distance(data_matrix2[0][0], data_matrix2[0][2], data_matrix2[2][0], data_matrix2[2][2]) # 2.82
b_to_c = distance(data_matrix2[1][0], data_matrix2[1][2], data_matrix2[2][0], data_matrix2[2][2]) # 1.35

a_to_b = distance(data_matrix2[0][1], data_matrix2[0][2], data_matrix2[1][1], data_matrix2[1][2]) # 1.48
a_to_c = distance(data_matrix2[0][1], data_matrix2[0][2], data_matrix2[2][1], data_matrix2[2][2]) # 2.82
b_to_c = distance(data_matrix2[1][1], data_matrix2[1][2], data_matrix2[2][1], data_matrix2[2][2]) # 1.35

척도를 조절하니 결과가 같아졌다.

척도 조절은 '단위'를 제거해주는 중요한 역할을 한다는 것을 잊지 않았으면 좋겠습니다.

 

이 글의 출처는 data science from scratch o'reilly입니다.

'Python > 데이터 분석' 카테고리의 다른 글

단순 회귀 분석  (0) 2019.09.02
(2) 차원 축소  (0) 2019.08.26

댓글