Python数据分析(比率检验、方差分析、线性回归)

编程 · 2023-08-04 · 190 人浏览

比率检验

总体比率指具有某种特征的个体所占有的比值。例如,学生中男生的比值,广告的点击率等。

比率检验用于检测总体比率是否与预期的假设一致。

比率检验可以分为如下两类:

  1. 单总体比率检验
  2. 双总体比率检验

关于比率检验,说明如下 :

  1. 比率检验的原假设为等值假设,备择假设为不等值假设(双边检验)
  2. 样本比率服从二项分布。当满足一定条件时,二项分布近似于正态分布
  3. 比率检验通过构造Z统计量来实现

单总体比率检验

前提条件:

  1. 样本容量充分大(n>30)
  2. np≥5
  3. n(1-p)≥5

案例:A公司计划提高广告转化率,于是,公司老板聘请高级设计师小马,来对广告页面进行优化,进而提高转化率。小马设计完毕后,信誓旦旦立下军令状,扬言将广告页面转化率提升到10%。一周之后,公司对小马的业绩进行考核,广告点击500次,转换用户45人。小马是否能算完成任务了呢?

import numpy as np
from scipy import stats

p = 45 / 500  # 样本比率
pi_0 = 0.1  # 总体比率
n = 500  # 样本容量
Z = (p - pi_0) / np.sqrt(pi_0 * (1 - pi_0) / n)  # 计算Z统计量
print("Z统计量", Z)
P = stats.norm.cdf(Z)
print("P-Value:", P)

P>0.05,维持原假设,没有充分的理由证明小马没有完成任务。

双总体比率检验

前提条件:

  1. n1p1≥5
  2. n1(1-p1)≥5
  3. n2p2≥5
  4. n2(1-p2)≥5

案例:A公司采用两种方式来对自己的训练营进行推广,A方式成本较低但转化率也较低,B方式成本较高但转化率也较高。现A公司领导对两种推广方式进行评估,本着降低成本的原则,现决定:除非B方式比A方式转化率高2%以上,才采用B方式,否则采用A方式。现分别采用两种推广方式进行测试,A方式引进流量1052人,转化13人,B方式引进流量402人,转化10人,请问A公司应该采用哪种方式来推广训练营?

原假设:pl-p2≤0.02(B方式p1没有比A方式p2转化率多2%以上)
备择假设:p1-p2>0.02(B方式比A方式转化率多2%以上)

## 样本比率
p1 = 10 / 402
p2 = 13 / 1052
## 定义比率的差值
d0 = 0.02
## 定义样本容量
n1 = 402
n2 = 1052
## 计算分母部分
denominator = np.sqrt((p1 * (1 - p1) / n1) + (p2 * (1 - p2) / n2))
Z = (p1 - p2 - d0) / denominator
print("Z统计量:", Z)
P = stats.norm.sf(Z)
print("P-Value:", P)

P>0.05,维持原假设,没有充分的理由证明B方式比A方式转化率多2%以上,所以还是用A方式省钱。

方差分析

方差分析(ANOVA-Analysis of Variance),用于检测多个总体的均值是否相同(存在差异)。

方差分析可以分为两类:

  1. 单因素方差分析
  2. 多因素方差分析

关于方差分析,说明如下:

  1. 方差分析原假设为多个总体的均值相同,备择假设为至少两个总体的均值不同
  2. 方差分析通过构造F统计量来实现
  3. F统计量服从F分布

单因素方差分析

单因素方差分析用来分析两个或多个样本(来自不同总体)的均值是否相等,进而可以用来检验分类变量与连续变量之间是否相关。检验方式为,根据分类变量的不同取值,将样本进行分组,然后根据每个分组的均值进行检验。

单因素方差分析的前提条件如下:

  1. 样本观测值之间独立
  2. 每个样本来自正态分布的总体
  3. 总体之间的方差是相同的

案例:某公司领导在年终对部门进行评估,在一年内,A,B与C三个部门共收到投诉如下:

部门投诉量
A5
B3
B4
C6
A2

假设投诉量服从正态分布,请问三个部门的投诉量是否相同?

np.random.seed(0)
## 模拟随机生成3个部门的投诉数据
department_a = np.random.randint(5, 20, size=45)
department_b = np.random.randint(3, 15, size=60)
department_c = np.random.randint(7, 18, size=55)
## 进行levene检验,判断3个组的方差是否齐性
stats.levene(department_a, department_b, department_c)  # pvalue=0.42,说明方差相同
## 进行单因素方差分析
stats.f_oneway(department_a, department_b, department_c)

P<0.05,拒绝原假设,说明至少两个总体的均值不同,意味着这3个部门的投诉量是不一样的。

线性回归

回归分析是用来评估变量之间关系的统计过程。用来解释自变量X与因变量Y的关系。即当自变量X发生改变时,因变量Y会如何发生改变。

简单线性回归

这里以房屋面积(x)与房屋价格(y)为例,显而易见,二者是一种线性关系,房屋价格正比于房屋面积,我
们假设比例为w:ŷ = w * x + b。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
## 用来切分训练集与测试集
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
## 设置输出的精度,默认为8
np.set_printoptions(precision=2)
plt.rcParams["font.family"] = "SimHei"
plt.rcParams["font.size"] = 12
plt.rcParams["axes.unicode_minus"] = False

iris = load_iris()
## 花瓣长度作为x,宽度作为y
x, y = iris.data[:, 2].reshape(-1, 1), iris.data[:, 3]

lr = LinearRegression()
## 将数据集划分为训练集与测试集
## test_size:测试集大小
## random_state:随机种子
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=0)

## 使用训练集训练模型
lr.fit(x_train, y_train)
print("权重:", lr.coef_)
print("截距:", lr.intercept_)
## 从训练集学习得到模型的参数(w与b),确定方程,就可以进行预测
y_hat = lr.predict(x_test)
print("实际值:", y_test[:5])
print("预测值:", y_hat[:5])

plt.figure(figsize=(10, 6))
plt.scatter(x_train, y_train, c="orange", label="训练集")  # 散点图
plt.scatter(x_test, y_test, c="g", marker="D", label="测试集")
plt.plot(x, lr.predict(x), "r-")
plt.legend()
plt.xlabel("花瓣长度")
plt.ylabel("花瓣宽度")

plt.figure(figsize=(15, 6))
plt.plot(y_test, label="真实值", color="r", marker="o")
plt.plot(y_hat, label="预测值", ls="--", color="g", marker="o")
plt.xlabel("测试集数据序号")
plt.ylabel("数据值")
plt.legend()

回归模型评估

当我们建立好模型后,模型的效果如何呢?对于回归模型,可以采用如下的指标来进行衡量:

  • MSE
  • RMSE
  • MAE
  • R^2

R^2

R^2为决定系数,用来表示模型拟合性的分值,值越高表示模型拟合性越好,在训练集中取值范围为[0,1]。在测试集(未知数据)中取值范围为(-∞,1]。

from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score

print("均方误差(MSE):", mean_squared_error(y_test, y_hat))
print("根均方误差(RMSE):", np.sqrt(mean_squared_error(y_test, y_hat)))
print("平均绝对值误差(MAE):", mean_absolute_error(y_test, y_hat))

print("训练集R^2:", r2_score(y_train, lr.predict(x_train)))
print("测试集R^2:", r2_score(y_test, y_hat))
## score求解的就是R^2的值
print("训练集R^2:", lr.score(x_train, y_train))
print("测试集R^2:", lr.score(x_test, y_test))

多元线性回归

现实中的数据可能是比较复杂的,自变量也很可能不只一个。例如,影响房屋价格也很可能不只房屋面积一个因素,可能还有距地铁距离,距市中心距离,房间数量,房屋所在层数,房屋建筑年代等诸多因素。不过,这些因素,对房屋价格影响的力度(权重)是不同的,例如,房屋所在层数对房屋价格的影响就远不及房屋面积,因此,我们可以使用多个权重来表示多个因素与房屋价格的关系:

ŷ = w1 x1 + w2 x2 + w3 x3 + ··· + wn xn + b

data_url = "http://lib.stat.cmu.edu/datasets/boston"
raw_df = pd.read_csv(data_url, sep="s+", skiprows=22, header=None)
data = np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]])
target = raw_df.values[1::2, 2]
x, y = data, target

df = pd.DataFrame(np.concatenate([x, y.reshape(-1, 1)], axis=1), columns=["CRIM", "ZN", "INDUS", "CHAS", "NOX", "RM", "AGE", "DIS", "RAD", "TAX", "PTRATIO", "B", "LSTAT", "MEDV"])
df.head()

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.25, random_state=0)
## 使用训练集训练模型
lr.fit(x_train, y_train)
print("权重:", lr.coef_)
print("截距:", lr.intercept_)
y_hat = lr.predict(x_test)
print("训练集R^2:", lr.score(x_train, y_train))
print("测试集R^2:", lr.score(x_test, y_test))
Python
Theme Jasmine by Kent Liao