from matplotlib import pyplot
from numpy import sqrt
series = [i**2 for i in range(1, 100)]
pyplot.figure(1)
pyplot.subplot(211)
transform = series = sqrt(series)
pyplot.plot(transform)
pyplot.subplot(212)
pyplot.hist(transform)
pyplot.savefig('D:\\360\\index.png')
指数型统计图在点状线和直方图表现如下
特点
在数值较高的时候直方图会有一个明显的“小尾巴”趋势,极不符合高斯分布
举例:
from pandas import read_csv
from matplotlib import pyplot
series = read_csv('airline-passengers.csv', header=0, index_col=0, parse_dates=True,
squeeze=True)
pyplot.figure(1)
pyplot.subplot(211)
pyplot.plot(series)
pyplot.subplot(212)
pyplot.hist(series)
pyplot.savefig('D:\\360\\airline.png')
航空乘客数据集可能呈现二次增长。如果是这种情况,那么我们可以期望平方根变换将增长趋势减少为线性,并将观测值的分布改变为近似高斯分布。
优化
对数据进行开方处理
from pandas import read_csv
from pandas import DataFrame
from numpy import sqrt
from matplotlib import pyplot
series = read_csv('airline-passengers.csv', header=0, index_col=0, parse_dates=True,
squeeze=True)
dataframe = DataFrame(series.values)
dataframe.columns = ['passengers']
dataframe['passengers'] = sqrt(dataframe['passengers'])
pyplot.figure(1)
pyplot.subplot(211)
pyplot.plot(dataframe['passengers'])
pyplot.subplot(212)
pyplot.hist(dataframe['passengers'])
pyplot.savefig('D:\\360\\airlineTest.png')
我们可以看到,这一趋势有所减弱,但并未消除。曲线图仍显示周期间的方差不断增大。直方图仍然在分布的右侧显示一条长尾,这表明是指数分布或长尾分布。
对数据进行对数处理
from pandas import read_csv
from pandas import DataFrame
from numpy import log
from matplotlib import pyplot
series = read_csv('airline-passengers.csv', header=0, index_col=0, parse_dates=True,
squeeze=True)
dataframe = DataFrame(series.values)
dataframe.columns = ['passengers']
dataframe['passengers'] = log(dataframe['passengers'])
pyplot.figure(1)
pyplot.subplot(211)
pyplot.plot(dataframe['passengers'])
pyplot.subplot(212)
pyplot.hist(dataframe['passengers'])
pyplot.savefig('D:\\360\\airlineTestLog.png')
最后直方图呈现正态分布。
TIPS:
对数变换在时间序列数据中很流行,因为它们能有效地消除指数方差。必须注意,此操作假定值为正且非零。通常通过添加固定常数来转换观测值,以确保所有输入值都满足此要求。
变换应满足下式:
其中log是自然对数,transform是转换序列,constant是将所有观测值提升到零以上的固定值,x是时间序列。
直接使用Box-Cox变换
Box-Cox变换原理 box-cox变换
使用Box-Cox变换的好处 使用Box-Cox转换的益处
❼lambda=-1.0是一个倒数变换。
❼lambda=-0.5是平方根倒数变换。
❼lambda=0.0是一个对数变换。
❼lambda=0.5是平方根变换。
❼lambda=1.0不是转换。
from pandas import read_csv
from pandas import DataFrame
from scipy.stats import boxcox
from matplotlib import pyplot
series = read_csv('airline-passengers.csv', header=0, index_col=0, parse_dates=True,
squeeze=True)
dataframe = DataFrame(series.values)
dataframe.columns = ['passengers']
dataframe['passengers'], lam = boxcox(dataframe['passengers'])
print('Lambda:%f' % lam)
pyplot.figure(1)
pyplot.subplot(211)
pyplot.plot(dataframe['passengers'])
pyplot.subplot(212)
pyplot.hist(dataframe['passengers'])
pyplot.savefig('D:\\360\\airlineTestBox-cox.png')
运行该示例会发现lambda值为0.148023。我们可以看到,这非常接近于lambda值0.0,结果是log转换,平方根转换的强度(小于)小于0.5