晚上看神经网络的feature工程看到对偏度数据进行处理,已经忘了。。。查阅了一些资料,顺便写个小程序比较一下,记录下来
关于偏度和峰度的定义不再赘述,有很多文章
简单来说对于数据统计:
偏度能够反应分布的对称情况,右偏(也叫正偏),在图像上表现为数据右边脱了一个长长的尾巴,这时大多数值分布在左侧,有一小部分值分布在右侧。
峰度反应的是图像的尖锐程度:峰度越大,表现在图像上面是中心点越尖锐。在相同方差的情况下,中间一大部分的值方差都很小,为了达到和正太分布方差相同的目的,必须有一些值离中心点越远,所以这就是所说的“厚尾”,反应的是异常点增多这一现象。
Python的实验:
a. 先构造一个正态分布的随机100个数
b. 把排序后比较大的20个数*4,造成偏度和峰度都变大的数据
c. 把所有数据都取自然对数,再看偏度和峰度
实验结果:
可以看到b操作增加了右边的尾巴厚度,直接增大了skewness和kurtosis的值,造成了正偏分布,而对所有数取log又把数据的概率密度扁平化了,减小了这两个值
PS:网上流传最多的直接用python计算skewness和kurtosis的代码是有错误的,下面贴了改动后的正确代码,这个例子是直接用pandas自带的函数算的
实验代码:
def testSkewness():x = np.random.randn(100)x.sort()# print(calc_stat(x))# print(np.std(x))skew = round(pd.DataFrame(x).skew()[0], 2)kurtosis = round(pd.DataFrame(x).kurtosis()[0],2)label = 'Original--skew:' + str(skew) + ' kurtosis:' + str(kurtosis)g = sns.distplot(x, kde=True, hist = False, label = label)g = g.legend(loc='upper right')x[79:99] = x[79:99] * 4skew = round(pd.DataFrame(x).skew()[0],2)kurtosis = round(pd.DataFrame(x).kurtosis()[0],2)label = 'Skewed--skew:' + str(skew) + ' kurtosis:' + str(kurtosis)g = sns.distplot(x, kde=True, hist = False, label = label)g = g.legend(loc='upper right')x = np.log(x)skew = round(pd.DataFrame(x).skew()[0],2)kurtosis = round(pd.DataFrame(x).kurtosis()[0],2)label = 'logged--skew:' + str(skew) + ' kurtosis:' + str(kurtosis)g = sns.distplot(x, kde=True, hist = False, label = label)g = g.legend(loc='upper right')
手动计算两个值的代码:
def calc(data):n = len(data)niu = 0.0niu2 = 0.0niu3 = 0.0for a in data:niu += aniu2 += a**2niu3 += a**3niu/= n #这是求E(X)niu2 /= n #这是E(X^2)niu3 /= n #这是E(X^3)niu2temp = 0.0for a in data:niu2temp += np.power(a - niu, 2)niu2temp /=nsigma = np.sqrt(niu2temp) #这是D(X)的开方,标准差return [niu,sigma,niu3] #返回[E(X),标准差,E(X^3)]def calc_stat(data):[niu,sigma,niu3] = calc(data)n = len(data)niu4 = 0.0for a in data:a -= niuniu4 += a ** 4niu4 /= nskew = (niu3 - 3*niu*sigma**2 - niu**3)/(sigma**3)kurt = niu4/(sigma**2)return [niu,sigma,skew,kurt] #返回了均值,标准差,偏度,峰度
如果觉得《数据的偏度和峰度理解 + log消除 + python》对你有帮助,请点赞、收藏,并留下你的观点哦!