我们可以把统计学分成描述统计和统计推断这两个部分,这两个部分正好反映了统计方法发展的前后两个阶段以及用统计方法探索客观事物数量规律性的两个不同的过程。更进一步的,我们又可以把统计推断分为两个问题,参数估计问题及假设检验问题,除此之外其实统计推断还有一个很重要的分支叫做贝叶斯统计,贝叶斯务计为我们提供了一种新颖的视角和传统的假设检验非常不一样的视角来看待问题和解决问题。
什么是描述统计
描述统计是研究
- 如何取得反映客观现象的数据(数据的收集)
- 通过图表形式对数据进行加工处理和可视化
- 通过概括与分析得出反映客观现象的规律性数量特征
数据的可靠性和有效性
每当我们接触一个数据分析项目前,我们都应该先考虑一下:数据是否可靠(reliable)和有效(valid)?
- 可靠性(reliability): 多次测量得到的数据是否一致
比如一个人对统计学的态度(早:喜欢、中:不喜欢、晚:喜欢)数据是存在疑惑的。
又比如我们想知道某个治疗是否有效(评价者1:有效、评价者2:无效)数据也是存在疑惑的。
- 有效性(validity): 实际测量的对象=认为/希望测量的对象
比如我们希望测量的是某个人的身高,那么那个人的身高数据就是有效的,但是他的体重数据就是无效的
图中的红点代表我们拿到的数据,靶心就代表我们希望测量的客观事物
第一个图(左上角)中,我们可以看见点与点之间距离是很近的,没有很分散,也就是说数据的一致性很好,且数据又几乎都在靶心中,所以这些数据既是可靠的也是有效的
第二个图(右上角)中,虽然数据点之间很聚集,但是每一个数据点都远离了靶心,也就是他们反映的不是我们希望测量的对象,所以这些数据是可靠但是无效的
第三个图(左下角)中,数据点几乎都在靶心附近活动但是比较分散,可以看出测量出来的数据波动非常大但是描述的是我们希望测量的对象,所以这些数据是有效但是不可靠的
第四个图(右下角)中,数据不止远离了靶心且非常分散,这种情况就说明数据既不可靠也不有效
数据可视化
| 尺度 | 举例 | 逻辑与数学运算 | 类别 |
|---|---|---|---|
| 名目 | 性别、颜色 | =、≠ | 定性/(无序)分类变量 |
| 次序 | 教育程度、评价 | =、≠、>、< | 定性/(有序)分类变量 |
| 等距 | 温度、年份、时间 | =、≠、>、<、+、- | 定量/数值变量 |
| 等比 | 身高、体重、年龄 | =、≠、>、<、+、-、*、/ | 定量/数值变量 |
根据数据类别的不同,我们需要选择不同的图对其进行加工处理和可视化,并且不同的变量类型所具备的规律性数量特征也有区别
一个分类变量的特征和可视化
无序分类变量
以性别为例子,性别是通过名目尺度得到的,假设我们观测记录了12个新生儿的性别(n=12)
数据为:女,男,女,女,男,男,男,男,女,男,男,女
我们要是要对这组数据进行可视化,一般来说我们都会想到这组数据中有多少个男生,多少个女生?针对这个问题,我们可以构建一个频率表(frequency table)
| 性别 | 频数(count) | 评率((frequency) |
|---|---|---|
| 女 | 5 | 5/12=41.7% |
| 男 | 7 | 7/12=58.3% |
除此之外我们还可以使用条形图
import matplotlib.pyplot as plt
data = ['男','女','男','男','男','男','女','女','男','女','男','女']
plt.hist(data)
plt.ylabel("性别")
plt.xlabel("频数")
plt.show()
集中趋势(central tendency) :一组观测值向其中心集中的倾向和程度。虽然描述集中趋势的方法有很多,但是对于无序分类变量而言只有一种,那就是众数(mode) :一组观测值中出现次数最多的数(可能存在多个众数,也可能不存在众数)
比如当我们选择最受欢迎的颜色时,所得到的结果如下:
情况1:赤1,橙1,黄1,绿1,青1,蓝1,紫1 这种情况下,众数不存在
赤2,橙6,黄1,绿10,青3,蓝10,紫4 这种情况下,我们认为众数有多个
有序分类变量
我们以教育程度进行举例,教育程度是次序尺度下所得到的。我们给五类教育程度进行赋值:小学(1),初中(2),高中(3),本科(4),研究生(5)。假设我们需要观测19个人的教育程度(n= 19)
数据为:3,4,4,1,5,4,2,1,5,4,4,4,5,3,2,1,3,5,5
首先我们依然可以构建一个频率表
| 教育程度 | 频数 | 评率 |
|---|---|---|
| 小学(1) | 3 | 3/19=15.8% |
| 初中(2) | 2 | 2/19=10.5% |
| 高中(3) | 3 | 3/19=15.8% |
| 本科(4) | 6 | 6/19=31.6% |
| 研究生(5) | 5 | 5/19=26.3% |
然后我们通过条形图进行观察
data = ['高中','本科','本科','小学','研究生','本科','初中','小学','研究生','本科','本科','高中','研究生','高中','初中','小学','本科','研究生','研究生']
plt.hist(data)
plt.ylabel("教育程度")
plt.xlabel("频数")
plt.show()
集中趋势:众数
除了众数外,我们还可以通过中位数表示这类变量的集中趋势
中位数:对于有限的数集,把所有观测值按大小排序后,位于正中间的观测值即为中位数/中值
对于我们上面所描述的数据,我们通过排序后可以得到:
1,1,2,2,3,3,3,4,4,4,4,4,4,5,5,5,5,5(n=19)
那么这组数据的中位数就是4
当n为偶数时,中位数等于最靠近中心的两个数相加除以二
总结
| 无序分类变量 | 有序分类变量 | |
|---|---|---|
| 表 | 频率表 | 频率表 |
| 图 | 条形图 | 条形图 |
| 集中趋势 | 众数 | 众数、中位数 |
一个数值变量的特征和可视化
等距变量
我们以温度进行举例,温度是等距尺度下所得到的。假设我们收集了五月份前两周的温度,
数据为:19,22,21,17,13,19,18,17,17,21,21,21,19,20(n=14)
首先我们可以和分类变量一样,对上述数据创建一个频率表
| 温度 | 频数 | 频率 |
|---|---|---|
| 13 | 1 | 0.07 |
| 17 | 3 | 0.21 |
| 18 | 1 | 0.07 |
| 19 | 3 | 0.21 |
| 20 | 1 | 0.07 |
| 21 | 4 | 0.30 |
| 22 | 1 | 0.07 |
思考:数值变量的频率表和分类变量的频率表有本质什么区别?
我们知道,等距变量可以分割成小区间而分类变量不可以这样做,下面我们设区间长度
| 温度 | 频数 | 频率 |
|---|---|---|
| (12,13] | 1 | 0.07 |
| (13,14] | 0 | 0 |
| (14,15] | 0 | 0 |
| (15,16] | 0 | 0 |
| (16,17] | 3 | 0.21 |
| (17,18] | 1 | 0.07 |
| (18,19] | 3 | 0.21 |
| (19,20] | 1 | 0.07 |
| (20,21] | 4 | 0.30 |
| (21,22] | 1 | 0.07 |
然后我们对等距变量绘制频率直方图
data = [19,22,21,17,13,19,18,17,17,21,21,21,19,20]
plt.hist(data, weights = np.zeros_like(data) + 1 / len(data))
plt.show()
也可以根据划分的区间绘制区间直方图
data = [19,22,21,17,13,19,18,17,17,21,21,21,19,20]
s = pd.cut(data, bins=[x for x in range(min(data)-1, max(data) + 1)])
values = list(s.value_counts().values)
for index in range(len(values)):
values[index] = values[index]/len(data)
labels = [str(i) + '-' + str(i+1) for i in range(min(data)-1, max(data))]
df = pd.DataFrame(values, index=labels)
df.plot(kind='bar', legend=False)
plt.xticks(rotation=0)
plt.ylabel('频率')
plt.xlabel('区间')
plt.show()
最后,我们还可以选择箱线图对数据进行可视化
data = [19,22,21,17,13,19,18,17,17,21,21,21,19,20]
plt.grid(True) # 显示网格
plt.boxplot(data,
medianprops={'color': 'red', 'linewidth': '1.5'},
meanline=True,
showmeans=True,
meanprops={'color': 'blue', 'ls': '--', 'linewidth': '1.5'},
flierprops={"marker": "o", "markerfacecolor": "red", "markersize": 10})
plt.yticks(np.arange(10, 30, 1))
plt.show()
我们对箱线图进行讲解:
集中趋势:众数、中位数
除了众数、中位数外,我们还可以通过均值表示这类变量的集中趋势
在一组数据中,所有数据之和再除以这组数据的个数,所得即为这组数据的均值,公式为:
那么这组数据的均值就是
我们还可以对数值变量求离散趋势(tendency of dispersion): 观测值偏离其中心的趋势。
- 第一个离散趋势的度量指标叫极差/全距(Range) :最大值减去最小值,用于简单描述数据的范围大小
在上面的温度数据中,极差就是最大值22减去最小值13,极差为9。这样我们可以知道,在这两周的时间内,最高温度和最低温度相差了9度,可以看出温度波动还是较大的。
极差的缺点是很容易受极端值的影响
- 第二个离散趋势的度量指标叫分位数/分位点(quantile) : 把数据n等分的分割点
我们把上面的温度数据进行一个排序
13,17,17,17,18,19,19,19,20,21,21,21,21,22
数据的中位数19,把数据分成数目相等的两部分,是二分位数/点,除此之外,四分位数/点也比较常见
中位数划分将数据左右各自划分出了7个数据,那么图中蓝色圆圈中的数据又分别把中位数左右的两组数据进行了二等位划分,我们称这三个数据叫作:第一个四分位点(Q1)、第二个四分位点(Q2)、第三个四分位点(Q3),也可以称为25%分位点(Q1)、50%分位点(Q2)、75%分位点(Q3)。Q1和Q3的距离称为四分位距(IQR),四分位距满足下面的公式:
当n=16时,Q1=(17+17)/2=17,同样的,Q2=19,Q3=21
等比变量
我们以鸢尾花花瓣的长度为例子,花瓣长度是等比尺度下所得到的。我们有一组鸢尾花花瓣长度的数据,
数据为:
| 长度 | 4.3 | 4.4 | 4.5 | 4.6 | 4.7 | 4.8 | 4.9 | 5.0 | 5.1 | 5.2 | 5.3 | 5.4 | 5.5 | 5.7 | 5.8 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 频数 | 1 | 3 | 1 | 4 | 2 | 5 | 4 | 8 | 8 | 3 | 1 | 5 | 2 | 2 | 1 |
下面我们绘制频数直方图和频率直方图
data = [4.3,4.4,4.4,4.4,4.5,4.6,4.6,4.6,4.6,4.7,4.7,4.8,4.8,4.8,4.8,4.8,4.9,4.9,4.9,4.9,5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.0,5.1,5.1,5.1,5.1,5.1,5.1,5.1,5.1,5.2,5.2,5.2,5.3,5.4,5.4,5.4,5.4,5.4,5.5,5.5,5.7,5.7,5.8]
plt.hist(data, weights = np.zeros_like(data) + 1 / len(data))
plt.show()
s = pd.cut(data, bins=np.linspace(start=min(data), stop=max(data), num=6))
values = list(s.value_counts().values)
for index in range(len(values)):
values[index] = values[index]/len(data)
labels = [str(i) + '-' + str(i+0.3) for i in np.linspace(start=min(data), stop=max(data), num=5)]
df = pd.DataFrame(values, index=labels)
df.plot(kind='bar', legend=False)
plt.xticks(rotation=0)
plt.ylabel('频率')
plt.xlabel('区间')
plt.show()
接下去我们根据箱线图对数据进行可视化
plt.grid(True) # 显示网格
plt.boxplot(data,
medianprops={'color': 'red', 'linewidth': '1.5'},
meanline=True,
showmeans=True,
meanprops={'color': 'blue', 'ls': '--', 'linewidth': '1.5'},
flierprops={"marker": "o", "markerfacecolor": "red", "markersize": 10})
plt.yticks(np.arange(4, 6, 0.2))
plt.show()
集中趋势:众数、中位数、均值
离散趋势:极差、分位数、四分位数
除了上面三个描述离散趋势的值以外,我们还可以通过下面的计算,表示等比变量的离散趋势
- 首先是方差:每一个观测值与均值之间的差异的平方和的平均数,公式为:
上面的鸢尾花数据的方差为
- 标准差:标准差就等于对方差开根,公式为:
上面的鸢尾花数据的标准差为
标准差相对应方差而言有一个优势:标准差与原观测值具有相同的单位
也就是说,上面的鸢尾花数据中,鸢尾花花瓣长度偏离均值的程度是0.352厘米
总结
| (等距)数值变量 | (等距)数值变量 | |
|---|---|---|
| 表 | 频率表 | 频率表 |
| 图 | 频率直方图、箱线图 | 频率直方图、箱线图 |
| 集中趋势 | 众数、中位数、均值 | 众数、中位数、均值 |
| 离散趋势 | 极差、分位数、四分位数 | 极差、分位数、方差、标准差 |
分布的形状
我们可以通过看一个数据分布的情况,判断它是不是和我们预期中的一样或者判断这组数据有没有符合哪种已知的分布,从而来决定我们要采用的统计方式。
偏度skewness
我们观察下面三个分布的图:
我们可以看见图1的特征是,在图的左侧有一个尾巴,从图中我们可以看出这组数据分布的众数、中位数及平均数,可以看出这组数据的均值是小于中位数的,对于这种分布情况,我们可以说这组数据是左偏的
图二看起来是非常对称的,在图中,众数、中位数、均值都在同一范围内,我们把这种分布称为对称分布
图三和图一的分布情况相反,图三的绝大多数数据集中在左侧,但是右侧有一条长长的尾巴,可以看出这组数据的均值是大于中位数的,对于这组分布情况,我们可以说这组数据是右偏的
形态(modality)
形态主要是用来描述这个分布到底有多少个峰值的
像图一那样,数值分布中只有一个峰的情况我们称为单峰分布
图二的分布现象也很明显,左右各有一个峰,我们把这种分布情况称为双峰分布
对于图三这种有三个或三个以上峰的分布情况,我们称之为多峰分布
峰度(kurtosis)
对于上图中的分布情况,可以从图中看到,这类型的分布含有一个峰尖,尾巴比较平,数据向中心聚拢的程度高
对于图中绿色的曲线,相比于上面蓝色的曲线,绿色曲线整体偏扁平,说明数据向中心聚拢程度低,数据较为分散
两个变量间的关系
两个分类变量的关系
假设我们在调查存在经常健身的习惯和性别之间的关系时,我们收集到的数据如下:
| 序号 | 性别 | 是否存在经常健身的习惯 |
|---|---|---|
| 1 | 男 | 否 |
| 2 | 女 | 否 |
| ... | ... | ... |
| 500 | 女 | 是 |
我们可以将上面的数据表构建成一个数据关联表
| 性别 | ||||
|---|---|---|---|---|
| 是否存在经常健身的习惯 | 男 | 女 | 总计 | |
| 是 | 169 | 184 | 353 | |
| 否 | 111 | 36 | 147 | |
| 总计 | 280 | 220 | 500 |
从数据关联表中可以看出,在500个样本数据中,男性存在经常健身的习惯的人数为169,女性存在经常健身的习惯的人数为184,似乎两个数据之间差别不大,但是我们对每一列数据求频率时,我们可以生成一张相对频率表:
| 性别 | |||
|---|---|---|---|
| 是否存在经常健身的习惯 | 男 | 女 | |
| 是 | 60% | 83% | |
| 否 | 40% | 17% |
我们可以发现60%的男性存在经常健身的习惯,83%的女性存在经常健身的习惯,这时候数据就更可观了。
注意:我们常说两个变量之间有关系,不等于两者之间有因果关系
除了表的形式,我们还可以选择图表的形式探索两个变量间的关系,适用于呈现两个分类变量的关系的第一个图形就是分段条形图
labels = ['男','女']
blue = [169,184]
yellow = [111,36]
blue_err = [1, 1]
yellow_err = [1, 1]
width = 0.5
fig, ax = plt.subplots()
ax.bar(labels, blue, width, yerr=blue_err, label='是',)
ax.bar(labels,yellow,width,yerr=yellow_err,bottom=blue,label='否')
ax.legend()
plt.show()
我们还可以绘制相对频率分段条形图对数据进行可视化
labels = ['男','女']
blue = [169,184]
yellow = [111,36]
blue_err = [0, 0]
yellow_err = [0, 0]
for i in range(len(blue)):
count = blue[i] + yellow[i]
blue[i] = blue[i]/count
yellow[i] = 1-blue[i]
width = 0.5
fig, ax = plt.subplots()
ax.bar(labels, blue, width, yerr=blue_err, label='是',)
ax.bar(labels,yellow,width,yerr=yellow_err,bottom=blue,label='否')
ax.legend()
plt.show()
分段条形图和相对频率分段条形图对比,两者所强调的内容也是不同的,分段条形图反映的是总数上的差异而相对频率分段条形图反映的是不同分类之间的一个比例
两个数值变量的关系
- 工资与入职时间是否有关?什么关系?关系强弱?
- 房价与到学校的距离是否有关?什么关系?关系强弱?
- 抽烟年数与寿命是否有关?什么关系?关系强弱?
- ......
从这些例子中我们可以看出,我们生活中很多问题都可以映射到两个数值变量的关系的
描述两个数值变量之间的关系,我们可以使用散点图对数据进行描述,通过散点图,我们可以知道两个关系之间的方向,形状,关系的强度和数据的极端值
散点图的横轴和纵轴分别代表着第一个数值变量和第二个数值变量,每一个数据点就是一个一次观测,上面的散点图在,并未展示出两个变量之间的某种关系,这就意味着两个变量有关系的可能性很小
在这个散点图中,我们可以看见随着横坐标数值不断变大,纵坐标的数值也逐渐增大,所有数据点几乎在同一条直线上,这意味着两个数据变量之间存在着一定的线性关系且关系非常强
一个数值变量和一个分类变量的关系
- 工资与性别是否有关?
- 房价与学区房是否有关?
- 抽烟年数与肺癌是否有关?
- ......
我们生活中很多例子还可以抽象成一个数值变量和一个分类变量的关系
适合描述一个数值变量和一个分类变量的关系的图形叫并排箱图
例如上面的并排箱图所示,横坐标为分类变量,纵坐标是数值变量
极端值和缺失值
极端值和缺失值都会对我们的分析结果产生一定的偏差,因此我们需要正确处理极端值和缺失值
极端值
什么叫极端值
极端值也称为异常值,在数学定义里面所介绍的极端值是这样的:
在一组数据中,小于或者大于的数据是疑似极端值,在一组数据中,小于或者大于的数据是极端值。
我们通过箱线图对极端值进行观测
在上面的箱线图中,红色的数据点就是极端值
注意区分的一点:上面的箱线图是普通箱线图,下面我们来介绍一个叫修正箱线图的可视化图表
与普通箱线图不同的是,修正箱线图上下两根线并不代表数据的上下界,而是分别代表和,在两线范围以外的极端点叫疑似极端点或极端值
极端值产生的原因
- 数据的测量、记录或输入时的错误
- 数据来自不同的总体(例如:病人vs健康人)
- 数据是,正确的,但它只体现小概率事件
极端值可能产生的影响
先看一组数据,某公司员工的收入水平
1.2, 1.3, 1.4, 1.5,1.6, 1.6, 1.8, 2.0, 2.2, 15
我们通过计算得出,这组数据的均值是2.96,由于15这个极端值的存在,数据的均值超过了绝大多数员工的收入水平,如果我们把15从数据中剔除,我们计算得到的均值是1.62,中位数和众数无论是否剔除极端值,都是1.6,和剔除了极端值后的均值更相近
- 可以看出均值受极端值影响很大
除此之外,我们计算到数据的极差为13.8,如果把极端值剔除,极差仅为1
- 由此可见,极差受极端值影响也是挺大的
同样的,我们计算标准差为4.24,剔除极端值后标准差为0.33
- 可以看出标准差也极容易受到极端值影响
但是,当我们计算IQR的时候发现,带极端值(IQR=0.6)与不带极端值(IQR=0.55)差别不大
如何处理极端值
- 如果是由于测量或记录的错误,或其他明显的原因造成的,直接丢弃即可
- 如果极端值出现的原因无法解释,那么,丢弃或保留极端值则需要具体问题具体分析;尽量选用受极端值影响小的指标
- 可以通过对比保留极端值和丢弃极端值对结果的影响,来判断结果是否受到极端值的影响
缺失值
缺失值是指本应该存在但由于某些原因不存在的数据
如何处理缺失值
- 如果含有缺失值的观测记录很少,而数据量很大,可以把含有缺失值的观测记录丢弃
- 如果含有缺失值的观测记录很多,需要分析原因,看是否能够把缺失的记录补全
- 如果含有缺失值的观测记录较少,可以使用均值/中位数/众数/最大值等进行替代