robust Z-Sore로 비정규 분포를 표준화하다

18594 단어 Python
표준화는 일반적인min-max normalization 및 Z-Sore 정규화입니다.이번에는 robust Z-Sore를 시도해 상술한 정규화와 비교해 봤다.

min-max normalization


min-max normalization은 데이터를 최소치 0·최대치 1로 만드는 방법으로 다음 공식으로 정규화한다.
x' = \frac{x-min(x)}{max(x)-min(x)}
python에서는 sklearn.preprocessingminmax_scale 또는 MinMaxScaler로 계산할 수 있다.
이 귀일화는 데이터의 분포가 고르다는 것을 전제로 한다.

Z-score Normalization(Standardization)


Z-Sore 정규화는 데이터를 평균 0·분산 1로 만드는 방법으로 다음 공식을 통해 정규화하는 것이다.이 값을 Z-Sore라고 합니다.μ 평균치σ 표준 편차를 나타냅니다.
x' = \frac{x-\mu}{\sigma}
python에서는 sklearn.preprocessingscale 또는 StandardScaler로 계산할 수 있다.
이 귀일화는 데이터 분포를 정적 분포로 전제한다.

고르지 않게 분포하고 정태적으로 분포하지 않을 때는 어떻게 합니까?


실제 데이터에서는 균등분포도, 정규분포도 아닌 경우가 많아 어떻게 해야 할지 조사하던 중 아래 글에서 robust Z-Sore를 발견했다.
루팡z분: 중치와 4분위수, 표준화, 비정규 분포와 편차 포함
(비고) 루팡z 득점으로 이상치 제거
다음은 파이썬이 시도한 것이다.

robust Z-score 설치


robust Z-score에 대한 자세한 내용은 위의 기사를 참조하십시오.다음은 간략하게 설명하고 실시할 것이다.
Z-Sore는 정적 분포를 전제로 하지만 이를 비정상적 분포에 적용하기 위해서는 먼저 평균 분포를 확보해야 한다μ중간값, 표준 편차σ 4분위 범위(IQR)로 대체합니다.
x' = \frac{x-median(x)}{IQR}
이 공식은 sklearn.preprocessingrobust_scale 또는 RobustScaler로 계산할 수 있다.
또한 표준 정적 분포로 설정할 수도 있다.IQR이 표준 정적 분포에 대응하는 것을 표준화 4분의 1 범위(NIQR)라고 하고, IQR을 F(0.75)-F(0.25)=1.3489로 나눈다.(F(x)는 누적 분포 함수의 역함수)
NIQR = \frac{IQR}{1.3489}
아까식 분모를 IQR에서 NIQR로 바꾼 게 바로 robust Z-sore입니다.
robust Z score = \frac{x-median(x)}{NIQR}
상기 내용에 따라 실시하면 다음과 같은 함수로 변한다.

def robust_z(x):
    from sklearn.preprocessing import robust_scale
    from scipy.stats import norm

    coefficient = norm.ppf(0.75)-norm.ppf(0.25)
    robust_z_score = robust_scale(x)*coefficient

    return robust_z_score

세 가지 귀일화의 비교


지금까지 나타난 세 가지 정규화를 비교하고 싶다.
우선, 데이터를 준비한다.균등분포도 정태분포도 아닌 데이터를 원하기 때문에 균등분포와 정태분포를 결합한 데이터를 준비했다.
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from scipy.stats import chisquare, shapiro, norm
from sklearn.preprocessing import minmax_scale, scale, robust_scale

np.random.seed(2020)

# 一様分布と正規分布を結合したデータ。
data = np.concatenate((np.random.uniform(low=5.0, high=10.0, size=100),
                       np.random.normal(loc=5.0, scale=1.0, size=100)))

# ヒストグラムを作画。
fig, axes = plt.subplots()
axes.hist(data)
axes.set_title("Histogram of data")
fig.show()


검정을 통해 이 데이터의 고르지 않은 분포와 비정규 분포를 확인하다.
통일성은 케이 측 검사를 통과했고, 정규성은 (사피로 윌크 검사) 통과했다.
# 度数分布を計算する。
hist_data, _ = np.histogram(data, bins="auto")

# 一様性検定(カイ2乗検定)
_, chisquare_p = chisquare(hist_data)
print("一様性検定(カイ2乗検定)のp値 : {}".format(chisquare_p))

# 正規性検定(シャピロ–ウィルク検定)
_, shapiro_p = shapiro(data)
print("正規性検定(シャピロ–ウィルク検定)のp値 : {}".format(shapiro_p))

결과는 다음과 같다.P값이 모두 0.05보다 작기 때문에 균등분포도 정태분포도 아니라고 할 수 있다.
一様性検定カイ2乗検定のp値 : 3.8086163670115985e-09
正規性検定シャピロウィルク検定のp値 : 8.850588528730441e-06
이 데이터로min-max normalization, Z-sore, robust Z-sore를 계산해 비교한다.
# 各方法で正規化を行い、データフレームに入れる。
score_df = pd.DataFrame(data=np.array([minmax_scale(data), scale(data), robust_z(data)]).T,
                        columns=["min-max", "Z-score", "robust Z-score"])


# グラフを作成
fig, axs = plt.subplots(ncols=3, constrained_layout=True)

# x軸の幅の設定
xrange = {"min-max":(0,1),
          "Z-score":(-2.5,2.5),
          "robust Z-score":(-2.5,2.5)}

# 各ヒストグラムの作画
for i, score_name in enumerate(score_df.columns):

    axs[i].hist(score_df[score_name])
    axs[i].set_title(score_name)
    axs[i].set_xlim(xrange[score_name])

fig.show()
결과는 다음 그림과 같습니다.별 차이가 없다.데이터의 분포 상황에 따라 차이가 있을 수 있습니다.

편차 값이 있는 데이터로 비교하다


원래 robust Z-score의'robust'는 편차값에 비해robust(완고함)이라는 뜻이다.편차 값을 측정하는 데도 robust Z-score가 사용됩니다.
따라서 데이터에 편차값을 넣어 비교하고 싶습니다.비교적 쉽도록 극단적으로 다수의 편차 값을 입력해 보자.
# 外れ値(一様分布)をデータに結合する。
outier = np.concatenate((data,
                         np.random.uniform(low=19.0, high=20.0, size=15)))

# 各方法で正規化を行い、データフレームに入れる。
outlier_df = pd.DataFrame(data=np.array([minmax_scale(outier), scale(outier), robust_z(outier)]).T,
                          columns=["min-max", "Z-score", "robust Z-score"])

# 外れ値なしと外れ値ありのデータフレームを結合。
concat_df = pd.concat([score_df, outlier_df],
               axis=1,
               keys=['without outlier', 'with outlier'])


# グラフを作成
fig, axs = plt.subplots(nrows=2, ncols=3, constrained_layout=True)

# x軸の幅の設定
xrange = {"min-max":(0, 1),
          "Z-score":(-6.5, 6.5),
          "robust Z-score":(-6.5, 6.5)}

# ヒストグラムの作画
for i, (data_name, score_name) in enumerate(concat_df.columns):
    row, col = divmod(i, 3)
    axs[row, col].hist(concat_df[(data_name, score_name)])
    axs[row, col].set_xlim(xrange[score_name])

    title = "\n".join([data_name, score_name])    
    axs[row, col].set_title(title)       

plt.show()
결과는 다음 그림과 같습니다.위에는 편차 값이 없고, 아래에는 편차 값이 있는 경우.
min-max normalization은 편차값에 매우 큰 영향을 미칩니다.Z-Sore도 편차 값의 영향을 받아 편차 값이 없는 경우와 큰 차이가 있다.robust Z-Sore의 편차 값은 영향이 가장 작으며 편차 값이 없는 경우와 비슷합니다.

최후


robust Z-Sore는 데이터가 정규 분포될 때 Z-sore와 결과가 같기 때문에 헷갈리면 robust Z-sore를 사용한다.특히 편차 값을 사용하려면 robust Z-Sore가 효과적일 것 같다.

좋은 웹페이지 즐겨찾기