高度偏斜特征处理:log(x)、sqrt(x)、box-cox、Yeo-Johnson

一、概念

高度偏斜的特征 : 数据分布不均匀、不对称的特征

处理之后:使其分布更接近正态分布或至少减少偏斜程度

二、处理方法

1、对数变换:log(x)

  • 适用于右偏数据
  • 压缩大值,拉伸小值

2、平方根变换:sqrt(x)

  • 对右偏数据的效果比对数变换温和

3、Box-Cox变换

  • 一种更通用的幂变换方法
  • 可以处理各种程度的偏斜

4、Yeo-Johnson变换

  • Box-Cox的扩展,可以处理负值和零

三、代码

import numpy as np
import matplotlib.pyplot as plt
from scipy import stats
from sklearn.preprocessing import PowerTransformer

# 设置随机种子以确保结果可重现
np.random.seed(42)

# 生成一个右偏(正偏)的数据集
data = np.random.lognormal(mean=0, sigma=1, size=10000)

# 计算关键统计量
min_val = np.min(data)
q1 = np.percentile(data, 25)
median = np.median(data)
q3 = np.percentile(data, 75)
max_val = np.max(data)

print(f"原始数据:")
print(f"最小值: {min_val:.2f}")
print(f"25%分位点: {q1:.2f}")
print(f"中位数: {median:.2f}")
print(f"75%分位点: {q3:.2f}")
print(f"最大值: {max_val:.2f}")
print(f"偏度: {stats.skew(data):.2f}")

# 对数变换
log_data = np.log(data)
# 平方根变换
sqrt_data = np.sqrt(data)
# Box-Cox变换
pt_bc = PowerTransformer(method='box-cox')
boxcox_data = pt_bc.fit_transform(data.reshape(-1, 1)).flatten()
# Yeo-Johnson变换
pt_yj = PowerTransformer(method='yeo-johnson')
yeojohnson_data = pt_yj.fit_transform(data.reshape(-1, 1)).flatten()

# 可视化
plt.figure(figsize=(15, 10))

# 原始数据
plt.subplot(231)
plt.hist(data, bins=50, edgecolor='black')
plt.title(u"原始数据分布",fontproperties=zhfont)
plt.xlabel(u'值',fontproperties=zhfont)
plt.ylabel(u"频率",fontproperties=zhfont)

# 对数变换后的数据
plt.subplot(232)
plt.hist(log_data, bins=50, edgecolor='black')
plt.title("对数变换",fontproperties=zhfont)
plt.xlabel("log(值)",fontproperties=zhfont)
plt.ylabel("频率",fontproperties=zhfont)

# 平方根变换后的数据
plt.subplot(233)
plt.hist(sqrt_data, bins=50, edgecolor='black')
plt.title("平方根变换",fontproperties=zhfont)
plt.xlabel("sqrt(值)",fontproperties=zhfont)
plt.ylabel("频率",fontproperties=zhfont)

# Box-Cox变换后的数据
plt.subplot(234)
plt.hist(boxcox_data, bins=50, edgecolor='black')
plt.title("Box-Cox变换",fontproperties=zhfont)
plt.xlabel("Box-Cox(值)",fontproperties=zhfont)
plt.ylabel("频率",fontproperties=zhfont)

# Yeo-Johnson变换后的数据
plt.subplot(235)
plt.hist(yeojohnson_data, bins=50, edgecolor='black')
plt.title("Yeo-Johnson变换",fontproperties=zhfont)
plt.xlabel("Yeo-Johnson(值)",fontproperties=zhfont)
plt.ylabel("频率",fontproperties=zhfont)

plt.tight_layout()
plt.show()

# 计算变换后的统计量
for name, transformed_data in [("对数变换", log_data), 
                               ("平方根变换", sqrt_data), 
                               ("Box-Cox变换", boxcox_data), 
                               ("Yeo-Johnson变换", yeojohnson_data)]:
    print(f"\n{name}后:")
    print(f"最小值: {np.min(transformed_data):.2f}")
    print(f"25%分位点: {np.percentile(transformed_data, 25):.2f}")
    print(f"中位数: {np.median(transformed_data):.2f}")
    print(f"75%分位点: {np.percentile(transformed_data, 75):.2f}")
    print(f"最大值: {np.max(transformed_data):.2f}")
    print(f"偏度: {stats.skew(transformed_data):.2f}")
    

四、结果

原始数据:
最小值: 0.02
25%分位点: 0.51
中位数: 1.00
75%分位点: 1.96
最大值: 50.72
偏度: 5.83


对数变换后:
最小值: -3.92
25%分位点: -0.67
中位数: -0.00
75%分位点: 0.67
最大值: 3.93
偏度: 0.00

平方根变换后:
最小值: 0.14
25%分位点: 0.71
中位数: 1.00
75%分位点: 1.40
最大值: 7.12
偏度: 1.78

Box-Cox变换后:
最小值: -3.91
25%分位点: -0.67
中位数: -0.00
75%分位点: 0.67
最大值: 3.91
偏度: -0.00

Yeo-Johnson变换后:
最小值: -2.18
25%分位点: -0.78
中位数: -0.03
75%分位点: 0.75
最大值: 2.57
偏度: 0.13

 

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值