数据分析项目实战:完整案例从数据获取到洞察发现

举报
数字扫地僧 发表于 2025/08/22 17:11:03 2025/08/22
【摘要】 数据分析不仅仅是处理数字,更是关于讲述数据背后的故事。通过这个项目,你将学会如何获取数据、清洗数据、探索数据、构建模型,并从中提取有价值的业务洞察。我们将使用Python作为主要工具,因为它拥有强大的库生态系统,适合处理各种数据分析任务。 I. 项目介绍在这个项目中,我们将分析一个电子商务公司的销售数据。该公司销售各种电子产品,数据包括订单信息、产品详情、客户信息和销售时间等。我们的目标是探...

数据分析不仅仅是处理数字,更是关于讲述数据背后的故事。通过这个项目,你将学会如何获取数据、清洗数据、探索数据、构建模型,并从中提取有价值的业务洞察。我们将使用Python作为主要工具,因为它拥有强大的库生态系统,适合处理各种数据分析任务。

I. 项目介绍

在这个项目中,我们将分析一个电子商务公司的销售数据。该公司销售各种电子产品,数据包括订单信息、产品详情、客户信息和销售时间等。我们的目标是探索销售趋势、客户行为,并构建一个预测模型来预测未来销售额。通过这个分析,我们可以为业务决策提供支持,比如优化库存管理、制定营销策略等。

为什么选择这个项目?电子商务数据是典型的多维数据,包含数值、分类和时间序列数据,非常适合展示数据分析的全流程。此外,分析结果可以直接转化为业务行动,凸显数据分析的实际价值。

项目的主要步骤包括:

  • 数据获取:从本地文件或模拟数据源加载数据。
  • 数据清洗:处理缺失值、异常值和数据格式问题。
  • 探索性数据分析(EDA):通过统计和可视化理解数据分布和关系。
  • 数据建模:构建时间序列预测模型或分类模型。
  • 洞察发现:解释结果并提出业务建议。

为了更直观地理解项目结构,这里有一个Mermaid图总结本章内容。

Lexical error on line 6. Unrecognized text. ...行为] C --> F[数据清洗、EDA、建模] D --> G ----------------------^

现在,让我们进入下一章,设置环境并获取数据。

II. 环境设置和数据获取

首先,我们需要设置Python环境并安装必要的库。然后,我们将获取数据。由于真实数据可能涉及隐私,我们将使用模拟的电子商务数据,但这个过程与处理真实数据类似。

环境设置

我推荐使用Anaconda来管理Python环境,因为它预装了许多数据科学库。如果你还没有安装,可以从Anaconda官网下载(注意:博客不能带网址,所以请自行搜索)。安装后,创建一个新的Conda环境或使用基础环境。

安装必要库的命令如下(在终端中运行):

pip install pandas numpy matplotlib seaborn scikit-learn statsmodels

这些库将帮助我们进行数据处理、可视化、建模和时间序列分析。

数据获取

我们将模拟一个电子商务数据集,包含以下字段:

  • order_id: 订单ID
  • product_id: 产品ID
  • customer_id: 客户ID
  • order_date: 订单日期
  • quantity: 购买数量
  • unit_price: 产品单价
  • total_price: 总价(quantity * unit_price)
  • category: 产品类别

由于不能使用真实网址,我们将用Python代码生成模拟数据。这样,你可以直接复现这个项目。

以下是生成模拟数据的代码:

import pandas as pd
import numpy as np
from datetime import datetime, timedelta

# 设置随机种子以确保可复现性
np.random.seed(42)

# 生成日期范围:过去365天
dates = [datetime.now() - timedelta(days=i) for i in range(365)]
dates.sort()

# 生成模拟数据
num_records = 10000
data = {
    'order_id': np.arange(1, num_records + 1),
    'product_id': np.random.randint(1, 101, size=num_records),
    'customer_id': np.random.randint(1, 501, size=num_records),
    'order_date': np.random.choice(dates, size=num_records),
    'quantity': np.random.randint(1, 11, size=num_records),
    'unit_price': np.round(np.random.uniform(10, 1000, size=num_records), 2),
    'category': np.random.choice(['Electronics', 'Clothing', 'Home', 'Books'], size=num_records)
}

# 计算总价
data['total_price'] = data['quantity'] * data['unit_price']

# 创建DataFrame
df = pd.DataFrame(data)

# 保存到CSV文件(可选,便于后续使用)
df.to_csv('ecommerce_sales.csv', index=False)

print("数据形状:", df.shape)
print(df.head())

代码解释

  • 我们使用pandasnumpy生成模拟数据。datetime用于生成日期。
  • 数据包含10000条记录,覆盖过去365天的销售数据。
  • 字段包括订单ID、产品ID、客户ID、订单日期、数量、单价、类别和总价。
  • 最后,将数据保存为CSV文件,以便后续步骤使用。head()函数显示前几行数据,帮助验证数据生成是否正确。

现在,数据已经准备好,我们可以进入数据清洗阶段。用Mermaid图总结这一章。

环境设置和数据获取
安装库: pandas, numpy等
生成模拟数据
保存为CSV文件
使用pip安装
使用numpy和pandas
便于后续使用

数据获取是第一步,接下来我们需要清洗数据以确保质量。

III. 数据清洗和预处理

数据清洗是数据分析中至关重要的一步,因为原始数据往往包含缺失值、异常值或不一致的格式。在这一章,我们将清洗和预处理模拟的电子商务数据,为后续分析做好准备。

数据加载

首先,加载之前生成的CSV文件(如果你没有保存,可以直接使用上面的代码生成DataFrame)。

# 加载数据
df = pd.read_csv('ecommerce_sales.csv')
print("初始数据形状:", df.shape)
print(df.info())

检查数据问题

我们需要检查以下常见问题:

  • 缺失值:某些字段是否有空值。
  • 异常值:数值字段是否在合理范围内。
  • 数据类型:日期字段是否正确的日期格式。

使用以下代码检查缺失值:

print("缺失值统计:")
print(df.isnull().sum())

由于数据是模拟的,可能没有缺失值,但真实数据中常见缺失值。如果有缺失值,我们需要处理它们。

处理缺失值

假设我们在unit_price字段中有一些缺失值(尽管模拟数据中没有,但为了演示,我们随机引入一些缺失值)。

# 随机引入一些缺失值用于演示
np.random.seed(42)
missing_indices = np.random.choice(df.index, size=100, replace=False)
df.loc[missing_indices, 'unit_price'] = np.nan

# 检查缺失值
print("引入缺失值后的统计:")
print(df.isnull().sum())

# 处理缺失值:用中位数填充
median_price = df['unit_price'].median()
df['unit_price'].fillna(median_price, inplace=True)

# 重新计算total_price,因为unit_price可能被填充
df['total_price'] = df['quantity'] * df['unit_price']

print("处理后缺失值统计:")
print(df.isnull().sum())

代码解释

  • 我们随机选择100个索引,将unit_price设置为NaN来模拟缺失值。
  • 用中位数填充缺失值,因为中位数对异常值不敏感。
  • 由于total_price依赖于unit_price,我们重新计算它以确保一致性。

处理异常值

检查数值字段(如quantity、unit_price)的异常值。例如,数量应为正数,单价应在合理范围内。

# 检查数量的异常值
print("数量描述:")
print(df['quantity'].describe())

# 假设数量大于10为异常值,将其限制为10
df['quantity'] = df['quantity'].apply(lambda x: x if x <= 10 else 10)

# 检查单价的异常值
print("单价描述:")
print(df['unit_price'].describe())

# 假设单价低于10或高于1000为异常值,用中位数替换
median_price = df['unit_price'].median()
df['unit_price'] = df['unit_price'].apply(lambda x: x if 10 <= x <= 1000 else median_price)

# 重新计算total_price
df['total_price'] = df['quantity'] * df['unit_price']

代码解释

  • 使用describe()函数查看数值字段的统计摘要,识别异常值。
  • 对于数量,我们将大于10的值截断为10,因为模拟数据中数量范围是1到10,但真实数据可能有错误。
  • 对于单价,我们将超出合理范围的值用中位数替换。
  • 最后,重新计算总价。

日期格式转换

确保order_date是日期类型,并提取有用的时间特征。

# 转换日期格式
df['order_date'] = pd.to_datetime(df['order_date'])

# 提取年份、月份、星期几等特征
df['order_year'] = df['order_date'].dt.year
df['order_month'] = df['order_date'].dt.month
df['order_day'] = df['order_date'].dt.day
df['day_of_week'] = df['order_date'].dt.dayofweek  # 0=Monday, 6=Sunday

print(df[['order_date', 'order_year', 'order_month', 'day_of_week']].head())

代码解释

  • 使用pd.to_datetime将字符串日期转换为Pandas的日期类型。
  • 提取年份、月份、日期和星期几,这些特征可用于时间序列分析。

数据清洗完成后,我们保存清洗后的数据供后续使用。

# 保存清洗后的数据
df.to_csv('cleaned_ecommerce_sales.csv', index=False)

现在,数据已经干净且格式一致。用Mermaid图总结这一章。

数据清洗和预处理
加载数据
检查缺失值
处理缺失值: 填充
处理异常值: 截断或替换
日期转换和特征提取
使用pandas
使用isnull
用中位数填充
应用lambda函数
提取时间特征

数据清洗是确保分析准确性的基础。接下来,我们将进行探索性数据分析。

IV. 探索性数据分析(EDA)

探索性数据分析(EDA)是通过统计摘要和可视化来理解数据分布、关系和模式的过程。在这一章,我们将对清洗后的电子商务数据进行分析,探索销售趋势、客户行为和产品类别表现。

整体数据概览

首先,查看清洗后数据的基本信息。

# 加载清洗后的数据
df = pd.read_csv('cleaned_ecommerce_sales.csv')

# 基本统计摘要
print("数值字段描述:")
print(df[['quantity', 'unit_price', 'total_price']].describe())

# 类别字段的频次
print("类别分布:")
print(df['category'].value_counts())

销售趋势分析

分析销售额随时间的变化,识别季节性模式。

# 按日期聚合每日销售额
daily_sales = df.groupby('order_date')['total_price'].sum().reset_index()

# 绘制时间序列图
import matplotlib.pyplot as plt
plt.figure(figsize=(12, 6))
plt.plot(daily_sales['order_date'], daily_sales['total_price'])
plt.title('Daily Sales Trend')
plt.xlabel('Date')
plt.ylabel('Total Sales')
plt.grid(True)
plt.show()

代码解释

  • 使用groupby按日期分组,计算每日销售总额。
  • 使用matplotlib绘制折线图,显示销售额随时间的变化。这有助于识别趋势和季节性。

客户行为分析

探索客户购买行为,比如每个客户的平均订单价值。

# 按客户聚合购买行为
customer_behavior = df.groupby('customer_id').agg({
    'total_price': 'sum',
    'order_id': 'count',
    'quantity': 'sum'
}).rename(columns={'order_id': 'order_count', 'quantity': 'total_quantity'})

# 计算平均订单价值
customer_behavior['average_order_value'] = customer_behavior['total_price'] / customer_behavior['order_count']

print("客户行为描述:")
print(customer_behavior.describe())

# 绘制客户订单数量的直方图
plt.figure(figsize=(10, 6))
plt.hist(customer_behavior['order_count'], bins=20, alpha=0.7)
plt.title('Distribution of Order Count per Customer')
plt.xlabel('Order Count')
plt.ylabel('Frequency')
plt.show()

代码解释

  • 按客户ID分组,计算每个客户的总销售额、订单数量和总购买数量。
  • 计算平均订单价值(AOV),即总销售额除以订单数量。
  • 绘制直方图显示客户订单数量的分布,了解客户活跃度。

产品类别分析

分析不同产品类别的销售表现。

# 按类别聚合销售额和数量
category_performance = df.groupby('category').agg({
    'total_price': 'sum',
    'quantity': 'sum'
}).rename(columns={'total_price': 'total_sales', 'quantity': 'total_quantity'})

# 计算每个类别的平均单价
category_performance['average_unit_price'] = category_performance['total_sales'] / category_performance['total_quantity']

print("类别表现:")
print(category_performance)

# 绘制类别销售额的饼图
plt.figure(figsize=(8, 8))
plt.pie(category_performance['total_sales'], labels=category_performance.index, autopct='%1.1f%%')
plt.title('Sales Distribution by Category')
plt.show()

代码解释

  • 按产品类别分组,计算总销售额和总数量。
  • 计算每个类别的平均单价。
  • 使用饼图显示销售额的类别分布,直观展示哪些类别贡献最大。

相关性分析

检查数值字段之间的相关性。

# 计算相关系数矩阵
correlation_matrix = df[['quantity', 'unit_price', 'total_price']].corr()
print("相关系数矩阵:")
print(correlation_matrix)

# 绘制热力图
import seaborn as sns
plt.figure(figsize=(8, 6))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm')
plt.title('Correlation Heatmap')
plt.show()

代码解释

  • 使用corr()函数计算quantity、unit_price和total_price之间的相关系数。
  • 使用seaborn绘制热力图,颜色越深表示相关性越强。这有助于识别变量之间的关系。

通过EDA,我们获得了对数据的深入理解。用Mermaid图总结这一章。

探索性数据分析
整体概览: 描述统计
销售趋势: 时间序列图
客户行为: 聚合和直方图
产品类别: 饼图和聚合
相关性: 热力图
使用describe
使用groupby和plot
客户分组分析
类别分组分析
计算相关系数

EDA揭示了数据中的模式,接下来我们可以构建预测模型。

V. 数据建模

基于EDA的发现,我们将构建一个预测模型来预测未来销售额。由于销售数据是时间序列,我们使用ARIMA模型(自回归积分滑动平均模型)进行预测。同时,我们也会尝试一个简单的线性回归模型作为对比。

数据准备

首先,我们需要为时间序列预测准备数据。使用每日销售额数据。

# 确保日期是索引
daily_sales = daily_sales.set_index('order_date')

# 检查平稳性(时间序列要求)
from statsmodels.tsa.stattools import adfuller
result = adfuller(daily_sales['total_price'])
print('ADF Statistic:', result[0])
print('p-value:', result[1])

# 如果p值大于0.05,数据非平稳,需差分
if result[1] > 0.05:
    daily_sales['diff'] = daily_sales['total_price'].diff().dropna()
    print("差分后的ADF检验:")
    result_diff = adfuller(daily_sales['diff'].dropna())
    print('ADF Statistic:', result_diff[0])
    print('p-value:', result_diff[1])

代码解释

  • 将日期设置为索引,便于时间序列分析。
  • 使用ADF检验检查平稳性。如果p值大于0.05,数据非平稳,需要进行差分(计算一阶差分)使其平稳。

ARIMA模型

ARIMA是一种常见的时间序列预测模型。我们需要选择参数(p, d, q)。

from statsmodels.tsa.arima.model import ARIMA

# 拆分训练集和测试集(最后30天作为测试集)
train = daily_sales['total_price'][:-30]
test = daily_sales['total_price'][-30:]

# 拟合ARIMA模型
model = ARIMA(train, order=(1,1,1))  # 参数根据ACF/PACF图选择,这里简单示例
model_fit = model.fit()

# 预测
predictions = model_fit.forecast(steps=30)

代码解释

  • 将数据拆分为训练集和测试集,最后30天用于测试。
  • 使用ARIMA(1,1,1)模型拟合训练数据。参数选择通常基于ACF和PACF图,但这里为简化而固定。
  • 预测未来30天的销售额。

线性回归模型

作为对比,我们使用线性回归模型,使用时间特征进行预测。

from sklearn.linear_model import LinearRegression

# 为时间序列创建特征:例如,日期序号
daily_sales['day_index'] = range(len(daily_sales))

# 准备特征和目标变量
X = daily_sales[['day_index']][:-30]
y = daily_sales['total_price'][:-30]
X_test = daily_sales[['day_index']][-30:]

# 训练模型
lr_model = LinearRegression()
lr_model.fit(X, y)

# 预测
lr_predictions = lr_model.predict(X_test)

代码解释

  • 创建日期序号作为特征(因为线性回归需要数值特征)。
  • 使用前335天训练模型,预测最后30天。
  • 线性回归假设线性关系,可能不适合复杂时间序列,但作为基线模型。

模型评估

评估两个模型的性能,使用均方根误差(RMSE)。

from sklearn.metrics import mean_squared_error

# ARIMA模型评估
arima_rmse = np.sqrt(mean_squared_error(test, predictions))
print(f"ARIMA RMSE: {arima_rmse}")

# 线性回归模型评估
lr_rmse = np.sqrt(mean_squared_error(test, lr_predictions))
print(f"Linear Regression RMSE: {lr_rmse}")

# 绘制预测对比图
plt.figure(figsize=(12, 6))
plt.plot(test.index, test, label='Actual')
plt.plot(test.index, predictions, label='ARIMA Predictions')
plt.plot(test.index, lr_predictions, label='Linear Regression Predictions')
plt.legend()
plt.title('Sales Prediction Comparison')
plt.show()

代码解释

  • 计算RMSE来评估模型预测准确性。
  • 绘制实际值与预测值的对比图,直观比较模型性能。

通常,ARIMA模型在时间序列数据上表现更好,但具体结果取决于数据特性。

用Mermaid图总结这一章。

数据建模
数据准备: 平稳性检验
ARIMA模型: 时间序列预测
线性回归: 作为基线
模型评估: RMSE和可视化
使用ADF检验
使用statsmodels
使用sklearn
比较模型性能

建模后,我们需要解释结果并提取业务洞察。

VI. 结果解释和洞察发现

在这一章,我们将解释模型结果,并从分析中提取关键业务洞察。这些洞察可以帮助公司制定更好的策略。

模型结果解释

从预测模型来看,ARIMA模型的RMSE可能低于线性回归,表明ARIMA更适合预测销售额。预测图显示,销售额可能有季节性模式(例如,节假日销售高峰),但我们的简单模型可能没有完全捕捉到。建议使用更复杂的模型,如SARIMA(季节性ARIMA),以更好地处理季节性。

业务洞察

基于EDA和模型,我们提出以下洞察:

洞察点 描述 业务建议
销售趋势 销售额呈现波动上升趋势,但有季节性模式。 在销售高峰期增加库存和营销投入。
客户行为 少数客户贡献大部分销售额(帕累托原则)。 实施忠诚度计划留住高价值客户。
产品类别表现 电子产品类别销售额最高,但平均单价较低。 捆绑销售或促销提高电子产品单价。
预测模型 ARIMA模型预测准确性较高,可用于未来规划。 使用预测结果优化库存管理和预算分配。

这些洞察基于数据,但需要与业务团队验证以确保可行性。

可视化洞察

创建仪表板或报告来呈现发现。例如,使用以下代码绘制关键指标:

# 绘制销售额和预测的最终图表
plt.figure(figsize=(12, 6))
plt.plot(daily_sales.index, daily_sales['total_price'], label='Historical Sales')
plt.plot(test.index, predictions, label='ARIMA Forecast', color='red')
plt.title('Sales Forecast for Next 30 Days')
plt.legend()
plt.show()

# 绘制客户价值分布
plt.figure(figsize=(10, 6))
plt.hist(customer_behavior['total_price'], bins=30, alpha=0.7)
plt.title('Customer Value Distribution')
plt.xlabel('Total Spending')
plt.ylabel('Frequency')
plt.show()

代码解释

  • 第一个图显示历史销售额和ARIMA预测,用于未来规划。
  • 第二个图显示客户价值分布,帮助识别高价值客户。

用Mermaid图总结这一章。

Lexical error on line 3. Unrecognized text. ... A --> C[业务洞察: 从趋势、客户、类别等方面] A --> -----------------------^

这些洞察可以指导业务决策,实现数据驱动运营。

VII. 总结

在这个项目中,我们完成了一个完整的数据分析流程:从数据获取、清洗、EDA、建模到洞察发现。我们使用了Python和多种库,包括pandas、matplotlib、statsmodels和scikit-learn。通过电子商务销售数据的分析,我们展示了如何提取有价值的信息来支持业务决策。

关键 takeaways:

  • 数据清洗是基础,确保数据质量。
  • EDA帮助理解数据模式和关系。
  • 时间序列预测模型(如ARIMA)可用于销售额预测。
  • 洞察发现是分析的最终目的,需转化为业务行动。
数据分析项目实战
数据获取: 模拟数据
数据清洗: 处理缺失和异常
EDA: 探索模式和关系
建模: 时间序列预测
洞察: 业务建议
使用pandas
数据预处理
可视化和统计
使用ARIMA和线性回归
actionable 洞察
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。