Box-Cox变换是Box和Cox在1964年提出的一种广义幂变换方法,是统计建模中常用的一种数据变换,用于连续的响应变量不满足正态分布的情况。Box-Cox变换之后,可以一定程度上减小不可观测的误差和预测变量的相关性。Box-Cox变换的主要特点是引入一个参数,通过数据本身估计该参数进而确定应采取的数据变换形式,Box-Cox变换可以明显地改善数据的正态性、对称性和方差相等性,对许多实际数据都是行之有效的。
但是当我们遇到双峰性数据时,使用box-cox方法进行处理,处理出来的效果往往是不理想的,因此我们需要换方法。通过数据处理发现 sklearn.preprocessing.QuantileTransformer 这个方法处理双峰性数据的效果非常好,因此我们接下来讲讲这种方法的具体使用,以及对处理后的数据进行正态性检验,以及查看峰度和偏度,以及q-q图。
接下来我们先了解一下sklearn.preprocessing.QuantileTransformer 这个方法。
此方法将要素转换为遵循均匀或正态分布。因此,对于给定的特征,此变换趋向于散布最频繁的值。它还减少了(边际)离群值的影响:因此,这是一个可靠的预处理方案。
变换独立应用于每个功能。首先,特征的累积分布函数的估计值用于将原始值映射到均匀分布。然后使用关联的分位数函数将获得的值映射到所需的输出分布。低于或高于拟合范围的新数据/看不见数据的特征值将映射到输出分布的边界。请注意,此变换是非线性的。它可能会扭曲以相同比例尺测量的变量之间的线性相关性,但会使以不同比例尺测量的变量更直接可比。
好了,接下来,我们进入实战
我们以 2022 SAS中国高校数据分析大赛 复赛题目-农产品期货 数据为例子
首先导入数据
import pandas as pd
import numpy as np
from scipy import stats
import matplotlib.pyplot as plt
f = pd.read_csv(r'C:\Users\bai\Desktop\2022 SAS中国高校数据分析大赛 复赛题目-农产品期货\2022 SAS中国高校数据分析大赛 复赛题目-农产品期货\玉米期货2005-2021日线数据\Corn_dat.csv')
f.head() #查看数据
导入画图库,查看原始数据的分布
import seaborn as sns
sns.set() #切换到sns的默认运行配置
sns.displot(f['High']) #画直方图
画q-q图
res=stats.probplot(f['High'],plot=plt) #画q-q图
参数检验,p值,偏度与峰度
u = f['High'].mean() #求均值
std = f['High'].std() #求方差
result = stats.kstest(f['High'],'norm',(u,std)) #正态分布检验
print(result) #输出结果,pvalue大于0.05才满足正态分布
print(f"Skewness of saleprice: {f['High'].skew()}")
print(f"Kurtosis of saleprice: {f['High'].kurt()}")
导入机器学习库,对数据进行处理
from sklearn.preprocessing import QuantileTransformer #导入sklearn 分位数转换器 将双峰数据正态化
x=QuantileTransformer(n_quantiles = 300,output_distribution='normal', random_state=0) #初始化参数
#f['High'].values.reshape(-1,1) 由于在sklearn中,所有的数据都应该是二维矩阵,哪怕它只是单独一行或一列
#(比如前面做预测时,仅仅只用了一个样本数据),所以需要使用.reshape(1,-1)进行转换
high = x.fit_transform(f['High'].values.reshape(-1,1)) #调用分位数转换器,将数据进行转换
high.flatten() #将二维数据降维回来,以便后面画图
f['high']=high #将正态化的数据写入表
f.head() #查看处理后的数据
画处理后的直方图
sns.displot(f['high']) #画正态分布图
画q-q图
res=stats.probplot(f['high'],plot=plt) #画q-q图
输出检验参数
u = f['high'].mean() #求均值
std = f['high'].std() #求方差
result = stats.kstest(f['high'],'norm',(u,std)) #正态分布检验
print(result) #输出结果,pvalue大于0.05才满足正态分布
print(f"Skewness of saleprice: {f['High'].skew()}")
print(f"Kurtosis of saleprice: {f['High'].kurt()}")
将原始数据还原回来,方便数据分析
fhigh = x.inverse_transform(high) #将原始数据还原回来,进行数据分析
print(fhigh)
还原回来后和原数据相同。
接下来就可以进行其他分析啦!!!