Python

[Python] Z-Score 표준화

Any Developer 2023. 5. 9. 12:20

1. 목표

  - Z-Score 표준화를 통해 표준정규분포를 나타낼 수 있다.

 

2. 도구

 - Google Colaboratory

 

[Python] 데이터 프레임 CSV 파일로 저장하기 (tistory.com)

 

[Python] 데이터 프레임 CSV 파일로 저장하기

1. 목표 - 파이썬에서 처리한 데이터 프레임을 CSV 파일로 반출하는 것을 목표로 한다. 2. 도구 - Google Colaboratory [Python] 표준정규분포(정규분포) 데이터 생성 (tistory.com) [Python] 표준정규분포(정규분

iotcyuty.tistory.com

 

3. 상세 목표 및 시나리오

 - 저장된 데이터 (데이터 프레임) 을 불러와서 Z-Score 컬럼을 생성해 보도록 한다.

 - 사이파이 패키지와 넘파이 패키지에 공식을 이용해서 결과값을 확인해 보도록 한다.

 - 부가적으로 두 기능에 대한 처리 속도를 측정해 보도록 한다.

 

4. 작성 코드

'''
정규분포 Z-Score 구하기
'''

import numpy as np  # 넘파이 임포트
import matplotlib.pyplot as plt  # 맷플롯립.파이플롯 임포트
import pandas as pd  # 판다스 임포트
import scipy.stats as ss  # 사이파이.stats 임포트
import time

df = pd.read_csv('/content/Sample_normaldistribution.csv')

#### 사이파이를 통홰 Z-Score 계산 ####
time_start = time.time()  # 현재 시간

z_ss_a = ss.zscore(df["A"])  # scipy를 통해 Z-Score 를 구함.
z_ss_b = ss.zscore(df["B"])

time_elapse = time.time() - time_start  # 소요시간을 구함.

print("scipy.stats.zscore 소요시간",time_elapse)  # 소요시간을 나타냄.


#### 넘파이 공식을 이용 ####
time_start = time.time()  # 현재 시간

z_np_a = (df["A"] - np.mean(df["A"])) / np.std(df["A"])  ## 넘파이 공식을 이용해서 Z-Score 구함.
z_np_b = (df["B"] - np.mean(df["B"])) / np.std(df["B"])

time_elapse = time.time() - time_start  # 소요시간을 구함.

print("공식을 이용한 계산 소요시간",time_elapse)  # 소요시간을 나타냄.

#### 데이터 프레임 추가를 통한 결과 데이터 비교 ####
df["Z-Score_SS_A"] = z_ss_a
df["Z-Score_NP_A"] = z_np_a
df["Z-Score_SS_B"] = z_ss_b
df["Z-Score_NP_B"] = z_np_b

#### 결과 보기 ####
df.head(20)

 

5. 결과화면

  - 테이블을 보면 알 수 있듯 결과값은 모두 같음을 알 수 있다.

    (scipy.stats 와 numpy 의 mean, std 을 이용하여 공식에 대입하여 구하는 결과가 모두 같다.)

 - 그러나 재미있는 것은 두 연산의 소요 시간인데... 사실 위 결과화면은 소요시간이 두배차이가 나는 것으로 보여지지만 실행할 때 마다 비슷할 때도 있고 어떤 때는 scipy.stats.zscore 메소드 실행이 더 빠른 경우도 있었다. (아래 그림)

 - 어차피 Z-Score 를 구하는 과정이 평균과 표준편차를 구하고 이에 대한 사칙연산으로 구하는 과정일 뿐 특별히 빠른 알고리즘이란게 있을 수 없다.  인터프리터 언어 특성상 Step을 한번 덜 거치는게 속도면에서 더 유리한 것은 사실이다.

 - 그리고 한두번 측정만으로 속도비교를 단정 지을 수 없는 부분이 운영체제 스케쥴링의 매 순간마다 점유 정도가 달라서 사이클 시간이 매번 다를 수 있을 수 있기 때문이다.

 - 그러나 PC 성능면에서 워낙 처리 속도가 빠르기 때문에 딱히 치명적으로 속도차이가 나지 않는다면 코드 해석이 더 쉽게 향후 유지보수면에서 더 수월하게 코드를 작성하는 방향이 옳은 방향인 듯 하다.

 

numpy 공식 압도적 승
numpy 공식 승
scipy 간신히 승

 6. 결과 검증

  - 통계학적으로 Z-Score 정규화를 거쳤으면 평균값이 0, 표준편차가 1로 나타나야 하는 것이 맞고 의심할 여지가 없지만,, 엔지니어는 이를 검증해 보고 싶다.

 - 마치 Forward - Reverse 를 거쳐서 검증을 하듯 결과 내용을 한번 검증하고자 한다.

 

#### 결과검증 ####
print("\n\n")
print("Z-Score_SS_A의 평균값은 ",np.mean(df["Z-Score_SS_A"]),"입니다.",end = "  ||  " )
print("Z-Score_SS_A의 표준편차은 ",np.std(df["Z-Score_SS_A"]),"입니다.")

print("Z-Score_SS_B의 평균값은 ",np.mean(df["Z-Score_SS_B"]),"입니다.",end = "  ||  " )
print("Z-Score_SS_B의 표준편차은 ",np.std(df["Z-Score_SS_B"]),"입니다.")

- 위 코드를 삽입하여 결과값을 화면에 출력한다.

 

  - 평균값은 0에 가깝고 (0.00000000000000147, -0.00000000000000196) , 표준편차는 1.0 이 나온 것을 확인할 수 있다.