某快餐店用户市场数据挖掘与可视化

server/2025/3/19 15:31:03/

1、必要库的载入

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

2、加载并清洗数据

# 2.1 加载数据
df = pd.read_csv('/home/mw/input/survey6263/mcdonalds.csv')# 2.2 数据清洗
# 2.2.1 检查缺失值
print('缺失值情况:')
print(df.isnull().sum())
# 2.2.2 处理异常值(年龄范围在18 - 100岁为合理范围)
df = df[(df['Age'] >= 18) & (df['Age'] <= 100)]# 查看数据集行数和列数
rows, columns = df.shapeif rows < 100 and columns < 20:# 短表数据(行数少于100且列数少于20)查看全量数据信息print('数据全部内容信息:')print(df.to_csv(sep='\t', na_rep='nan'))
else:# 长表数据查看数据前几行信息print('数据前几行内容信息:')print(df.head().to_csv(sep='\t', na_rep='nan'))

在这里插入图片描述

3、可视化设置

# 3.1 设置图片清晰度
plt.rcParams['figure.dpi'] = 300
# 3.2 设置中文字体
plt.rcParams['font.sans-serif'] = ['WenQuanYi Zen Hei']
# 3.3 解决负号显示问题
plt.rcParams['axes.unicode_minus'] = False

4、顾客基础特征分析

4.1 顾客年龄分布和性别分布

import matplotlib.pyplot as plt
import seaborn as sns# 年龄分布
plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.histplot(df['Age'], bins=20, kde=False)
plt.title('Age distribution')# 性别分布
plt.subplot(1, 2, 2)
gender_counts = df['Gender'].value_counts()
sns.barplot(x=gender_counts.index, y=gender_counts.values)
plt.title('Gender distribution')plt.tight_layout()
plt.show()print('顾客年龄分布:')
print(df['Age'].describe())
print('\n顾客性别分布:')
print(df['Gender'].value_counts())

在这里插入图片描述
在这里插入图片描述

4.1.1 年龄分布

4.2 顾客光顾频率与年龄、性别的关系

plt.figure(figsize=(12, 6))
plt.subplot(1, 2, 1)
sns.boxplot(x='VisitFrequency', y='Age', data=df)
plt.title('Frequency VS Age')
plt.xticks(rotation=45)plt.subplot(1, 2, 2)
sns.countplot(x='VisitFrequency', hue='Gender', data=df)
plt.title('Frequency VS Gender')
plt.xticks(rotation=45)plt.tight_layout()
plt.show()print('光顾频率与年龄的关系:')
print(df.groupby('VisitFrequency')['Age'].describe())
print('\n光顾频率与性别的关系:')
print(pd.crosstab(df['VisitFrequency'], df['Gender']))

在这里插入图片描述
在这里插入图片描述

4.2.1 光顾频率与年龄的关系

4.3 顾客对某快餐店各方面评价的分布

# 提取评价列
evaluation_columns = ['yummy', 'convenient', 'spicy', 'fattening', 'greasy', 'fast', 'cheap', 'tasty', 'expensive', 'healthy', 'disgusting']# 创建画布
plt.figure(figsize=(15, 10))# 绘制每个评价的分布柱状图
for i, column in enumerate(evaluation_columns):plt.subplot(3, 4, i + 1)value_counts = df[column].value_counts()sns.barplot(x=value_counts.index, y=value_counts.values)plt.title(f'{column} distribution')plt.tight_layout()
plt.show()# 查看每个评价的分布情况
for column in evaluation_columns:print(f'{column}评价分布:')print(df[column].value_counts())

在这里插入图片描述
在这里插入图片描述

4.4 顾客喜好与各评价之间的相关性

import re# 使用正则表达式提取 Like 列中的数字部分并转换为数值型
df['Like'] = df['Like'].apply(lambda x: int(re.findall(r'\d+', x)[0]))# 将评价列进行编码
for column in evaluation_columns:df[column] = df[column].map({'Yes': 1, 'No': 0})# 计算相关系数矩阵
correlation_matrix = df[evaluation_columns + ['Like']].corr()# 绘制热力图
plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', vmin=-1, vmax=1)
plt.title('Customer preferences VS Reviews')
plt.show()print('顾客喜好与各评价之间的相关系数矩阵:')
print(correlation_matrix.round(2))

在这里插入图片描述
在这里插入图片描述

5、顾客口味偏好分析

import matplotlib.pyplot as plt# 统计口味相关特征的分布(选取 spicy, yummy, tasty, greasy 作为口味相关特征)
taste_features = ['spicy', 'yummy', 'tasty', 'greasy']
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
axes = axes.ravel()for i, feature in enumerate(taste_features):value_counts = df[feature].value_counts()axes[i].pie(value_counts, labels=value_counts.index, autopct='%1.1f%%', startangle=90)axes[i].set_title(f'{feature} distribution')plt.tight_layout()
plt.show()# 查看具体比例
for feature in taste_features:print(df[feature].value_counts(normalize=True))

在这里插入图片描述

6、价格敏感性分析

# 统计认为便宜和昂贵的比例
cheap_counts = df['cheap'].value_counts(normalize=True)
expensive_counts = df['expensive'].value_counts(normalize=True)# 绘制柱状图
fig, axes = plt.subplots(1, 2, figsize=(10, 5))axes[0].bar(cheap_counts.index, cheap_counts)
axes[0].set_title('Thinking cheap')
axes[0].set_xlabel('cheap or not')
axes[0].set_ylabel('scale')axes[1].bar(expensive_counts.index, expensive_counts)
axes[1].set_title('Thinking expensive')
axes[1].set_xlabel('expensive or not')
axes[1].set_ylabel('scale')plt.tight_layout()
plt.show()print("认为便宜的比例:")
print(cheap_counts)
print("认为昂贵的比例:")
print(expensive_counts)

在这里插入图片描述

7、消费频率预测

from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score# 对 object 类型数据进行编码
label_encoders = {}
for column in df.columns:if df[column].dtype == 'object':le = LabelEncoder()df[column] = le.fit_transform(df[column])label_encoders[column] = le# 准备特征和目标变量
X = df.drop(['VisitFrequency', 'Index'], axis=1)
y = df['VisitFrequency']# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
from sklearn.ensemble import RandomForestClassifier
from sklearn.svm import SVC
from sklearn.metrics import accuracy_score, classification_report# 定义不同的模型
models = {'Logistic Regression': LogisticRegression(max_iter=1000),'Decision Tree': DecisionTreeClassifier(),'Random Forest': RandomForestClassifier(),'Support Vector Machine': SVC()
}# 训练和评估每个模型
for name, model in models.items():model.fit(X_train, y_train)y_pred = model.predict(X_test)accuracy = accuracy_score(y_test, y_pred)print(f'{name} 准确率: {accuracy:.4f}')print(f'{name} 分类报告:\n', classification_report(y_test, y_pred))print('-' * 50)

在这里插入图片描述

8、顾客画像分类

8.1 确定最佳簇数

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score# 尝试不同的簇数
silhouette_scores = []
for k in range(2, 11):kmeans = KMeans(n_clusters=k, random_state=42)kmeans.fit(X)labels = kmeans.labels_score = silhouette_score(X, labels)silhouette_scores.append((k, score))# 找到最高轮廓系数对应的簇数
best_k, _ = max(silhouette_scores, key=lambda x: x[1])
print(f'最佳簇数: {best_k}')

在这里插入图片描述

8.2 不同簇的特征分析

# 使用最佳簇数进行 KMeans 聚类
kmeans = KMeans(n_clusters=best_k, random_state=42)
df['Cluster'] = kmeans.fit_predict(X)# 分析不同簇的特征(以年龄和喜欢程度为例)
cluster_analysis = df.groupby('Cluster').agg({'Age': 'mean','Like': 'mean'
}).reset_index()print(cluster_analysis)

在这里插入图片描述
从年龄均值来看,簇 0 的顾客相对年轻,平均年龄约为 31 岁,而簇 1 的顾客平均年龄约为 56 岁,两者存在明显的年龄差异。在喜欢程度方面,两个簇的均值都比较高且较为接近,不过簇 1 的喜欢程度均值略高于簇 0,这可能暗示年龄较大的顾客对相关事物的喜欢程度稍高一些,但差异并不是非常显著。

8.3 不同簇的年龄和喜欢程度分布可视化

# 绘制不同簇的年龄和喜欢程度分布
plt.scatter(df['Age'], df['Like'], c=df['Cluster'])
plt.xlabel('Age')
plt.xticks(rotation=45)
plt.ylabel('Liking degree')
plt.title('Age VS liking of different clusters')
plt.show()

在这里插入图片描述

# 若需要完整数据集以及代码请点击以下链接
# https://mbd.pub/o/bread/mbd-aJaUlJpt

http://www.ppmy.cn/server/176275.html

相关文章

C++特性——智能指针

为什么需要智能指针 对于定义的局部变量&#xff0c;当作用域结束之后&#xff0c;就会自动回收&#xff0c;这没有什么问题。 当时用new delete的时候&#xff0c;就是动态分配对象的时候&#xff0c;如果new了一个变量&#xff0c;但却没有delete&#xff0c;这会造成内存泄…

【canvas】一键自动布局:如何让流程图节点自动找到最佳位置

一键自动布局&#xff1a;如何让流程图节点自动找到最佳位置 引言 在流程图、拓扑图和系统架构图设计中&#xff0c;节点布局往往是最令人头疼的问题。如果手动调整每个节点位置&#xff0c;不仅耗时费力&#xff0c;还难以保证美观性和一致性。本文将深入解析如何实现自动布…

flutter 专题 九十八 Flutter 1.7正式版发布

此次发布的版本是继上次 I/O大会众多重要功能发布以来的一次小更新。Flutter 1.7 包含了对 AndroidX 的支持&#xff0c;满足了 Play 商店近期对应用提出的要求&#xff0c;包含了一些新的和增强过的组件&#xff0c;修复了开发者们提出的 bug 等。 如果你已经安装并使用默认稳…

Paper Reading: AnomalyGPT:利用大型视觉-语言模型检测工业异常 (AAAI 2024 Oral)

目录 简介动机/目标相关工作基于特征嵌入的方法 feature embedding-based基于重建的方法 reconstruction-based 方法3.1 模型架构3.2 译码器和提示学习器3.3 图像-文本对齐数据异常生成 3.4 损失函数 实验比较消融 总结AppendixA. 现有IAD方法的更多实验结果B. 正常与异常文本C…

不像人做的题————十四届蓝桥杯省赛真题解析(上)A,B,C,D题解析

题目A&#xff1a;日期统计 思路分析&#xff1a; 本题的题目比较繁琐&#xff0c;我们采用暴力加DFS剪枝的方式去做&#xff0c;我们在DFS中按照8位日期的每一个位的要求进行初步剪枝找出所有的八位子串&#xff0c;但是还是会存在19月的情况&#xff0c;为此还需要在CHECK函数…

第六章-PHP错误处理

PHP错误处理 一&#xff0c;错误处理的基本概念&#xff1a; 1. 错误类型 PHP中的错误主要分为以下几类&#xff1a; 致命错误 (Fatal Errors): 这些错误会导致脚本终止执行。例如&#xff0c;调用未定义的函数或类。警告 (Warnings): 这些错误不会终止脚本执行&#xff0c…

MrRobot靶机详细解答

一、主机发现 arp-scan -l二、端口扫描、目录枚举、指纹识别 2.1端口扫描 nmap -p- 192.168.55.147发现22端口关闭&#xff0c;且无其它特殊端口&#xff0c;只能去网页中寻找信息 2.2目录枚举 dirb http://192.168.55.1472.3指纹识别 nmap 192.168.55.147 -sV -sC -O --…

Unity WebGL IIS报错无法使用

Unity WebGL IIS报错无法使用 原因1&#xff1a;WebGL文件夹无访问权限 右键WebGL文件夹-属性 点击安全-编辑-添加 输入ever点击确定-应用即可