在机器学习和深度学习领域,某些模型如线性回归、逻辑回归、人工神经网络等,假设特征是正态分布的,并且在建模时提供的特征如果是正态分布的,模型的性能会更好。然而,提供的数据并不一定遵循正态分布,这种情况下该怎么办呢?本文将探讨这个问题。
在概率论中,正态分布(或高斯分布)是一种连续概率分布,适用于实值随机变量。其概率密度函数的一般形式是:
f(x) = (1 / (σ√(2π))) * e^(-(x-μ)^2 / (2σ^2))
正态分布的样本呈现钟形曲线,并且围绕均值分布。正态分布的均值、中位数和众数是相同的。
可以通过多种方式来检查变量的分布情况,包括:
将通过一个数据集来展示上述方法。这里,将使用一个汽车价格数据集的子集,其中排除了分类变量,并检查数值变量的分布。
import pandas as pd
# 读取数据集
cp = pd.read_csv('CarPrice_Assignment.csv')
# 取数据子集
cp = cp[['symboling', 'wheelbase', 'carlength', 'carwidth', 'carheight', 'curbweight', 'boreratio', 'stroke', 'compressionratio', 'horsepower', 'peakrpm', 'citympg', 'highwaympg', 'price']]
# 打印数据的前五行
print(cp.head())
通过偏度检查分布:
cp.skew()
从上述结果中,可以检查哪些变量是正态分布的,哪些不是。
已经看到了如何检查特征的分布。本节将学习如何将变量转换为正态分布,如果它们不遵循正态分布的话。
首先,定义一个Python函数,该函数接受数据和特征名称作为输入,并返回该特征的核密度估计图和Q-Q图。
def normality(data, feature):
plt.figure(figsize=(10,5))
plt.subplot(1,2,1)
sns.kdeplot(data[feature])
plt.subplot(1,2,2)
stats.probplot(data[feature], plot=pylab)
plt.show()
使用上述定义的函数绘制价格特征的图表:
normality(cp, 'price')
这将把价格值转换为其对数值,即log(Price)。
cp['price_log'] = np.log(cp['price'])
绘制变换后的图表以检查变换效果:
normality(cp, 'price_log')
这将反转价格值,即1/Price。
cp['price_reciprocal'] = 1/cp.price
绘制变换后的图表以检查变换效果:
normality(cp, 'price_reciprocal')
这种变换将取价格列的平方根,即sqrt(Price)。
cp['price_sqroot'] = np.sqrt(cp.price)
绘制变换后的图表以检查变换效果:
normality(cp, 'price_sqroot')
取价格变量的指数值。
cp['price_exponential'] = cp.price**(1/1.2)
绘制变换后的图表以检查变换效果:
normality(cp, 'price_exponential')
y = (x^λ - 1) / λ (for λ ≠ 0)
y = log(x) (for λ = 0)
cp['price_Boxcox'], parameters = stats.boxcox(cp['price'])
normality(cp, 'price_Boxcox')