数理统计:
数理统计是以概率论为基础,研究社会和自然界中大量随机现象数量变化基本规律的一种方法。分为:
描述统计
(描述统计的任务是搜集资料,进行整理、分组,编制次数分配表,绘制次数分配曲线,计算各种特征指标,以描述资料分布的集中趋势、离中趋势和次数分布的偏斜度等。)
推断统计
(推断统计是在描述统计的基础上,根据样本资料归纳出的规律性,对总体进行推断和预测。)
概念
描述性统计,就是从总体数据中提取变量的主要信息(总和、均值等),从而从总体层面上,对数据进行统计性描述。
在统计的过程中,通常会配合绘制相关的统计图来进行辅助。
描述性统计所提取统计的信息,称为统计量。
统计量
频数与频率
(数据的频数与频率统计适用于类别变量)
频数
(数据中类别变量每个不同取值出现的次数)
频率
(每个类别变量的频数与总次数的比值,通常采用百分数表示)
e.g. 在n个变量中,类别变量a出现了m次(频数),频率为m/n
集中趋势分析
均值
(即平均值,其为一组数据的总和除以数据的个数)
中位数
(将一组数据升序排列,位于该组数据最中间位置的值。如果数据个数为偶数,则取中间两个数值的均值)
众数
(一组数据中出现次数最多的值)
分位数
(通过n-1个分位将数据划分为n个区间,使得每个区间的数值个数相等,或近似相等。其中,n为分位数的数量。
常用的分位数有四分位数与百分位数)
以四分位数为例,通过3个分位,将数据划分为4个区间
第1个分位称为1/4分位(下四分位)。数据中1/4的数据小于该分位值
第2个分位称为2/4分位(中四分位)。数据中2/4的数据小于该分位值
第3个分位称为3/4分位(上四分位)。数据中3/4的数据小于该分位值
1.首先,计算四分位的位置
(其中,位置index从0开始,n为数组中元素的个数)2.根据位置计算四分位值
⊙如果index为整数(小数点后为0),四分位的值就是数组中索引为index的元素
⊙如果index不为整数,则四分位位置介于ceil(index)[向上取整]与floor(index)[向下取整]之间,根据这两个位置的元素确定四分位值
离散程度分析
极差
(一组数据中,最大值与最小值之差)
方差
(一组数据中,每个元素与均值偏离的大小)
:数组中的每个元素
:数组中所有元素的均值
:数组元素的个数
标准差
(方差的开方)
分布形状
偏度
(是统计数据分布偏斜方向和程度的度量,是统计数据分布非对称程度的数字特征)
如果数据对称分布(例如正态分布) ⇒ 偏度为0
如果数据左偏分布 ⇒ 偏度小于0
如果数据右偏分布 ⇒ 则偏度大于0
峰度
(是描述总体中所有取值分布形态陡缓程度的统计量,可理解为数据分布的高矮程度
峰度的比较是相对于标准正态分布的)
对于标准正态分布,峰度为0
如果峰度大于0,则密度图高于标准正态分布
数据在分布上比标准正态分布密集,方差(标准差)较小
如果峰度小于0,则密度图低于标准正态分布
数据在分布上比标准正态分布分散,方差(标准差)较大
变量
类别变量
(变量是一种分类,e.g. 颜色,性别,职位...)
无序类别变量
(无大小顺序等级之分,又称名义变量)
有序类别变量
(可按大小顺序等级区分,又称等级变量)
数值变量
(变量是一个具体的值,e.g. 1, 0.1...)
连续变量
(在一定区间内可以任意取值)
离散变量
(按一定顺序一一列举,通常以整数位取值的变量)
Q&A:
当数据中用0和1表示性别(或其他类别变量)时,此时0和1在实际意义上不做数值计算,应映射为类别变量。
均值、中位数与众数:
数值变量通常使用均值与中值表示集中趋势
类别变量通常使用众数表示集中趋势
在正态分布下,三者是相同的。在偏态分布下,三者会有所不同
均值使用所有的数据进行计算,因此容易受到极端值的影响
中位数与众数不受极端值的影响,因此会相对稳定
众数在一组数据中可能不是唯一的
三者的数量关系如下:
极差、方差与标准差:
极差的计算非常简单,但是极差没有充分的利用数据信息
方差(标准差)可以体现数据的分散性。方差(标准差)越大,数据越分散,方差(标准差)越小,数据越集中
方差(标准差)也可以体现数据的波动性(稳定性)。方差(标准差)越大,数据波动性越大,方差(标准差)越小,数据波动性越小
当数据较大时,也可以使用n代替n-1
代码实现
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.datasets import load_iris
import warnings
# 设置seaborn绘图的样式
sns.set(style = "darkgrid")
plt.rcParams["font.family"] = "SimHei" # 正常显示中文标签
plt.rcParams["axes.unicode_minus"] = False # 正常显示负号
# 忽略警告信息
warnings.filterwarnings("ignore")
# 加载鸢尾花数据集
iris = load_iris() # dict[花萼的长度,花萼的宽度,花瓣的长度,花瓣的宽度]
# iris.data:鸢尾花数据集
# iris.target:每朵鸢尾花对应的类别(三种类别,取值为0,1,2)
print(iris.data[0:10],iris.target[:10]) # 取前10条数据
# iris.feature_names:特征列的名称
# iris.target_names:鸢尾花类别的名称
print(iris.feature_names,iris.target_names)
输出结果:
# 将鸢尾花数据与对应的类型合并,组合成完整的记录
data = np.concatenate([iris.data, iris.target.reshape(-1,1)], axis=1) # 横向拼接
data = pd.DataFrame(data, columns=["sepal_length","sepal_width","petal_length","petal_width","type"])
data.sample(10) # 任意取出10条数据
输出结果:
1频数与频率iris.target.reshape( -1,1) 表示将一维数组转为二维数组
# 计算鸢尾花数据中,每个类别出现的频数
frequency = data["type"].value_counts()
print(frequency)
# 计算每个类别出现的频率,通常使用百分比表示
percentage = frequency * 100 / len(data)
print(percentage)
# 绘制条状图
frequency.plot(kind="bar")
输出结果:
2均值、中位数以及众数# 计算花萼长度的均值
mean = data["sepal_length"].mean()
# 计算花萼长度的中位数
median = data["sepal_length"].median()
# 方法一:计算花萼长度的众数
s = data["sepal_length"].mode()
print(s)
# 注意:mode方法返回的是Series类型
mode = s.iloc[0]
print(mean, median, mode)
# 方法二:使用scipy中的stats模块获取花萼长度的众数
from scipy import stats
stats.mode(data["sepal_length"]).mode
# 绘制数据的分布(直方图+密度图)
sns.distplot(data["sepal_length"])
# 绘制垂直线
plt.axvline(mean, ls="-", color="r", label="均值")
plt.axvline(median, ls="-", color="g", label="中位数")
plt.axvline(mode, ls="-", color="indigo", label="众数")
plt.legend()
输出结果:
3分位数# index为整数的情况
x = np.arange(10,19)
n = len(x)
# 计算四分位的索引(index)
q1_index = (n-1) * 0.25
q2_index = (n-1) * 0.5
q3_index = (n-1) * 0.75
print(q1_index, q2_index, q3_index)
# 将index转换成整数类型
index = np.array([q1_index, q2_index, q3_index]).astype(np.int32)
print(x[index])
plt.figure(figsize=(15,4))
plt.xticks(x)
plt.plot(x, np.zeros(len(x)), ls="", marker="D", ms=15, label="元素值")
plt.plot(x[index], np.zeros(len(index)), ls="", marker="X", ms=15, label="四分位置")
plt.legend()
输出结果:
# index不为整数的情况
x = np.arange(10,20)
n = len(x)
q1_index = (n-1) * 0.25
q2_index = (n-1) * 0.5
q3_index = (n-1) * 0.75
print(q1_index, q2_index, q3_index)
# 使用该值临近的两个整数来计算四分位置
index = np.array([q1_index, q2_index, q3_index])
# 计算index左边的整数值
left = np.floor(index).astype(np.int32)
# 计算index右边的整数值
right = np.ceil(index).astype(np.int32)
# 获取index的小数部分与整数部分(整数部分不使用,变量名用下划线)
weight, _ = np.modf(index)
# 根据左右两边的整数,加权计算四分位数的值。权重与距离成反比
q = x[left] * (1-weight) + x[right] * weight
print(q)
plt.figure(figsize=(15,4))
plt.xticks(x)
plt.plot(x, np.zeros(len(x)), ls="", marker="D", ms=15, label="元素值")
plt.plot(q, np.zeros(len(q)), ls="", marker="X", ms=15, label="四分位置")
for v in q:
plt.text(v, 0.01, s=v, fontsize=15)
plt.legend()
输出结果:
# Numpy中计算分位数 np.quantile(x, q)/np.percentile(x, q)
x = [1, 3, 10, 15, 18, 20, 23, 40]
print(np.quantile(x, q=[0.25, 0.5, 0.75]))
print(np.percentile(x, q=[25, 50, 75]))
输出结果:
quantile与percentile都可以计算分位数
quantile方法中 q(要计算的分位数)的取值范围为[0,1]
percentile方法中 q 的取值范围为[0,100]
# Pandas中计算分位数 s.describe(percentiles)
x = [1, 3, 10, 15, 18, 20, 21, 23, 40]
s = pd.Series(x)
print(s.describe())
输出结果:
获取四分之一分位的值的方法:
A. s.describe()[4]
B. s.describe()["25%"]
C. s.describe().iloc[4] (推荐使用)
D. s.describe().loc["25%"](推荐使用)
E. s.describe().ix[4]
F. s.describe().ix["25%"]
4极差、方差以及标准差
# 计算极差
sub1 = data["sepal_length"].max() - data["sepal_length"].min()
sub2 = np.ptp(data["sepal_length"])
# pandas 新版本中无法使用ptp(),旧版本的可以使用如下
# sub2 = data["sepal_length"].ptp()
# 计算方差
var = data["sepal_length"].var()
# 计算标准差
std = data["sepal_length"].std()
print(sub1, sub2, var, std)
输出结果:
5偏度以及峰度# 构造左偏分布数据
t1 = np.random.randint(1, 11, size=100)
t2 = np.random.randint(11, 21, size=500)
t3 = np.concatenate([t1, t2])
left_skew = pd.Series(t3)
# 构造右偏分布数据
t1 = np.random.randint(1, 11, size=500)
t2 = np.random.randint(11, 21, size=100)
t3 = np.concatenate([t1, t2])
right_skew = pd.Series(t3)
# 计算偏度
print(left_skew.skew(), right_skew.skew())
# 绘制核密度图
sns.kdeplot(left_skew, shade=True, label="左偏")
sns.kdeplot(right_skew, shade=True, label="右偏")
plt.legend()
输出结果:
# 标准正态分布
standard_normal = pd.Series(np.random.normal(0, 1, size=10000))
print("标准正态分布峰度:", standard_normal.kurt(), "标准差:", standard_normal.std())
print("花萼宽度峰度:", data["sepal_width"].kurt(), "标准差:", data["sepal_width"].std())
print("花瓣长度峰度:", data["petal_length"].kurt(), "标准差:", data["petal_length"].std())
sns.kdeplot(standard_normal, label="标准正态分布")
sns.kdeplot(data["sepal_width"], label="花萼宽度峰度")
sns.kdeplot(data["petal_length"], label="花瓣长度峰度")
输出结果:
学习课程:开课吧-大数据分析全栈课程