Python pandas统计分析实战教程 通过真实数据案例掌握数据处理描述统计和假设检验的核心技能
引言
Pandas是Python编程语言中一个强大的数据分析和处理库,它提供了高性能、易于使用的数据结构和数据分析工具。作为数据科学领域的重要工具,pandas使数据清洗、处理、分析和可视化变得更加简便。本教程将通过真实数据案例,带你深入学习如何使用pandas进行数据处理、描述统计和假设检验,帮助你掌握统计分析的核心技能。
无论你是数据分析师、研究人员,还是对数据分析感兴趣的初学者,本教程都将为你提供实用的知识和技能,让你能够熟练运用pandas解决实际数据分析问题。
准备工作
环境设置
在开始之前,确保你的系统已经安装了Python和必要的库。如果尚未安装,可以通过以下命令安装:
pip install pandas numpy scipy matplotlib seaborn 这些库中:
- pandas:用于数据处理和分析
- numpy:提供数值计算功能
- scipy:提供科学计算功能,包括统计检验
- matplotlib和seaborn:用于数据可视化
导入库
在Python脚本或Jupyter Notebook中,首先导入所需的库:
import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns from scipy import stats # 设置可视化风格 sns.set(style="whitegrid") plt.rcParams['figure.figsize'] = [10, 6] # 设置显示选项 pd.set_option('display.max_columns', 50) pd.set_option('display.max_rows', 100) 数据获取
本教程将使用几个真实数据集来演示统计分析技术。我们将使用以下数据集:
- 鸢尾花数据集(Iris Dataset):经典的机器学习数据集,包含三种鸢尾花的四个特征。
- 泰坦尼克号数据集(Titanic Dataset):包含泰坦尼克号乘客的信息,常用于数据分析和预测建模。
- 波士顿房价数据集(Boston Housing Dataset):包含波士顿地区房屋价格及相关因素的数据。
让我们加载这些数据集:
# 加载鸢尾花数据集 iris = sns.load_dataset('iris') print("鸢尾花数据集前5行:") print(iris.head()) # 加载泰坦尼克号数据集 titanic = sns.load_dataset('titanic') print("n泰坦尼克号数据集前5行:") print(titanic.head()) # 加载波士顿房价数据集 from sklearn.datasets import load_boston boston = load_boston() boston_df = pd.DataFrame(boston.data, columns=boston.feature_names) boston_df['PRICE'] = boston.target print("n波士顿房价数据集前5行:") print(boston_df.head()) 数据基本了解
在开始分析之前,我们需要对数据有一个基本的了解:
# 鸢尾花数据集基本信息 print("鸢尾花数据集信息:") print(iris.info()) print("n鸢尾花数据集描述统计:") print(iris.describe()) # 泰坦尼克号数据集基本信息 print("n泰坦尼克号数据集信息:") print(titanic.info()) print("n泰坦尼克号数据集描述统计:") print(titanic.describe()) # 波士顿房价数据集基本信息 print("n波士顿房价数据集信息:") print(boston_df.info()) print("n波士顿房价数据集描述统计:") print(boston_df.describe()) 数据处理
数据处理是数据分析的重要步骤,包括数据清洗、转换、整合等操作。在本节中,我们将学习如何使用pandas进行各种数据处理操作。
数据清洗
数据清洗是处理数据中的错误、不一致和缺失值的过程。让我们以泰坦尼克号数据集为例,进行数据清洗。
处理缺失值
首先,检查数据中的缺失值:
# 检查泰坦尼克号数据集中的缺失值 print("泰坦尼克号数据集中的缺失值:") print(titanic.isnull().sum()) 输出显示,’age’、’embarked’、’deck’和’embark_town’列存在缺失值。我们可以采用不同的策略处理这些缺失值:
# 复制原始数据,以便比较 titanic_clean = titanic.copy() # 1. 对于'age'列,使用中位数填充 age_median = titanic_clean['age'].median() titanic_clean['age'].fillna(age_median, inplace=True) # 2. 对于'embarked'和'embark_town'列,使用众数填充 embarked_mode = titanic_clean['embarked'].mode()[0] titanic_clean['embarked'].fillna(embarked_mode, inplace=True) titanic_clean['embark_town'].fillna(embarked_mode, inplace=True) # 3. 对于'deck'列,由于缺失值太多,我们可以删除该列 titanic_clean.drop('deck', axis=1, inplace=True) # 再次检查缺失值 print("处理后的缺失值:") print(titanic_clean.isnull().sum()) 处理重复值
检查并处理数据中的重复值:
# 检查重复值 print("泰坦尼克号数据集中的重复值数量:", titanic_clean.duplicated().sum()) # 删除重复值 titanic_clean.drop_duplicates(inplace=True) # 再次检查重复值 print("删除后的重复值数量:", titanic_clean.duplicated().sum()) 处理异常值
异常值是数据集中与其他观测值明显不同的值。我们可以使用箱线图或统计方法来检测异常值。以波士顿房价数据集为例:
# 绘制房价的箱线图 plt.figure(figsize=(10, 6)) sns.boxplot(x=boston_df['PRICE']) plt.title('波士顿房价箱线图') plt.show() # 使用IQR方法检测异常值 Q1 = boston_df['PRICE'].quantile(0.25) Q3 = boston_df['PRICE'].quantile(0.75) IQR = Q3 - Q1 lower_bound = Q1 - 1.5 * IQR upper_bound = Q3 + 1.5 * IQR # 找出异常值 outliers = boston_df[(boston_df['PRICE'] < lower_bound) | (boston_df['PRICE'] > upper_bound)] print("检测到的异常值数量:", len(outliers)) # 处理异常值(这里使用截尾方法) boston_df_clean = boston_df.copy() boston_df_clean['PRICE'] = np.where(boston_df_clean['PRICE'] > upper_bound, upper_bound, np.where(boston_df_clean['PRICE'] < lower_bound, lower_bound, boston_df_clean['PRICE'])) # 绘制处理后的箱线图 plt.figure(figsize=(10, 6)) sns.boxplot(x=boston_df_clean['PRICE']) plt.title('处理后的波士顿房价箱线图') plt.show() 数据转换
数据转换包括将数据从一种形式转换为另一种形式,以满足分析需求。
类型转换
# 查看泰坦尼克号数据集的数据类型 print("泰坦尼克号数据集的数据类型:") print(titanic_clean.dtypes) # 将'category'类型的列转换为'category'数据类型 category_cols = ['sex', 'embarked', 'class', 'who', 'adult_male', 'embark_town', 'alive', 'alone'] for col in category_cols: titanic_clean[col] = titanic_clean[col].astype('category') # 将'survived'和'pclass'转换为分类类型 titanic_clean['survived'] = titanic_clean['survived'].astype('category') titanic_clean['pclass'] = titanic_clean['pclass'].astype('category') # 查看转换后的数据类型 print("n转换后的数据类型:") print(titanic_clean.dtypes) 标准化/归一化
标准化和归一化是常用的数据预处理技术,用于将数据缩放到特定的范围。
from sklearn.preprocessing import StandardScaler, MinMaxScaler # 对波士顿房价数据集进行标准化 scaler = StandardScaler() boston_scaled = boston_df_clean.copy() boston_scaled[boston_df.columns] = scaler.fit_transform(boston_df_clean[boston_df.columns]) print("标准化后的波士顿房价数据集前5行:") print(boston_scaled.head()) # 对波士顿房价数据集进行归一化 min_max_scaler = MinMaxScaler() boston_normalized = boston_df_clean.copy() boston_normalized[boston_df.columns] = min_max_scaler.fit_transform(boston_df_clean[boston_df.columns]) print("n归一化后的波士顿房价数据集前5行:") print(boston_normalized.head()) 虚拟变量编码
将分类变量转换为数值形式,以便进行统计分析:
# 对泰坦尼克号数据集进行虚拟变量编码 titanic_encoded = pd.get_dummies(titanic_clean, columns=['sex', 'embarked', 'class', 'who', 'embark_town', 'alive'], drop_first=True) print("虚拟变量编码后的泰坦尼克号数据集前5行:") print(titanic_encoded.head()) 数据整合
数据整合是将多个数据集合并为一个数据集的过程。
# 创建两个简单的数据框用于演示 df1 = pd.DataFrame({ 'id': [1, 2, 3, 4], 'name': ['Alice', 'Bob', 'Charlie', 'David'] }) df2 = pd.DataFrame({ 'id': [3, 4, 5, 6], 'score': [85, 90, 75, 80] }) # 内连接(inner join) inner_join = pd.merge(df1, df2, on='id', how='inner') print("内连接结果:") print(inner_join) # 左连接(left join) left_join = pd.merge(df1, df2, on='id', how='left') print("n左连接结果:") print(left_join) # 右连接(right join) right_join = pd.merge(df1, df2, on='id', how='right') print("n右连接结果:") print(right_join) # 外连接(outer join) outer_join = pd.merge(df1, df2, on='id', how='outer') print("n外连接结果:") print(outer_join) 数据分组与聚合
数据分组与聚合是数据分析中常用的操作,用于对数据进行分组并计算各组的统计量。
# 对泰坦尼克号数据集按性别分组,计算平均年龄和票价 grouped = titanic_clean.groupby('sex')[['age', 'fare']].mean() print("按性别分组的平均年龄和票价:") print(grouped) # 多级分组 multi_grouped = titanic_clean.groupby(['sex', 'pclass'])[['survived', 'age', 'fare']].agg({ 'survived': 'mean', 'age': 'mean', 'fare': 'mean' }) print("n按性别和舱位等级分组的统计信息:") print(multi_grouped) # 使用pivot_table进行数据透视 pivot_table = titanic_clean.pivot_table( values='survived', index='sex', columns='pclass', aggfunc='mean' ) print("n生存率的数据透视表:") print(pivot_table) 描述统计
描述统计是通过图表和数值摘要来理解和总结数据的方法。本节将介绍如何使用pandas进行各种描述统计分析。
集中趋势测量
集中趋势测量包括均值、中位数和众数,它们表示数据的中心位置。
# 计算鸢尾花数据集中各种鸢尾花的花瓣长度的均值、中位数和众数 print("鸢尾花花瓣长度的集中趋势测量:") print("均值:", iris['petal_length'].mean()) print("中位数:", iris['petal_length'].median()) print("众数:n", iris['petal_length'].mode()) # 按种类分组计算集中趋势测量 print("n按种类分组的集中趋势测量:") grouped_central = iris.groupby('species')['petal_length'].agg(['mean', 'median', lambda x: stats.mode(x)[0][0]]) grouped_central.columns = ['均值', '中位数', '众数'] print(grouped_central) 离散程度测量
离散程度测量包括极差、方差、标准差和四分位距,它们表示数据的分散程度。
# 计算鸢尾花数据集中各种鸢尾花的花瓣长度的离散程度测量 print("鸢尾花花瓣长度的离散程度测量:") print("极差:", iris['petal_length'].max() - iris['petal_length'].min()) print("方差:", iris['petal_length'].var()) print("标准差:", iris['petal_length'].std()) print("四分位距:", iris['petal_length'].quantile(0.75) - iris['petal_length'].quantile(0.25)) # 按种类分组计算离散程度测量 print("n按种类分组的离散程度测量:") grouped_dispersion = iris.groupby('species')['petal_length'].agg([ lambda x: x.max() - x.min(), # 极差 'var', # 方差 'std', # 标准差 lambda x: x.quantile(0.75) - x.quantile(0.25) # 四分位距 ]) grouped_dispersion.columns = ['极差', '方差', '标准差', '四分位距'] print(grouped_dispersion) 分布形态
分布形态描述了数据分布的形状,包括偏度和峰度。
# 计算鸢尾花花瓣长度的偏度和峰度 print("鸢尾花花瓣长度的分布形态:") print("偏度:", iris['petal_length'].skew()) print("峰度:", iris['petal_length'].kurtosis()) # 按种类分组计算分布形态 print("n按种类分组的分布形态:") grouped_shape = iris.groupby('species')['petal_length'].agg(['skew', 'kurtosis']) grouped_shape.columns = ['偏度', '峰度'] print(grouped_shape) # 绘制直方图和密度图 plt.figure(figsize=(12, 6)) for species in iris['species'].unique(): subset = iris[iris['species'] == species] sns.distplot(subset['petal_length'], hist=True, kde=True, label=species, hist_kws={'alpha': 0.3}) plt.title('不同种类鸢尾花花瓣长度的分布') plt.xlabel('花瓣长度') plt.ylabel('密度') plt.legend() plt.show() 相关性分析
相关性分析用于研究两个或多个变量之间的关系。
# 计算鸢尾花数据集中数值变量之间的相关系数 print("鸢尾花数据集的相关系数矩阵:") correlation_matrix = iris.corr() print(correlation_matrix) # 绘制热力图 plt.figure(figsize=(10, 8)) sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', linewidths=0.5) plt.title('鸢尾花数据集的相关系数热力图') plt.show() # 绘制散点图矩阵 sns.pairplot(iris, hue='species') plt.suptitle('鸢尾花数据集的散点图矩阵', y=1.02) plt.show() # 计算波士顿房价数据集的相关性 boston_correlation = boston_df.corr() print("n波士顿房价数据集与房价相关性最高的几个特征:") price_correlation = boston_correlation['PRICE'].sort_values(ascending=False) print(price_correlation) # 绘制与房价相关性最高的特征的散点图 top_features = price_correlation[1:4].index.tolist() # 排除'PRICE'本身 plt.figure(figsize=(15, 5)) for i, feature in enumerate(top_features, 1): plt.subplot(1, 3, i) sns.scatterplot(x=boston_df[feature], y=boston_df['PRICE']) plt.title(f'{feature} vs PRICE') plt.tight_layout() plt.show() 假设检验
假设检验是统计分析中用于判断样本数据是否支持某个关于总体的假设的方法。本节将介绍几种常用的假设检验方法。
基本概念
假设检验涉及以下基本概念:
- 原假设(H0):通常表示”无差异”或”无效果”的假设。
- 备择假设(H1):与原假设相对的假设。
- 显著性水平(α):通常设置为0.05,表示我们接受错误地拒绝原假设的风险。
- p值:在原假设为真的情况下,观察到当前或更极端结果的概率。
- 统计决策:如果p值小于显著性水平,则拒绝原假设;否则,不拒绝原假设。
t检验
t检验用于比较两个样本的均值是否有显著差异。
单样本t检验
单样本t检验用于比较样本均值与已知的总体均值是否有显著差异。
# 假设我们想知道鸢尾花setosa种类的花瓣长度是否显著不同于1.5cm setosa_petal_length = iris[iris['species'] == 'setosa']['petal_length'] # 进行单样本t检验 t_stat, p_value = stats.ttest_1samp(setosa_petal_length, 1.5) print("单样本t检验结果:") print(f"t统计量: {t_stat:.4f}") print(f"p值: {p_value:.4f}") # 解释结果 alpha = 0.05 if p_value < alpha: print("结论:拒绝原假设,setosa种类的花瓣长度显著不同于1.5cm。") else: print("结论:不拒绝原假设,没有足够证据表明setosa种类的花瓣长度显著不同于1.5cm。") 独立样本t检验
独立样本t检验用于比较两个独立样本的均值是否有显著差异。
# 比较鸢尾花setosa和versicolor种类的花瓣长度是否有显著差异 setosa_petal_length = iris[iris['species'] == 'setosa']['petal_length'] versicolor_petal_length = iris[iris['species'] == 'versicolor']['petal_length'] # 进行独立样本t检验 t_stat, p_value = stats.ttest_ind(setosa_petal_length, versicolor_petal_length) print("n独立样本t检验结果:") print(f"t统计量: {t_stat:.4f}") print(f"p值: {p_value:.4f}") # 解释结果 if p_value < alpha: print("结论:拒绝原假设,setosa和versicolor种类的花瓣长度有显著差异。") else: print("结论:不拒绝原假设,没有足够证据表明setosa和versicolor种类的花瓣长度有显著差异。") # 可视化 plt.figure(figsize=(10, 6)) sns.boxplot(x='species', y='petal_length', data=iris[iris['species'].isin(['setosa', 'versicolor'])]) plt.title('Setosa和Versicolor种类花瓣长度的比较') plt.show() 配对样本t检验
配对样本t检验用于比较同一组对象在两种不同条件下的测量值是否有显著差异。
# 创建一个示例数据集 np.random.seed(42) before_treatment = np.random.normal(loc=100, scale=15, size=30) after_treatment = before_treatment + np.random.normal(loc=-5, scale=5, size=30) # 进行配对样本t检验 t_stat, p_value = stats.ttest_rel(before_treatment, after_treatment) print("n配对样本t检验结果:") print(f"t统计量: {t_stat:.4f}") print(f"p值: {p_value:.4f}") # 解释结果 if p_value < alpha: print("结论:拒绝原假设,治疗前后的测量值有显著差异。") else: print("结论:不拒绝原假设,没有足够证据表明治疗前后的测量值有显著差异。") # 可视化 plt.figure(figsize=(10, 6)) plt.plot(before_treatment, after_treatment, 'o') plt.plot([before_treatment.min(), before_treatment.max()], [before_treatment.min(), before_treatment.max()], 'r--') plt.xlabel('治疗前') plt.ylabel('治疗后') plt.title('治疗前后的测量值比较') plt.show() 方差分析(ANOVA)
方差分析用于比较三个或更多组的均值是否有显著差异。
单因素方差分析
# 比较三种鸢尾花的花瓣长度是否有显著差异 setosa = iris[iris['species'] == 'setosa']['petal_length'] versicolor = iris[iris['species'] == 'versicolor']['petal_length'] virginica = iris[iris['species'] == 'virginica']['petal_length'] # 进行单因素方差分析 f_stat, p_value = stats.f_oneway(setosa, versicolor, virginica) print("单因素方差分析结果:") print(f"F统计量: {f_stat:.4f}") print(f"p值: {p_value:.4f}") # 解释结果 if p_value < alpha: print("结论:拒绝原假设,至少有两种鸢尾花的花瓣长度有显著差异。") else: print("结论:不拒绝原假设,没有足够证据表明不同种类鸢尾花的花瓣长度有显著差异。") # 可视化 plt.figure(figsize=(10, 6)) sns.boxplot(x='species', y='petal_length', data=iris) plt.title('三种鸢尾花花瓣长度的比较') plt.show() # 如果ANOVA显著,可以进行事后检验(如Tukey HSD)来确定哪些组之间有差异 from statsmodels.stats.multicomp import pairwise_tukeyhsd # 进行Tukey HSD检验 tukey = pairwise_tukeyhsd(endog=iris['petal_length'], groups=iris['species'], alpha=0.05) print("nTukey HSD检验结果:") print(tukey) 卡方检验
卡方检验用于检验分类变量之间的独立性。
# 创建一个列联表,观察泰坦尼克号数据集中性别和生存状态之间的关系 contingency_table = pd.crosstab(titanic_clean['sex'], titanic_clean['survived']) print("性别与生存状态的列联表:") print(contingency_table) # 进行卡方检验 chi2, p_value, dof, expected = stats.chi2_contingency(contingency_table) print("n卡方检验结果:") print(f"卡方统计量: {chi2:.4f}") print(f"p值: {p_value:.4f}") print(f"自由度: {dof}") # 解释结果 if p_value < alpha: print("结论:拒绝原假设,性别与生存状态之间存在显著关联。") else: print("结论:不拒绝原假设,没有足够证据表明性别与生存状态之间存在显著关联。") # 可视化 plt.figure(figsize=(10, 6)) sns.heatmap(contingency_table, annot=True, fmt='d', cmap='YlGnBu') plt.title('性别与生存状态的关系') plt.xlabel('生存状态') plt.ylabel('性别') plt.show() 相关性检验
相关性检验用于检验两个连续变量之间是否存在显著的相关关系。
Pearson相关系数检验
# 检验波士顿房价数据集中房间数量(RM)与房价(PRICE)之间的相关性 rm = boston_df['RM'] price = boston_df['PRICE'] # 计算Pearson相关系数和p值 corr_coef, p_value = stats.pearsonr(rm, price) print("Pearson相关系数检验结果:") print(f"相关系数: {corr_coef:.4f}") print(f"p值: {p_value:.4f}") # 解释结果 if p_value < alpha: print("结论:拒绝原假设,房间数量与房价之间存在显著的相关关系。") else: print("结论:不拒绝原假设,没有足够证据表明房间数量与房价之间存在显著的相关关系。") # 可视化 plt.figure(figsize=(10, 6)) sns.regplot(x='RM', y='PRICE', data=boston_df, scatter_kws={'alpha':0.3}) plt.title('房间数量与房价的关系') plt.xlabel('房间数量') plt.ylabel('房价') plt.show() Spearman等级相关检验
# 检验波士顿房价数据集中房间数量(RM)与房价(PRICE)之间的Spearman等级相关 corr_coef, p_value = stats.spearmanr(rm, price) print("nSpearman等级相关检验结果:") print(f"相关系数: {corr_coef:.4f}") print(f"p值: {p_value:.4f}") # 解释结果 if p_value < alpha: print("结论:拒绝原假设,房间数量与房价之间存在显著的等级相关关系。") else: print("结论:不拒绝原假设,没有足够证据表明房间数量与房价之间存在显著的等级相关关系。") 综合案例
在本节中,我们将应用前面学习的知识,对一个完整的数据集进行全面的统计分析。我们将使用鸢尾花数据集,回答以下研究问题:
- 不同种类鸢尾花的四个特征(花萼长度、花萼宽度、花瓣长度、花瓣宽度)是否存在显著差异?
- 这些特征之间是否存在相关关系?
- 是否可以基于这些特征构建一个简单的分类模型来预测鸢尾花的种类?
数据探索
首先,让我们对数据进行基本的探索:
# 加载数据 iris = sns.load_dataset('iris') # 查看数据的基本信息 print("数据集基本信息:") print(iris.info()) # 查看描述性统计信息 print("n描述性统计信息:") print(iris.describe()) # 检查缺失值 print("n缺失值检查:") print(iris.isnull().sum()) # 查看各个种类的数量 print("n各个种类的数量:") print(iris['species'].value_counts()) 数据可视化
让我们通过可视化来更好地理解数据:
# 绘制散点图矩阵 sns.pairplot(iris, hue='species') plt.suptitle('鸢尾花数据集的散点图矩阵', y=1.02) plt.show() # 绘制箱线图 plt.figure(figsize=(12, 8)) for i, feature in enumerate(iris.columns[:-1], 1): plt.subplot(2, 2, i) sns.boxplot(x='species', y=feature, data=iris) plt.title(f'{feature}的分布') plt.tight_layout() plt.show() # 绘制相关性热力图 plt.figure(figsize=(10, 8)) correlation_matrix = iris.corr() sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', linewidths=0.5) plt.title('鸢尾花特征的相关性热力图') plt.show() 假设检验
现在,让我们进行一系列的假设检验来回答我们的研究问题。
不同种类鸢尾花的特征是否存在显著差异?
我们可以使用单因素方差分析来检验不同种类鸢尾花的各个特征是否存在显著差异:
# 对每个特征进行单因素方差分析 features = iris.columns[:-1] for feature in features: print(f"n{feature}的单因素方差分析结果:") # 提取每种鸢尾花的特征数据 setosa = iris[iris['species'] == 'setosa'][feature] versicolor = iris[iris['species'] == 'versicolor'][feature] virginica = iris[iris['species'] == 'virginica'][feature] # 进行单因素方差分析 f_stat, p_value = stats.f_oneway(setosa, versicolor, virginica) print(f"F统计量: {f_stat:.4f}") print(f"p值: {p_value:.4f}") # 解释结果 if p_value < alpha: print("结论:拒绝原假设,不同种类鸢尾花的该特征有显著差异。") # 如果ANOVA显著,进行Tukey HSD检验 tukey = pairwise_tukeyhsd(endog=iris[feature], groups=iris['species'], alpha=0.05) print("nTukey HSD检验结果:") print(tukey) else: print("结论:不拒绝原假设,没有足够证据表明不同种类鸢尾花的该特征有显著差异。") 这些特征之间是否存在相关关系?
我们可以使用Pearson相关系数检验来检验特征之间的相关关系:
# 计算特征之间的相关系数 print("n特征之间的相关系数:") print(iris.corr()) # 对显著的相关关系进行检验 print("n相关关系检验结果:") features = iris.columns[:-1] for i in range(len(features)): for j in range(i+1, len(features)): feature1 = features[i] feature2 = features[j] # 计算Pearson相关系数和p值 corr_coef, p_value = stats.pearsonr(iris[feature1], iris[feature2]) # 如果相关关系显著,则输出结果 if p_value < alpha: print(f"{feature1}和{feature2}:") print(f"相关系数: {corr_coef:.4f}") print(f"p值: {p_value:.4f}") print("结论:拒绝原假设,这两个特征之间存在显著的相关关系。n") 构建简单的分类模型
最后,让我们尝试构建一个简单的分类模型来预测鸢尾花的种类。我们将使用逻辑回归和决策树作为示例。
数据准备
from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler, LabelEncoder from sklearn.linear_model import LogisticRegression from sklearn.tree import DecisionTreeClassifier from sklearn.metrics import accuracy_score, classification_report, confusion_matrix # 准备特征和目标变量 X = iris.drop('species', axis=1) y = iris['species'] # 将目标变量编码为数值 le = LabelEncoder() y = le.fit_transform(y) # 分割数据集为训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) # 标准化特征 scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) 逻辑回归模型
# 构建逻辑回归模型 logreg = LogisticRegression(random_state=42) logreg.fit(X_train_scaled, y_train) # 在测试集上进行预测 y_pred = logreg.predict(X_test_scaled) # 评估模型 accuracy = accuracy_score(y_test, y_pred) print(f"逻辑回归模型的准确率: {accuracy:.4f}") # 打印分类报告 print("n分类报告:") print(classification_report(y_test, y_pred, target_names=le.classes_)) # 绘制混淆矩阵 plt.figure(figsize=(8, 6)) cm = confusion_matrix(y_test, y_pred) sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=le.classes_, yticklabels=le.classes_) plt.title('逻辑回归模型的混淆矩阵') plt.xlabel('预测类别') plt.ylabel('真实类别') plt.show() 决策树模型
# 构建决策树模型 dt = DecisionTreeClassifier(random_state=42) dt.fit(X_train, y_train) # 决策树不需要特征标准化 # 在测试集上进行预测 y_pred_dt = dt.predict(X_test) # 评估模型 accuracy_dt = accuracy_score(y_test, y_pred_dt) print(f"决策树模型的准确率: {accuracy_dt:.4f}") # 打印分类报告 print("n分类报告:") print(classification_report(y_test, y_pred_dt, target_names=le.classes_)) # 绘制混淆矩阵 plt.figure(figsize=(8, 6)) cm_dt = confusion_matrix(y_test, y_pred_dt) sns.heatmap(cm_dt, annot=True, fmt='d', cmap='Blues', xticklabels=le.classes_, yticklabels=le.classes_) plt.title('决策树模型的混淆矩阵') plt.xlabel('预测类别') plt.ylabel('真实类别') plt.show() # 可视化决策树 from sklearn.tree import plot_tree plt.figure(figsize=(20, 10)) plot_tree(dt, filled=True, feature_names=X.columns, class_names=le.classes_) plt.title('决策树可视化') plt.show() 模型比较
让我们比较这两个模型的性能:
# 比较两个模型的准确率 models = ['逻辑回归', '决策树'] accuracies = [accuracy, accuracy_dt] plt.figure(figsize=(8, 6)) sns.barplot(x=models, y=accuracies) plt.title('模型准确率比较') plt.ylabel('准确率') plt.ylim(0, 1) for i, acc in enumerate(accuracies): plt.text(i, acc + 0.01, f'{acc:.4f}', ha='center') plt.show() 总结与展望
本教程通过真实数据案例,详细介绍了如何使用Python pandas进行数据处理、描述统计和假设检验。我们学习了:
数据处理:包括数据清洗(处理缺失值、重复值和异常值)、数据转换(类型转换、标准化/归一化、虚拟变量编码)、数据整合以及数据分组与聚合。
描述统计:包括集中趋势测量(均值、中位数、众数)、离散程度测量(极差、方差、标准差、四分位距)、分布形态(偏度、峰度)以及相关性分析。
假设检验:包括t检验(单样本t检验、独立样本t检验、配对样本t检验)、方差分析(单因素方差分析)、卡方检验以及相关性检验(Pearson相关系数检验、Spearman等级相关检验)。
综合案例:通过鸢尾花数据集,我们应用了前面学习的知识,进行了全面的数据分析,并构建了简单的分类模型。
通过本教程,你应该已经掌握了使用Python pandas进行统计分析的核心技能。这些技能可以帮助你处理各种数据分析问题,从数据清洗到高级统计分析。
未来学习方向
如果你想进一步深入学习,可以考虑以下方向:
高级统计方法:学习更多的高级统计方法,如多元回归分析、时间序列分析、非参数检验等。
机器学习:深入学习机器学习算法,如支持向量机、随机森林、神经网络等。
大数据处理:学习如何使用Spark、Dask等工具处理大规模数据集。
数据可视化:学习更高级的数据可视化技术,如交互式可视化、地理信息系统(GIS)可视化等。
特定领域的统计分析:根据你的兴趣或专业需求,学习特定领域的统计分析方法,如生物统计学、金融统计学、社会科学统计学等。
希望本教程能够帮助你建立坚实的统计分析基础,并激发你进一步学习和探索的兴趣。记住,实践是最好的老师,继续使用真实数据集进行分析和实验,不断提高你的技能!
支付宝扫一扫
微信扫一扫