ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Python+MySQL数据分析实战:泡泡玛特评论情感分析与可视化

Python+MySQL数据分析实战:泡泡玛特评论情感分析与可视化 做数据分析类项目最怕的不是某个算法不会调包而是数据从哪来、存到哪里、怎么清洗、如何分析、最后怎么汇报整条链路没有形成一个能讲清楚的闭环。很多同学学完 Python 和 MySQL 基础后往往缺一个足够真实、又能跑通全流程的练手项目。本文围绕“泡泡玛特热搜评论”这个场景整理一套基于 Python MySQL 的评论数据分析实战项目覆盖数据构造、预处理、入库、SQL 聚合分析、中文分词统计和可视化展示。如果你是刚开始接触数据分析或者准备把“数据分析项目”写进简历但还没找到一个可复现的案例这篇文章可以照着一行行敲完。项目本身不复杂但把 Python 脚本、MySQL 建表、批量写入、去重策略、文本情感打分和图表绘制串起来恰好是初级数据分析岗位面试中最高频的一类能力。在正式写代码之前先提醒一点招聘方不会因为你贴了一个电商评论项目就发 offer但如果你能把“采集了什么、表怎么设计、数据重复怎么处理、哪些系列讨论热度高、如何用 SQL 和 Python 交叉验证结果”讲清楚这次实战才会真正变成你的项目谈资。1. 项目背景与整体设计1.1 为什么选择泡泡玛特热搜评论作为分析对象泡泡玛特是潮玩领域的典型品牌用户群体活跃评论中经常出现“隐藏款”“端盒”“手感”“瑕疵”“涂装”“售后”等强业务词汇。相比普通商品评论这类评论有三个明显特点文本口语化强包含大量潮玩圈黑话适合练中文分词和词频统计。用户表达的情绪倾向明显喜欢或失望都会直接体现在评论里适合做简单的情感标记。评论背后涉及“系列”“款式”“日期”“点赞数”等结构化字段特别适合用 MySQL 来存储和做多维聚合查询。用这类业务场景做数据分析项目既能练习 Python 数据处理能力也能体现对业务指标的思考而不是只会跑一遍group by。1.2 技术栈与选型理由这次项目主要使用 Python、MySQL以及常用的数据分析第三方库。模块工具说明数据生成/采集Python requests json演示阶段用本地 JSON 作为数据源也可替换为合法授权接口数据清洗pandas去空、去重、时间格式转换、字段扩展中文分词jieba针对中文评论做切词统计高频热词MySQL 连接pymysql执行建表、插入、SQL 查询可视化matplotlib绘制趋势图、TOP10 柱状图MySQL 适合这个项目的原因很简单评论数据是结构化较强的二维表按时间、系列做统计时GROUP BY和ORDER BY可以直接完成不需要引入太重的大数据框架。后续如果数据量增加到千万级再考虑迁移到 Spark、Hive 或数据仓库体系也不迟。现在先把业务闭环跑通比盲目上大数据组件更重要。1.3 项目整体流程整个项目从零开始建议按下面这条路径执行准备评论数据先用本地 JSON 模拟评论文本。对评论内容做清洗补充分类字段计算一个简单的情感分。在 MySQL 中创建评论表将清洗后的数据批量写入。通过 SQL 统计总评论数、平均点赞数、系列热度、每日趋势。把评论内容取出来做中文分词统计高频词。用 matplotlib 生成可视化图表输出结论。项目目录规划为popmart-analysis/ ├── config.py # 数据库配置 ├── mysql_helper.py # pymysql 操作封装 ├── create_demo_data.py # 生成模拟评论 JSON ├── preprocess.py # 数据清洗与情感打分 ├── load_to_mysql.py # 建表 写入 MySQL ├── analyze.py # SQL 聚合 中文分词统计 ├── visualize.py # 可视化图表 ├── requirements.txt # 依赖清单 ├── data/ # 存放原始数据和清洗后数据 ├── output/ # 存放图表和分析结果2. 环境准备与 MySQL 初始化2.1 建议开发环境本文的演示环境以 Python 3.10 MySQL 8.0 为例Windows、macOS、Linux 都可以运行。只要你电脑里已经装好 Python 和 MySQL版本差异不会太大。如果你是第一次配置环境建议先完成两件事Python 安装完成后在命令行执行python --version确认版本。MySQL 启动后能用mysql -u root -p成功登录。在 PyCharm 或 VSCode 里打开项目目录然后创建虚拟环境。虚拟环境的作用是把项目依赖隔离起来避免不同项目之间互相污染。2.2 创建虚拟环境并安装依赖在命令行进入项目根目录执行# Windows python -m venv venv venv\Scripts\activate # macOS / Linux python3 -m venv venv source venv/bin/activate然后创建requirements.txt文件pandas2.0.3 pymysql1.1.0 jieba0.42.1 matplotlib3.7.2 requests2.31.0执行安装pip install -r requirements.txt如果安装较慢可以临时切换为国内镜像源例如pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple不推荐把所有包都装到全局环境尤其是后面要写进简历的项目环境隔离能避免很多版本兼容问题。2.3 MySQL 初始化在 MySQL 中创建本次项目使用的数据库。登录 MySQL 后执行CREATE DATABASE IF NOT EXISTS popmart_analysis DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;使用 utf8mb4 是因为评论内容可能出现 emoji 或特殊字符utf8mb4 能完整存储。实际项目里包含中文、表情、特殊符号的文本最稳妥的字符集就是 utf8mb4。然后编写config.py把数据库连接信息集中管理# config.py DB_CONFIG { host: 127.0.0.1, port: 3306, user: root, password: 123456, database: popmart_analysis, charset: utf8mb4 }这里直接写密码只适合本地学习。真实项目中密码不要提交到 Git可以用环境变量或.env文件管理。后面章节会专门说明。3. 评论数据准备与预处理3.1 数据来源说明与合规建议写数据分析项目时很多人第一反应是“去爬虫”。这里必须先做一个边界提醒不要未经授权批量抓取社交平台用户数据更不能利用接口漏洞或绕过权限获取评论。如果项目要写进简历最好的做法是使用公开数据集、企业已授权的数据或者在自己搭建的测试环境中模拟数据。本教程为了让你能完整复现全流程先用一个本地 JSON 模拟评论数据。它和真实评论结构保持一致字段包括comment_id、content、user_name、series_name、category_name、comment_time、like_count。接入真实数据时只需要把“读取 JSON 的函数”替换成“读取合法接口或数据库的函数”后续清洗与分析代码不需要大改。3.2 生成演示用评论数据创建create_demo_data.py生成 500 条评论 JSON。这里用随机组合方式模拟不同用户的评论内容仅用于教学链路验证不代表真实用户观点。# create_demo_data.py import json import random from datetime import datetime, timedelta random.seed(42) # 演示用系列数据接入真实数据后按业务字段替换 series_list [ {series_name: MOLLY 示例系列, category_name: 盲盒}, {series_name: DIMOO 示例系列, category_name: 盲盒}, {series_name: SKULLPANDA 示例系列, category_name: 手办}, {series_name: LABUBU 示例系列, category_name: 手办} ] positive_contents [ 隐藏款真的太好看了端盒体验直接拉满, 这次设计很惊喜细节精致值得收藏, 手感很轻涂装也很干净整体超出预期, 娃友都说值我已经回购第二次了, 盲盒开箱非常快乐这款越看越喜欢 ] neutral_contents [ 物流速度还可以盒子有一个角有点压痕, 颜色比图片浅一些不过问题不大, 单买了一个还没有抽到隐藏款下次继续, 包装很严实生产日期是新的感觉还行, 整体中规中矩主要看个人喜好 ] negative_contents [ 这次有点失望涂装瑕疵比较明显, 面部眼睛附近有掉漆售后处理周期太长, 价格偏贵手感也没有想象中好, 抽到重复款了有点踩雷, 发货比预期慢很多体验一般 ] def create_demo_data(total500): rows [] start_time datetime(2025, 5, 1, 9, 0, 0) content_pool positive_contents * 6 neutral_contents * 3 negative_contents * 2 for i in range(total): series random.choice(series_list) content random.choice(content_pool) # 模拟不同用户 ID user_code random.randint(100, 999) like_count random.randint(0, 1200) comment_time start_time timedelta(minutesi * 9) rows.append({ comment_id: fDEMO{i 1:05d}, user_name: f娃友_{user_code}, content: content, series_name: series[series_name], category_name: series[category_name], comment_time: comment_time.strftime(%Y-%m-%d %H:%M:%S), like_count: like_count }) return rows if __name__ __main__: rows create_demo_data() with open(data/comments.json, w, encodingutf-8) as f: json.dump(rows, f, ensure_asciiFalse, indent2) print(f生成评论数据: {len(rows)} 条)运行前先创建data目录然后执行mkdir data python create_demo_data.py执行后data/comments.json中会出现 500 条带comment_id的数据。随机种子设置了seed(42)目的是让结果可复现方便后续排查问题。3.3 使用 pandas 清洗评论数据模拟数据也存在很多现实场景中的脏数据问题例如空内容、内容只有空格、时间格式不对、同一评论重复出现等。清洗规则如下去掉comment_id和comment_time为空的行。对content去掉首尾空格把换行符替换为空格。对评论按comment_id去重。如果同一comment_id没有则按content comment_time生成去重键。将字符串时间转成真正的datetime类型方便后续按天统计。代码如下# preprocess.py import json import pandas as pd def read_json_to_df(file_path: str data/comments.json) - pd.DataFrame: with open(file_path, r, encodingutf-8) as f: rows json.load(f) df pd.DataFrame(rows) print(f原始数据量: {len(df)}) # 清洗文本 df[content] df[content].astype(str).str.replace(\n, ).str.strip() # 去关键字段为空的行 df df.dropna(subset[comment_id, comment_time]) print(f删除空字段后数据量: {len(df)}) # 评论ID去重 df df.drop_duplicates(subset[comment_id], keeplast) print(f按 comment_id 去重后数据量: {len(df)}) # 内容时间去重避免同一内容重复写入 df[content_time_key] df[content] _ df[comment_time].astype(str) df df.drop_duplicates(subset[content_time_key], keeplast) # 时间标准化 df[comment_time] pd.to_datetime(df[comment_time], errorscoerce) df df.dropna(subset[comment_time]) df[comment_time_str] df[comment_time].dt.strftime(%Y-%m-%d %H:%M:%S) df[comment_date] df[comment_time].dt.strftime(%Y-%m-%d) df df.drop(columns[content_time_key]) print(f清洗后数据量: {len(df)}) return df def main(): df read_json_to_df() df.to_csv(data/comments_clean.csv, indexFalse, encodingutf-8-sig) print(清洗完成已保存 comments_clean.csv) if __name__ __main__: main()to_csv时使用encodingutf-8-sig方便后续用 Excel 打开 CSV 时中文不乱码。输出到 MySQL 时不需要关心这个编码因为 MySQL 端已经使用了 utf8mb4。3.4 增加规则情感分评论分析不能只统计数量还要判断用户情绪。常见做法有训练模型、调用云服务、基于词典规则。对于学习项目基于词典的规则打分最简单也能看到足够多的可解释性。情感分定义如下积极评论命中积极词score 1消极评论命中消极词score -1中性评论没有明显倾向score 0在preprocess.py中追加代码如下POSITIVE_WORDS [ 好看, 惊喜, 满意, 精致, 喜欢, 值得, 开心, 手感好, 收藏, 回购, 超出预期 ] NEGATIVE_WORDS [ 失望, 瑕疵, 色差, 掉漆, 发货慢, 售后差, 不值, 踩雷, 压痕, 偏贵, 体验一般 ] def add_score(df: pd.DataFrame) - pd.DataFrame: def judge(content: str) - int: score 0 for word in POSITIVE_WORDS: if word in content: score 1 for word in NEGATIVE_WORDS: if word in content: score - 1 if score 0: return 1 if score 0: return -1 return 0 df[score] df[content].map(judge) return df然后修改maindef main(): df read_json_to_df() df add_score(df) df.to_csv(data/comments_clean.csv, indexFalse, encodingutf-8-sig) print(df[score].value_counts().to_dict()) print(清洗完成已保存 comments_clean.csv)执行python preprocess.py如果生成逻辑正常控制台可能输出类似{0: 100, 1: 210, -1: 190}由于正负词表比较小这个分数只能判断“有没有明显情绪词”不能做到细粒度的情感程度。面试时如果被问到可以如实说明当前是规则方案后续可以换成 BERT 之类的模型来做更好。4. 设计 MySQL 表并完成批量入库4.1 评论表结构设计在设计评论表时需要先想想后续会怎么查询按评论时间统计每天的评论量。按系列统计讨论热度。按情感分看正负面评论占比。按点赞数找热门评论。评论内容需要支持文本挖掘。因此创建一张comment_info表字段设计如下CREATE TABLE IF NOT EXISTS comment_info ( id INT NOT NULL AUTO_INCREMENT COMMENT 主键, comment_id VARCHAR(64) NOT NULL COMMENT 评论唯一ID业务侧提供, content TEXT NOT NULL COMMENT 评论内容, user_name VARCHAR(100) DEFAULT 匿名 COMMENT 用户名统一脱敏处理, series_name VARCHAR(200) DEFAULT COMMENT 所属系列, category_name VARCHAR(100) DEFAULT COMMENT 所属品类, comment_time DATETIME NOT NULL COMMENT 评论发生时间, like_count INT DEFAULT 0 COMMENT 点赞数, score TINYINT DEFAULT 0 COMMENT 情感分-1消极0中性1积极, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 记录入库时间, PRIMARY KEY (id), UNIQUE KEY uk_comment_id (comment_id), KEY idx_comment_time (comment_time), KEY idx_series_name (series_name), KEY idx_score (score) ) ENGINEInnoDB DEFAULT CHARSETutf8mb4 COLLATEutf8mb4_unicode_ci COMMENT泡泡玛特评论信息表;表设计有三个关键点comment_id是业务去重键建立唯一索引防止重复评论反复写入。content使用TEXT避免直接指定过小的VARCHAR导致长文本入库失败。score使用TINYINT比VARCHAR更适合做统计和索引。like_count使用INT点赞数比评论数增长更快时也不易溢出。4.2 封装 MySQLHelper保持代码可复用的关键是把数据库连接、增删改查封装成一个独立的类。创建mysql_helper.py文件# mysql_helper.py import pymysql class MySQLHelper: def __init__(self, config):
返回列表