Python数据分析

213次阅读
没有评论

共计 8005 个字符,预计需要花费 21 分钟才能阅读完成。

方法论

OSEMN(Obtain, Scrub, Explore, Model, iNterpret)是一种常用的数据分析方法论,包括数据获取、数据清洗、数据探索、建模和解释等步骤。OSEMN 方法论强调了数据分析过程中数据质量和数据探索的重要性。

数理统计

数理统计分为如下两类:

  • 描述统计
  • 推断统计

描述性统计分析

描述性统计所提取统计的信息,称为 统计量,主要包括以下几个方面:

  • 频数与频率
  • 集中趋势分析

    • 均值
    • 中位数
    • 众数
    • 分位数
  • 离散程度分析

    • 极差
    • 方差
    • 标准差
  • 分布形状

    • 偏度
    • 峰度

频数与频率

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", font_scale=1.2)
plt.rcParams["font.family"] = "SimHei"  # 设置中文字体
plt.rcParams["axes.unicode_minus"] = False  # 是否使用 Unicode 字符集中的负号
warnings.filterwarnings("ignore")  # 忽略警告信息

iris = load_iris()  # 加载鸢尾花数据集
print(iris.data.shape)  # NumPy 数组 (150, 4)
print(iris.target.shape)  # NumPy 数组 (150,) 每朵鸢尾花对应的类别,取值为 0,1,2
print(iris.feature_names)  # 特征列的名称
print(iris.target_names)  # 鸢尾花类别的名称,即数值 0,1,2 分别对应的类别

## 合并数据
data = np.concatenate([iris.data, iris.target.reshape(-1, 1)], axis=1)  # 横向拼接,- 1 的作用是自动计算行
data = pd.DataFrame(data, columns=["sepal_length", "sepal_width", "petal_length", "petal_width", "type"])
data.sample(10)  # 随机抽样

frequency = data["type"].value_counts()  # 计算类别出现的频数
print(frequency)
percentage = frequency * 100 / len(data)  # 计算类别出现的频率
print(percentage)

sns.countplot(x="type", data=data)  # 绘制 type 列不同取值出现的次数
plt.show()

集中趋势

mean = data["sepal_length"].mean()  # 花萼长度的均值
median = data["sepal_length"].median()  # 中位数
s = data["sepal_length"].mode()  # mode 方法返回 Series 类型
mode = s.iloc[0]  # 众数
print(mean, median, 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()

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]))

s = pd.Series(x)
print(s.describe())  # pandas 中计算分位数
print(s.describe(percentiles=[0.25, 0.9]))

离散程度

sub = np.ptp(data["sepal_length"])  # 极差
var = data["sepal_length"].var()  # 方差
std = data["sepal_length"].std()  # 标准差
print(sub, var, std)

plt.figure(figsize=(15, 4))  # 设置图形大小,宽 * 高,单位为英寸
plt.ylim(-0.5, 1.5)
plt.plot(data["petal_length"], np.zeros(len(data)), linestyle="", marker="o", markersize=10, color="g", label=" 花瓣长度 ")
plt.plot(data["petal_width"], np.ones(len(data)), ls="", marker="o", ms=10, color="r", label=" 花瓣宽度 ")
plt.axvline(data["petal_length"].mean(), ls="--", color="g", label=" 花瓣长度均值 ")
plt.axvline(data["petal_width"].mean(), ls="--", color="r", label=" 花瓣宽度均值 ")
plt.legend()

分布形状

## 构造左偏分布数据
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())

sns.kdeplot(standard_normal, label=" 标准正态分布 ")
sns.kdeplot(data["sepal_width"], label=" 花萼宽度 ")
sns.kdeplot(data["petal_length"], label=" 花瓣长度 ")
plt.legend()

推断统计分析

总体的参数往往是未知的,为了获取总体的参数,就需要通过样本统计量来估计总体参数。

参数估计

点估计

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

sns.set(style="darkgrid", font_scale=1.2)
plt.rcParams["font.family"] = "SimHei"
plt.rcParams["axes.unicode_minus"] = False
warnings.filterwarnings("ignore")

iris = load_iris()
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"])
print(data["petal_length"].mean())

点估计容易受到随机抽样的影响,可能无法保证结论的准确性。但是,样本来自于总体,样本还是能够体现出总体的一些特征的。

区间估计

区间估计使用一个置信区间与置信度,表示总体参数有多少可能(置信度)会在该范围(置信区间)内。

样本均值分布的标准差,称为标准误差,简称标准误。

根据中心极限定理,如果多次抽样 (总体的均值为 μ,方差为σ*σ),则样本均值构成的正态分布,满足样本均值~N(μ, σ*σ/n),如果只对总体进行一次抽样,则该样本的均值有 95% 的概率会在(μ-2σ, μ+2σ) 范围内,仅有 5% 的概率会在 (μ-2σ, μ+2σ) 范围外。根据小概率事件 (很小的概率在一次抽样中基本不会发生),如果抽样的样本均值在(μ-2σ, μ+2σ) 之外,就可以认为,本次抽样来自的总体,该总体的均值并非是我们所期望的均值。

通常,以 2 倍标准差作为判依据,即以样本均值为中心,正负 2 倍标准差构成的区间,就是置信区间。而 2 倍标准差包含了 95% 的数据,因此,此时的置信度为 95%。换言之,有 95% 的信心认为总体的均值会在置信区间之内。

a = np.array([0.497, 0.506, 0.518, 0.524, 0.498, 0.511, 0.520, 0.515, 0.512])
mean, std = 0.5, 0.015  # 总体均值与标准差
sample_mean = a.mean()  # 样本均值
se = std / np.sqrt(len(a))  # 标准误
left, right = sample_mean - 1.96 * se, sample_mean + 1.96 * se
print(f" 置信区间:({left:.3f}, {right:.3f})")

plt.plot(mean, 0, marker="*", color="orange", ms=15, label=" 总体均值 ")
plt.plot(sample_mean, 0, marker="o", color="r", label=" 样本均值 ")
plt.hlines(0, xmin=left, xmax=right, color="b", label=" 置信区间 ")
plt.axvline(left, 0.4, 0.6, color="r", ls="--", label=" 左边界 ")
plt.axvline(right, 0.4, 0.6, color="g", ls="--", label=" 右边界 ")
plt.legend()

假设检验

  1. 设置原假设与备择假设

    • 原假设:μ=μ0=0.5kg(机器运作正常)
    • 备择假设:μ≠μ0≠0.5kg(机器运作不正常)
  2. 设置显著性水平,设置 α =0.05
  3. 根据问题选择假设检验的方式。袋装糖的净重呈正态分布,总体标准差已知,选择 Z 检验
  4. 计算统计量,并通过统计量获取 P 值。根据选择的假设检验,进行计算

Z 检验

Z 检验用于正态总体均值的检验,即用来检验总体的均值 (末知) 是否与假设的均值相同。

from scipy import stats

a = np.array([0.497, 0.506, 0.518, 0.524, 0.498, 0.511, 0.520, 0.515, 0.512])
mean, std = 0.5, 0.015  # 总体均值与标准差
sample_mean = a.mean()  # 样本均值
se = std / np.sqrt(len(a))  # 标准误
Z = (sample_mean - mean) / se  # Z 统计量
print(" 统计量 Z:", Z)
## 计算 P 值
## sf 函数,根据参数指定的统计量,返回该统计量与右侧图像围成的面积值
## 实际上,P 值就是通过概率密度函数计算出来的面积,即概率值
P = 2 * stats.norm.sf(abs(Z))
print("P-Value 值:", P)

由结果可知,Z 值偏离超过了 2 倍的标准差,P 值也就小于 0.05。因此,在显著性水平 α =0.05 下,P<α,故拒绝原假设,接受备择假设,即认为机器运作是不正常的。

右边假设检验

右边假设检验的拒绝域在正态分布的右侧区域。

  • 原假设:μ≤μ0=0.5kg(机器运作正常)
  • 备择假设:μ>μ0≠0.5kg(机器运作不正常)
## Z 统计量与之前计算的方式相同
P = stats.norm.sf(Z)
print("P-Value 值:", P)

P<α,拒绝原假设,认为机器运作是不正常的。

左边假设检验

左边假设检验的拒绝域在正态分布的左侧区域。

  • 原假设:μ≥μ0=0.5kg(机器运作正常)
  • 备择假设:μ<μ0≠0.5kg(机器运作不正常)
## cdf 函数,返回该统计量与左侧图像围成的面积值
P = stats.norm.cdf(Z)
print("P-Value 值:", P)

P>α,维持原假设,认为机器运作是正常的。

假设检验的两类错误

接受 H0 拒绝 H0
H0 为真 正确 I 类错误(α 错误,去真错误)
H0 为假 II 类错误(β 错误,取伪错误) 正确

t 检验

与 Z 检验的应用场景类似,t 检验也用于正态总体均值的检验。只不过,t 检验的正态总体,标准差是未知的。

t 检验分为三种类型:

  1. 单样本 t 检验
  2. 两独立样本 t 检验
  3. 两配对样本 t 检验
  • t 检验原假设为等值假设,备择假设为不等值假设(双边检验)
  • t 检验通过构造 t 统计量来实现
  • t 统计量服从 t 分布
  • 随着样本容量的增大,t 分布逐渐接近于标准正态分布

单样本 t 检验

单样本 t 检验 前提条件为:

  1. 总体服从正态分布
  2. 总体方差 (标准差) 末知

    mean = data["petal_length"].mean()
    std = data["petal_length"].std()
    t = (mean - 3.5) / (std / np.sqrt(len(data)))  # t 统计量
    print("t 统计量:", t)
    P = 2 * stats.t.sf(abs(t), df=len(data["petal_length"]) - 1)
    print("P-Value 值:", P)
    
    ## 此外,也可通过 scipy 提供的相关方法来进行 t 检验的计算,无需自行计算
    stats.ttest_1samp(data["petal_length"], 3.5)

两独立样本 t 检验

两独立样本 t 检验 用于检验两个正态总体的均值是否相同,其前提条件为:

  • 1. 两个样本是独立的
  • 2. 两个样本所在的总体服从正态分布
  • 3. 总体方差未知

由于方差是否齐性(相同),会影响 t 统计量的计算。因此,在进行两独立样本 t 检验时,首先需要进行方差齐性检验。可以通过 Levene 检验来判断两个正态总体的方差是否相同。

## A,B 两个学校的学生数据
school_A = np.array([169.7, 163.1, 179.0, 163.4, 180.2, 160.9, 177.3, 160.7, 169.9, 163.4])
school_B = np.array([163.6, 180.0, 171.8, 174.7, 164.3, 173.9, 167.0, 162.9, 164.2, 171.6])
print(school_A.mean(), school_B.mean())
## 使用 levene 检验判断两个样本背后的总体,其方差是否一致
stats.levene(school_A, school_B)

P>0.05,因此可以认为两个总体的方差是相同的。然后,就可以使用两独立样本 t 检验,来验证两个正态总体的均值是否相同。

stats.ttest_ind(school_A, school_B, equal_var=False)

P>0.05,因此维持原假设,认为两个正态总体的均值是相同的,即 A 与 B 两个学校的平均身高相同。

两配对样本 t 检验

两配对样本 t 检验,是同一组受试者产生两组数据,然后,验证两组数据是否存在显著性差异的方式。两组数据可以是:

  1. 受试者在接受处理前与处理后的数据
  2. 受试者在接受两种不同的处理方式,分别产生的数据

两配对样本 t 检验的前提条件为 :

  1. 配对样本差值独立
  2. 配对样本差值服从正态分布
  3. 总体标准差末知
## 培训前体重数据
train_before = np.array([98.8, 92.0, 94.9, 101.2, 99.3, 85.1, 94.8, 89.2, 89.5, 92.1])
## 培训后体重数据
train_after = np.array([88.4, 92.4, 90.3, 88.4, 89.3, 89.0, 92.5, 87.4, 88.9, 85.4])
## 两配对样本 t 检验(双边检验)stats.ttest_rel(train_before, train_after)

P<0.05,拒绝原假设,认为体重在培训前跟培训后是不同的。

如果没有充足的证据证明减肥有效,则应该按照减肥无效处理。则:

  • 原假设:D≤0(减肥无效)
  • 备择假设:D>0(减肥有效)
sta = stats.ttest_rel(train_before, train_after).statistic  # 获取统计量
P = stats.t.sf(sta, df=len(train_before) - 1)
print(P)

P<0.05,拒绝原假设,认为减肥有效。

卡方检验

卡方检验用于检测变量的理论频数与实际频数是否一致。

卡方检验可以分为两个类别 :

  1. 单个变量
  2. 两个变量

关于卡方检验,说明如下 :

  1. 卡方检验原假设为理论频数与实际频数一致,备择假设为理论频数与实际频数不一致(双边假设)
  2. 卡方检验为非参数检验,不对总体进行任何假设,因此也不涉及关于总体分布的参数
  3. 卡方检验通过卡方统计量来实现
  4. 卡方统计量服从卡方分布

单个变量

卡方检验 (单个变量) 的前提条件为 :

  1. 观测值之间相互独立
  2. 变量每个取值的理论频数与实际频数≥5

举例:某手机在一段时间内,销量为 200,各种颜色销量如下表所示:

红色 绿色 黄色 紫色 白色
43 50 24 31 52

请问该款手机的颜色对销售是否会造成影响?

o = [43, 50, 24, 31, 52]
e = [40, 40, 40, 40, 40]
stats.chisquare(f_obs=o, f_exp=e)

P<0.05,拒绝原假设,认为理论频数与实际频数不一致,得出结论:手机颜色对销售确实造成了影响。

两个变量

举例:某手机在一段时间内,每种颜色与性别的销量如下表所示:

红色 绿色 黄色 紫色 白色
43 50 24 31 52
38 42 30 29 45

请问该款手机的购买用户中,性别与手机颜色是否具有关联?

根据随机变量独立性的定义,如果两个随机变量 A 与 B 是独立的,则有:

P(AB) = P(A)*P(B)

因此,可以根据该定义来计算在性别与颜色两个变量独立的情况下,每个变量取值的期望概率(理论概率。例如,计算性别为男,颜色为红色为例。

P(A= 男, B= 红色) = P(A= 男) * P(B= 红色)
=(43 + 50 + 24 + 31 + 52) / 384 * (43 + 38) / 384
=0.52083 * 0.2109
=0.10986328125

有了期望概率,就可以很容易计算每个取值的期望频数:
Expected(A= 男, B= 红色) = count * P(A= 男, B= 红色)
=384 *0.10986328125
=42.1875

observed = [[43, 50, 24, 31, 52], [38, 42, 30, 29, 45]]
stats.chi2_contingency(observed)

P>0.05,维持原假设,认为理论频数与实际频数一致(意味着两个变量是独立的),得出结论:性别对手机颜色没有影响,他们之间没有关系。

正文完
 0
阿伯手记
版权声明:本站原创文章,由 阿伯手记 于2023-08-04发表,共计8005字。
转载说明:本站原创内容,除特殊说明外,均基于 CC BY-NC-SA 4.0 协议发布,转载须注明出处与链接。
评论(没有评论)
验证码

阿伯手记

阿伯手记
阿伯手记
喜欢编程,头发渐稀;成长路上,宝藏满地
文章数
766
评论数
204
阅读量
446510
今日一言
-「
热门文章
职场救急!AI请假话术生成器:1秒定制高通过率理由

职场救急!AI请假话术生成器:1秒定制高通过率理由

超级借口 不好开口?借口交给我!智能生成工作请假、上学请假、饭局爽约、约会拒绝、邀约推辞、万能借口等各种借口理...
夸克网盘快传助手提高非VIP下载速度

夸克网盘快传助手提高非VIP下载速度

夸克网盘限速这个大家都知道,不开会员差不多限速在几百 K。那有没有办法在合法合规途径加速下载夸克网盘呢?这里推...
国内已部署DeepSeek模型第三方列表 免费满血版联网搜索

国内已部署DeepSeek模型第三方列表 免费满血版联网搜索

本文收集了目前国内已部署 DeepSeek 模型的第三方列表,个个都是免费不限次数的满血版 DeepSeek,...
巴别英语:用美剧和TED演讲轻松提升英语听力与口语

巴别英语:用美剧和TED演讲轻松提升英语听力与口语

还在为枯燥的英语学习而烦恼吗?巴别英语通过创新的美剧学习模式,让英语学习变得生动有趣。平台提供海量美剧和 TE...
Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 是一款在线中文姓名生成器,可在几秒内生成符合个人需求的中文名字。...
TVAPP:开源电视盒子资源库,一键打造家庭影院

TVAPP:开源电视盒子资源库,一键打造家庭影院

导语 TVAPP 是一个专为 Android TV 电视盒子用户打造的开源影音资源库,集成了影视、直播、游戏等...
2025年12月 每日精选

2025年12月 每日精选

关于每日精选栏目 发现一些不错的资源,点击 这里 快速投稿。 12 月 26 日 .ax 顶级域 目前全球唯一...
最新评论
15220202929 15220202929 怎么用
八对 八对 麻烦大佬更新下【堆新】的友链站名:八对星星描述:极目星视穹苍无界•足履行者大地有疆链接:https://8dui.com图标:https://cf.8dui.com/logo.webp横标:https://cf.8dui.com/logo-w.webp订阅:https://8dui.com/rss.xml
三毛笔记 三毛笔记 已添加
DUINEW DUINEW 已添加贵站,期待贵站友链~博客名称:堆新博客地址:https://duinew.com/博客描述:堆新堆新,引力向新!——堆新(DUINEW)博客头像:https://d.duinew.com/logo.webp横版头像:https://d.duinew.com/logo-w.webp博客订阅:https://duinew.com/rss.xml
hedp hedp 没看懂
bingo bingo 直接生成就可以啦,也可以添加一些选项
满心 满心 申请更新下友联信息,原名:满心记,现名:周天记原域名:qq.mba,现域名:zhoutian.com描述:我在人间混日子
开业吉日 开业吉日 没看明白这个怎么用
开业吉日 开业吉日 beddystories 这个网站太赞了,收藏
热评文章
夸克网盘快传助手提高非VIP下载速度

夸克网盘快传助手提高非VIP下载速度

夸克网盘限速这个大家都知道,不开会员差不多限速在几百 K。那有没有办法在合法合规途径加速下载夸克网盘呢?这里推...
清华大学官方免费DeepSeek教程

清华大学官方免费DeepSeek教程

AI 领域近期最引人注目的焦点当属 DeepSeek,这款由中国创新企业深度求索研发的人工智能工具,正以开放源...
Short-Link 免费开源短网址程序,基于Fastify、Vercel和Supabase构建

Short-Link 免费开源短网址程序,基于Fastify、Vercel和Supabase构建

Short-Link 是一款基于 Fastify、Vercel 和 Supabase 构建的 URL 缩短服务...
国内已部署DeepSeek模型第三方列表 免费满血版联网搜索

国内已部署DeepSeek模型第三方列表 免费满血版联网搜索

本文收集了目前国内已部署 DeepSeek 模型的第三方列表,个个都是免费不限次数的满血版 DeepSeek,...
Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 是一款在线中文姓名生成器,可在几秒内生成符合个人需求的中文名字。...
BeddyStories 完全免费儿童睡前故事库,让孩子随时随地入睡更轻松

BeddyStories 完全免费儿童睡前故事库,让孩子随时随地入睡更轻松

BeddyStories 是一个致力于为儿童提供优质睡前故事的在线平台,用户可以在这里找到来自世界各地的经典故...
DrawLink:一键生成链接视觉卡片,提升分享点击率

DrawLink:一键生成链接视觉卡片,提升分享点击率

小贴士 :此站或已变迁,但探索不止步。我们已为您备好「类似网站」精选合集,相信其中的发现同样能为您带来惊喜。