avatar


1.描述统计量

本文讨论的一些内容,在《机器学习实战方法(Python):特征工程-2.特征衍生 [1/2]》也有讨论,作为一种特征衍生的方法。

描述统计量通常包括三大类:

  1. 描述数据水平的统计量
    如样本平均数、样本中位数等,用于反映全部数据的数值大小。
  2. 描述数据差异的统计量
    如样本方差等,用于反映各数据间的离散程度。
  3. 描述数据分布形状的统计量
    如偏度系数和峰度系数等,用于反映数据分布的偏度和峰度。

描述水平的统计量

数据的水平是指其数值的大小,描述数据水平的统计量有平均数、分位数和众数等。

平均数

什么是平均数

平均数,也称均值(mean),是一组数据相加后除以数据个数得到的结果。

假设存在一组样本效据为x1x_1x2x_2\cdotsxnx_n,样本量(样本数据的个数)为nn,样本平均效用xˉ\bar{x}表示,计算公式为如下。也被称为算术(普通)平均数(simple mean)。

xˉ=x1+x2++xnn+i=1nxin\bar{x} = \frac{x_1 + x_2 + \cdots + x_n}{n} + \frac{\sum_{i=1}^n x_i}{n}

如果样本数据被分成kk组,各组的平均数分别用m1m_1m2m_2\cdotsmkm_k表示,各组的频数分别用f1f_1f2f_2\cdotsfkf_k表示,则样本平均数的计算公式如下。也被称为加权平均数(weighted mean)。

xˉ=m1f1+m2f2++mkfkf1+f2++fk=i=1kmifin\bar{x} = \frac{m_1 f_1 + m_2 f_2 + \cdots + m_k f_k}{f_1 + f_2 + \cdots + f_k} = \frac{\sum_{i=1}^k m_i f_i}{n}

基于Python求解

求算术平均数的方法有:

  • df[【列名】].mean()
  • np.mean(【数据】)
  • np.average(【数据】)

求加权平均数的方法有:

  • np.average(a=【数据】, weights=【权重】)

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
import pandas as pd
import numpy as np

df = pd.DataFrame({
'm': [1, 3, 5, 7, 9],
'f': [2, 4, 6, 8, 10]
})


print(df['m'].mean())
print(np.mean(df['m']))
print(np.average(df['m']))

print(np.average(a=df['m'], weights=df['f']))

运行结果:

1
2
3
4
5.0
5.0
5.0
6.333333333333333

分位数

一组数据按从小到大的顺序排序后,可以找出排在某个位置上的数值,该数值可以代表数据水平的高低。这些位置上的数值就是相应的分位数(quantie)。常用的分位数有中位数、四分位数、百分位数等。

中位数

什么是中位数

中位数(median),一组数据排序后处于中间位置上的数值。一般用MeMe,或者MeM_e表示。

中位数用一个点将全部数据等分成两部分,每部分包含50%50\%的数据,其中一部分数据比中位数大,另一部分比中位数小。中位数用中间位置上的值代表数据的水平,其特点是不受极端值的影响,具有统计上的稳健性(robustess)。

计算中位数时,要先对n个数据从小到大排序,然后确定中位数的位置,最后计算中位数的具体数值。

基于Python求解

求中位数的方法有:

  • df[【列名】].median()
  • np.median(【数据】)

示例代码:

1
2
3
4
5
6
7
8
9
10
11
import pandas as pd
import numpy as np

df = pd.DataFrame({
'm': [1, 3, 5, 7, 9],
'f': [2, 4, 6, 8, 10]
})


print(df['m'].median())
print(np.median(df['m']))

运行结果:

1
2
5.0
5.0

四分位数

什么是四分位数

四分位数(quartile),一组数据排序后处在25%25\%75%75\%位置上的数值。例如,我们用Q25Q_{25}表示处于25%25\%位置的数,用Q75Q_{75}表示处于75%75\%位置的数,则有一半的数会处于Q25Q_{25}Q75Q_{75}之间。

与中位数的计算方法类似,计算四分位数时,首先对数据从小到大排序,然后确定四分位数所在的位置,该位置上的数值就是四分位数。

基于Python求解

求解四分位数的方法有:

  • df[【列名】].quantile(q=【四分位数选项】)
  • np.quantile(a=【数据】, q=【四分位数选项】)

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pandas as pd
import numpy as np

df = pd.DataFrame({
'm': [1, 3, 5, 7, 9],
'f': [2, 4, 6, 8, 10]
})

print(df['m'].quantile(q=[0.25, 0.75]))
print(df['m'].quantile(q=[0.25, 0.75])[0.25])
print(df['m'].quantile(q=[0.25, 0.75])[0.75])

print(np.quantile(a=df['m'], q=[0.25, 0.75]))
print(np.quantile(a=df['m'], q=[0.25, 0.75][0]))
print(np.quantile(a=df['m'], q=[0.25, 0.75][1]))

运行结果:

1
2
3
4
5
6
7
8
0.25    3.0
0.75 7.0
Name: m, dtype: float64
3.0
7.0
[3. 7.]
3.0
7.0

解释说明:Pandas和Numpy的quantile都有一个参数interpolation,表示确定四分位方法,默认的都是linear,插值法。

百分位数

上文的四分位数特指0.250.250.750.75这几个位置的数,百分位数(percentile),包含[0,1][0,1]之间的所有数字。

基于Python求解的方法,也没有区别。

不赘述。

众数

什么是众数

众数(mode),一组数据中频数最多的数值。一般用MoMo或者MoM_o表示。

《机器学习实战方法(Python):特征工程-2.特征衍生 [1/2]》,我们提到过,一般不把众数作为一种特征衍生的方法,并且解释了原因,这里再补充关于众数的两个特点

  • 只有在数据量较大时众数才有意义。
  • 从数值数据分布的角度看,众数是一组数据分布的峰值点对应的数值。如果数据的分布没有明显的峰值,众数可能不存在,或者没有意义。如果有两个或多个峰值,众数可以有两个或多个。

基于Python求解

求解众数的方法有:

  • stats.mode(【数据】)
  • df[【列名】].mode()

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import pandas as pd
from scipy import stats

s = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679'

l = []

for str_iter in s:
if str_iter != '.':
l.append(int(str_iter))

print('stats.mode(l)')
print(stats.mode(l))
print('stats.mode(l).mode')
print(stats.mode(l).mode)


df = pd.DataFrame({
'l': l
})

print("df['l'].mode()")
print(df['l'].mode())
print("df['l'].mode()[0]")
print(df['l'].mode()[0])

运行结果:

1
2
3
4
5
6
7
8
9
stats.mode(l)
ModeResult(mode=9, count=14)
stats.mode(l).mode
9
df['l'].mode()
0 9
Name: l, dtype: int64
df['l'].mode()[0]
9

比较

实际应用中,应该用哪个统计量来代表一组数据的水平取决于数据的分布特征。平均数易被多数人理解和接受,实际中使用得也较多,但其缺点是易受极端值的影响。当数据的分布对称或偏斜程度不大时,可选择使用平均数。而对于严重偏斜分布的数据,平均数的代表性则较差。由于中位数不受极端值的影响,因此,当数据分布的偏斜程度较大时,可以选择使用中位数,其代表性要优于平均数。

描述差异的统计量

数据之间的差异反映了数据的离散程度。
各水平统计量对该组数据的代表程度取决于数据的离散程度,离散程度越大,其代表性越差;离散程度越小,其代表性越好。
描述样本数据离散程度的统计量主要有极差、四分位差、方差和标准差以及度量相对离散程度的变异系数等。

极差

极差(range)是一组数据的最大值与最小值之差,也称全距,一般用RR表示,计算公式为:

R=max(x)min(x)R = \max(x) - \min(x)

由于极差只利用了一组数据两端的信息,因此容易受到极端值的影响,不能全面反映数据的差异状况。

虽然极差可以作为分析数据离散程度的一个参考值,但在实际中很少单独使用。

关于基于Python的求解方法,略,用最大值减去最小值即可。

四分位差

四分位差,也称四分位距(interquarile range),是一组数据75%75\%位置上的四分位数与25%25\%位置上的四分位数之差。

四分拉差反映了中间50%50\%数据的离散程度,其数值越小,说明中间50%50\%的数据越集中;数值越大,说明中间50%50\%的数据越分散。
四分位差不受极值的影响。
由于中位数处于数据的中间位置,因此,四分位差的大小在一定程度上反映了中位数对一组数据的代表程度。

关于基于Python的求解方法,略,用75%75\%数减去25%25\%数即可。

方差和标准差

什么是方差和标准差

如果我们考虑每个数据xx,与其平均数xˉ\bar{x}之间的差异,并以此作为一组数据离散程度的度量,那么结果要比极差和四分位差更为全面和准确。
此时就需要计算每个数据xx,与其平均数xˉ\bar{x}离差的平均数,有两种方法:

  1. 将离差取绝对值,求和后再平均,这一结果称为平均离差(mean deviation)或平均绝对离差(mean absolute deviation)
  2. 将离差平方后再求平均数,这一结果称为方差(variance)。
    方差开平方后的结果称为标准差(standard deviation),它是一组数据与其平均数相比平均相差的数值。

方差(或标准差)是实际中应用最广泛的度量数据离散程度的统计量。

设样本方差次s2s^2,计算公式为:

s2=i=1n(xixˉ)2n1s^2 = \frac{\sum_{i=1}^{n}(x_i - \bar{x})^2}{n-1}

样本标准差的计算公式为:

s=i=1n(xixˉ)2n1s = \sqrt{\frac{\sum_{i=1}^{n}(x_i - \bar{x})^2}{n-1}}

如果原始数据被分成kk组,各组的组中值分别为m1m_1m2m_2\cdotsmkm_k,各组的频数分别为f1f_1f2f_2\cdotsfkf_k,则加权样本方差的计算公式为:

s2=i=1k(mixˉ)2fin1s^2 = \frac{\sum_{i=1}^{k}(m_i - \bar{x})^2 f_i}{n-1}

加权样本标准差的计算公式为:

s=i=1k(mixˉ)2fin1s = \sqrt{\frac{\sum_{i=1}^{k}(m_i - \bar{x})^2 f_i}{n-1}}

与方差不同的是,标准差与原始数据的计量单位相同,其实际意义比方差更清楚。因此,在分析实际问题时通常使用标准差。

基于Python求解

求解方差的方法有:

  • df[【列名】].var()
  • np.var(【数据】)

求解标准差的方法有:

  • df[【列名】].std()
  • np.std(【数据】)

需要注意的是,方差和标准差的自由度由函数的参数ddof(自由度)设置,不同Python包函数的默认设置不同。

  • Numpy中的函数默认ddof=0,即分母是nn而非n1n-1,
  • Pandas中的函数默认ddof=1,即自由度为n1n-1,分母是n1n-1

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import pandas as pd
import numpy as np

s = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679'

l = []

for str_iter in s:
if str_iter != '.':
l.append(int(str_iter))

print('np.var(l)')
print(np.var(l))
print('np.std(l)')
print(np.std(l))


df = pd.DataFrame({
'l': l
})

print("df['l'].var()")
print(df['l'].var())
print("df['l'].std()")
print(df['l'].std())

运行结果:

1
2
3
4
5
6
7
8
np.var(l)
8.522889912753651
np.std(l)
2.91939889579236
df['l'].var()
8.608118811881189
df['l'].std()
2.933959579115089

变异系数

标准差是反映数据离散程度的绝对值,其数值的大小受原始数据大小的影响,原始数据的观测值越大,标准差的值通常也就越大。此外,标准差与原始数据的计量单位相同, 采用不同计量单位计量的数据,其标准差的值也就不同。因此,对于不同样本的数据,如果原始数据的观测值相差较大或计量单位不同,就不能直接用标准差比较其离散程度,这时就需要计算变异系数。

变异系数(coeficient of variation,CV),也被称为离散系数,是一组数据的标准差与其相应的平均数之比。由于变异系数消除了数值大小和计量单位对标准差的影响,因而可以反映一组数据的相对离散程度。其计算公式为:

CV=sxˉCV = \frac{s}{\bar{x}}

变异系数主要用于比较不同样本或不同变量的数据的离散程度。其数值越大,说明数据的相对离散程度越大;数值越小,说明数据的相对离散程度越小。对于只有一个样本或变量的数据集,计算变异系数的意义不大。

关于基于Python的求解方法,略,用标准差除以均值即可。

描述分布形状的统计量

我们利用直方图或核密度图可以大致看出数据的分布是否对称。但是如果要想知道不对称程度,则需要计算相应的描述统计量。偏度系数和峰度系数就是对分布的不对称程度和峰值高低的一种度量。

偏度系数

什么是偏度系数

偏度(skewness),指数据分布的不对称性。描述数据分布不对称性的统计量称为偏度系数(cocfficient of skewness),一般SKSK表示。

三种计算方法

mr=1nin(xixˉ)rm_r = \frac{1}{n}\sum_i^n (x_i - \bar{x})^r为样本的rr阶中心矩,偏度系数的计算方法有以下三种:

  1. SK=m3m23/2SK = \frac{m_3}{m_2^{3/2}}
    Scipy中stats.skew函数采用的是这个。
  2. SK=m3m23/2×n(n1)n2SK = \frac{m_3}{m_2^{3/2}} \times \frac{\sqrt{n(n-1)}}{n-2}
    Pandas中DataFrame.skew函数的采用的是这个,也是SPSS、SAS、Excel软件中的默认算法。
  3. SK=m3m23/2×(n1n)3/2SK = \frac{m_3}{m_2^{3/2}} \times (\frac{n-1}{n})^{3/2}

含义

  • 当数据对称分布时,偏度系数等于0。
    偏度系数越接近于0,偏斜程度越小,数据也就越接近于对称分布。
    如果偏度系数明显不等于0,则表示分布是不对称的。
  • 若偏度系数大于11或小于1-1,则视为严重偏斜分布。
    若偏度系数在$[0.5,1]或[-1,-0.5]之间,则视为中等偏斜分布。
    若偏度系数小于0.50.5或大于0.5-0.5,则视为轻微偏斜。
  • 其中负值表示左偏分布(在分布的左侧有长尾)。
    正值则表示右偏分布(在分布的右侧有长尾)。

基于Python求解

求解偏度的方法有:

  • stats.skew(【数据】)
  • df[【列名】].skew()

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import pandas as pd
from scipy import stats

s = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679'

l = []

for str_iter in s:
if str_iter != '.':
l.append(int(str_iter))

print('stats.skew(l)')
print(stats.skew(l))


df = pd.DataFrame({
'l': l
})

print("df['l'].skew()")
print(df['l'].skew())

运行结果:

1
2
3
4
stats.skew(l)
-0.0032834735787880226
df['l'].skew()
-0.0033331819264703346

峰度系数

什么是峰度系数

峰度(kurtosis),数据分布峰值的高低。描述数据分布峰值高低的统计量称为峰度系数(coefficient of kurtosis),一般用KK表示。

三种计算方法

mr=1nin(xixˉ)rm_r = \frac{1}{n}\sum_i^n (x_i - \bar{x})^r为样本的rr阶中心矩,峰度系数的计算方法有以下三种:

  1. K=m4(m2)2K = \frac{m_4}{(m_2)^2} - 3
    Scipy中stats.kurtosis函数采用的是这个。
  2. 将第一种方法的"KK"记作K1K_1,则方法二的计算公式为K=((n+1)K1+6)×n1(n2)(n3)K=((n+1)K_1 + 6)\times\frac{n-1}{(n-2)(n-3)}
    Pandas模块中DataFrame.kurt函数采用的是这个,也是SPSS、SAS、Excel软件中的默认方法。
  3. K=m4s43K = \frac{m_4}{s^4} - 3
    ss是标准差

含义

  • 峰度通常是与标准正态分布相比较而言的。
  • 标准正态分布的峰度系数为0,当K>0K>0时,称为尖峰分布,数据分布的峰值比标准正态分布高,数据相对集中。
  • K<0K<0时,为扁平分布,数据分布的峰值比标准正态分布低,数据相对分散。

基于Python求解

求解峰度的方法有:

  • stats.kurtosis(【数据】)
  • df[【列名】].kurt()
  • df[【列名】].kurtosis()

其中df[【列名】].kurt()df[【列名】].kurtosis()是等价的,我们点进源代码,会发现这个

1
kurtosis = kurt

示例代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import pandas as pd
from scipy import stats

s = '3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679'

l = []

for str_iter in s:
if str_iter != '.':
l.append(int(str_iter))

print('stats.kurtosis(l)')
print(stats.kurtosis(l))

df = pd.DataFrame({
'l': l
})

print("df['l'].kurt()")
print(df['l'].kurt())

print("df['l'].kurtosis()")
print(df['l'].kurtosis())

运行结果:

1
2
3
4
5
6
stats.kurtosis(l)
-1.2839464222615538
df['l'].kurt()
-1.2880079887721965
df['l'].kurtosis()
-1.2880079887721965
文章作者: Kaka Wan Yifan
文章链接: https://kakawanyifan.com/30101
版权声明: 本博客所有文章版权为文章作者所有,未经书面许可,任何机构和个人不得以任何形式转载、摘编或复制。

评论区