Box-Cox轉換


 

1.適用變量

連續的變量不滿足正態分布的情況,一般是對因變量y進行轉換,但是其實連續的自變量也是可以轉換的

 

2.如何判斷變量是否滿足正態分布

#使用ks檢驗:
#導入scipy模塊
from scipy import stats

"""
kstest方法:KS檢驗,參數分別是:待檢驗的數據,檢驗方法(這里設置成norm正態分布),均值與標准差
結果返回兩個值:statistic → D值,pvalue → P值
p值大於0.05,為正態分布
H0:樣本符合  
H1:樣本不符合 
如何p>0.05接受H0 ,反之 
"""
u = s['value'].mean()  # 計算均值
std = s['value'].std()  # 計算標准差
stats.kstest(s['value'], 'norm', (u, std))

 

3.Box-Cox轉換的優勢

Box-Cox變換的目的是為了讓數據滿足線性模型的基本假定,即線性、正態性及方差齊性

 

4.什么時候用Box-Cox

對於非正太數據的轉換方法有:

在一些情況下(P值<0.003)上述方法很難實現正態化處理,所以優先使用Box-Cox轉換,但是當P值>0.003時兩種方法均可,優先考慮普通的平方變換

至於為什么是0.003??

 

 5.知道什么時候使用了,但是參數值怎么選擇

y_boxcox = special.boxcox1p(y, lam_best) 利用llf獲得優化后的lambda或boxcox_normmax(x) 得到優化后的lambda

# -*- coding: utf-8 -*-
"""
Created on Tue Apr 13 09:55:46 2021

@author: Administrator
"""

#導入需要的模塊\n
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
import pycard as pc

train_data =pd.read_csv('D:/迅雷下載/used_car_train_20200313.csv',sep=' ')

#%%計算p值
#使用ks檢驗:
#導入scipy模塊
from scipy import stats

"""
kstest方法:KS檢驗,參數分別是:待檢驗的數據,檢驗方法(這里設置成norm正態分布),均值與標准差
結果返回兩個值:statistic → D值,pvalue → P值
p值大於0.05,為正態分布
H0:樣本符合  
H1:樣本不符合 
如何p>0.05接受H0 ,反之 
"""
u = train_data['price'].mean()  # 計算均值
std =train_data['price'].std()  # 計算標准差
s,p = stats.kstest(train_data['price'], 'norm', (u, std))  #(0.21608994799012532, 0.0)


#%%計算最佳的lambda

from scipy import stats,special

 
lam_range = np.linspace(-2,5,100)  # default nums=50
llf = np.zeros(lam_range.shape, dtype=float)

y = train_data['price']
 
# lambda estimate:
for i,lam in enumerate(lam_range):
    llf[i] = stats.boxcox_llf(lam, y)        # y 必須>0
 
# find the max lgo-likelihood(llf) index and decide the lambda
lam_best = lam_range[llf.argmax()]
print('Suitable lam is: ',round(lam_best,2))
print('Max llf is: ', round(llf.max(),2))
 

y_boxcox = special.boxcox1p(y, lam_best)

# 逆轉換:
y_invboxcox = special.inv_boxcox1p(y_boxcox, lam_best)

#%%畫圖
plt.figure(1)
sns.distplot(train_data['price'])
plt.figure(2)
sns.distplot(y_boxcox)

#%%計算轉換之后的p值
u = y_boxcox.mean()  # 計算均值
std =y_boxcox.std()  # 計算標准差
s,p = stats.kstest(y_boxcox, 'norm', (u, std))  #(0.02719269319870718, 8.643971208421137e-97)

然而經Box-Cox變換后數據是否同時滿足了以上假定,仍需要考察驗證,雖然圖片看着比之前好很多,但是仍然不能不滿足正態分布

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM