基于大数据的电信客户流失数据分析系统(Spark+Spring+Vue+Echarts)

45 阅读8分钟

💖💖作者:计算机编程小央姐 💙💙个人简介:曾长期从事计算机专业培训教学,本人也热爱上课教学,语言擅长Java、微信小程序、Python、Golang、安卓Android等,开发项目包括大数据、深度学习、网站、小程序、安卓、算法。平常会做一些项目定制化开发、代码讲解、答辩教学、文档编写、也懂一些降重方面的技巧。平常喜欢分享一些自己开发中遇到的问题的解决办法,也喜欢交流技术,大家有技术代码这一块的问题可以问我! 💛💛想说的话:感谢大家的关注与支持! 💜💜

💕💕文末获取源码

@TOC

基于大数据的电信客户流失数据分析系统(Spark+Spring+Vue+Echarts)-系统功能介绍

基于大数据的电信客户流失数据分析系统以 Spark 为核心大数据处理框架,结合 Spring 后端技术、Vue+ElementUI 前端框架及 Echarts 可视化工具,聚焦电信行业客户流失问题搭建一站式分析平台。系统支持从客户总体流失概览、人口属性、账户合约、业务办理及客户分群价值五大维度展开深度分析,通过 Spark SQL 实现海量客户数据的高效查询与计算,借助 Pandas、NumPy 完成数据清洗与特征处理,最终以 Echarts 生成直观的可视化图表呈现分析结果。平台能够精准识别不同在网时长、消费层级、合约类型客户的流失规律,挖掘客户流失的核心影响因素,为电信企业制定留存策略提供数据支撑,同时兼顾技术实现的可行性与业务逻辑的完整性,适合作为计算机专业大数据方向的毕业设计项目。

基于大数据的电信客户流失数据分析系统(Spark+Spring+Vue+Echarts)-系统技术介绍

大数据框架:Hadoop+Spark(本次没用Hive,支持定制) 开发语言:Python+Java(两个版本都支持) 后端框架:Django+Spring Boot(Spring+SpringMVC+Mybatis)(两个版本都支持) 前端:Vue+ElementUI+Echarts+HTML+CSS+JavaScript+jQuery 详细技术点:Hadoop、HDFS、Spark、Spark SQL、Pandas、NumPy 数据库:MySQL

基于大数据的电信客户流失数据分析系统(Spark+Spring+Vue+Echarts)-系统背景意义

在数字化转型加速的当下,电信行业竞争日趋激烈,客户作为企业核心资产,其流失问题直接影响企业的稳定发展与市场竞争力。随着电信业务的多元化拓展,客户可选择的服务方案愈发丰富,转网成本逐渐降低,导致客户流失现象愈发普遍。传统的客户管理方式多依赖人工统计与经验判断,难以应对海量客户数据带来的分析压力,无法精准捕捉客户流失的潜在信号与关键诱因。而大数据技术的成熟为解决这一问题提供了有效途径,能够实现对客户行为数据、消费数据、合约数据等多维度信息的深度挖掘。在此背景下,搭建一套基于大数据技术的电信客户流失数据分析系统,通过系统化的分析方法挖掘客户流失规律,成为解决电信企业客户管理痛点的务实选择,也符合计算机专业大数据方向毕业设计的实践需求。 本选题的意义主要体现在实践应用与学习提升两个层面,且均以务实、可行的目标为导向。从实践角度来看,系统能够帮助电信企业快速掌握客户流失的整体态势,精准定位高流失风险客户群体及核心影响因素,为制定差异化的客户留存策略提供数据参考,虽无法直接产生巨大的商业价值,但能为企业客户管理工作提供轻量化的分析工具。从技术实践角度,选题整合了 Spark、Spring、Vue 等主流技术,涵盖大数据处理、后端开发、前端可视化等多个技术模块,能够将课堂所学的理论知识转化为实际的系统开发能力,提升数据处理、逻辑建模与项目实战的综合素养。此外,系统所涉及的客户分群、多维度数据分析等思路,也可为同类行业数据分析项目提供简单的参考,其技术方案与实现逻辑符合本科毕业设计的难度要求,兼具实用性与学习价值。

基于大数据的电信客户流失数据分析系统(Spark+Spring+Vue+Echarts)-系统演示视频

演示视频

基于大数据的电信客户流失数据分析系统(Spark+Spring+Vue+Echarts)-系统演示图片

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

基于大数据的电信客户流失数据分析系统(Spark+Spring+Vue+Echarts)-系统部分代码

from pyspark.sql import SparkSession from pyspark.sql.functions import col, count, avg, when, sum, round, concat_ws, regexp_replace from pyspark.sql.types import DoubleType import pandas as pd import numpy as np # 初始化SparkSession spark = SparkSession.builder.appName("TelecomCustomerChurnAnalysis").master("local[*]").getOrCreate() # 核心功能1:客户流失总体概览分析(含流失率、不同在网时长流失趋势) def analyze_overall_churn(customer_df):     # 数据清洗:处理TotalCharges字段的非数值型数据     cleaned_df = customer_df.withColumn("TotalCharges", regexp_replace(col("TotalCharges"), "^\\s*$", "0.0"))     cleaned_df = cleaned_df.withColumn("TotalCharges", col("TotalCharges").cast(DoubleType()))     # 计算总体流失率     churn_overall = cleaned_df.groupBy("Churn").agg(count("customerID").alias("customer_count"))     total_customers = churn_overall.agg(sum("customer_count").alias("total")).collect()[0]["total"]     churn_rate = churn_overall.filter(col("Churn") == "Yes").agg(         round((count("customerID") / total_customers) * 100, 2).alias("churn_rate")     ).collect()[0]["churn_rate"]     retention_rate = 100.0 - churn_rate     # 不同在网时长流失趋势分析:将在网时长分段     tenure_churn = cleaned_df.withColumn(         "tenure_segment",         when(col("tenure") <= 12, "0-12月").when(col("tenure") <= 24, "13-24月").when(col("tenure") <= 36, "25-36月")         .when(col("tenure") <= 48, "37-48月").otherwise("49月以上")     ).groupBy("tenure_segment", "Churn").agg(count("customerID").alias("count"))     # 计算各分段流失率     tenure_total = tenure_churn.groupBy("tenure_segment").agg(sum("count").alias("total")).withColumnRenamed("tenure_segment", "ts")     tenure_churn_rate = tenure_churn.filter(col("Churn") == "Yes").join(         tenure_total, col("tenure_segment") == col("ts"), "left"     ).withColumn("churn_rate", round((col("count") / col("total")) * 100, 2))     tenure_churn_result = tenure_churn_rate.select("tenure_segment", "churn_rate").orderBy("tenure_segment")     # 不同月度消费金额流失分布     monthly_charges_churn = cleaned_df.withColumn(         "monthly_segment",         when(col("MonthlyCharges") <= 30, "低消费(≤30元)").when(col("MonthlyCharges") <= 60, "中消费(31-60元)").otherwise("高消费(>60元)")     ).groupBy("monthly_segment", "Churn").agg(count("customerID").alias("count"))     monthly_total = monthly_charges_churn.groupBy("monthly_segment").agg(sum("count").alias("total")).withColumnRenamed("monthly_segment", "ms")     monthly_churn_rate = monthly_charges_churn.filter(col("Churn") == "Yes").join(         monthly_total, col("monthly_segment") == col("ms"), "left"     ).withColumn("churn_rate", round((col("count") / col("total")) * 100, 2))     monthly_churn_result = monthly_churn_rate.select("monthly_segment", "churn_rate").orderBy("monthly_segment")     # 汇总结果     overall_result = spark.createDataFrame([(churn_rate, retention_rate)], ["churn_rate", "retention_rate"])     return overall_result, tenure_churn_result, monthly_churn_result # 核心功能2:客户分群与流失率分析(LTM模型) def analyze_customer_segmentation(customer_df):     # 数据预处理:处理缺失值和类型转换     processed_df = customer_df.withColumn("TotalCharges", regexp_replace(col("TotalCharges"), "^\\s*$", "0.0"))     processed_df = processed_df.withColumn("TotalCharges", col("TotalCharges").cast(DoubleType()))     # 合同类型数值化:按月=1,一年=2,两年=3     processed_df = processed_df.withColumn(         "contract_score",         when(col("Contract") == "Month-to-month", 1).when(col("Contract") == "One year", 2).when(col("Contract") == "Two year", 3).otherwise(0)     )     # 标准化在网时长、月度消费、合同得分(简化版标准化,避免复杂依赖)     tenure_stats = processed_df.agg(avg("tenure").alias("avg_tenure"), (max("tenure") - min("tenure")).alias("tenure_range")).collect()[0]     monthly_stats = processed_df.agg(avg("MonthlyCharges").alias("avg_monthly"), (max("MonthlyCharges") - min("MonthlyCharges")).alias("monthly_range")).collect()[0]     contract_stats = processed_df.agg(avg("contract_score").alias("avg_contract"), (max("contract_score") - min("contract_score")).alias("contract_range")).collect()[0]     # 计算标准化值(避免除以零)     processed_df = processed_df.withColumn(         "norm_tenure",         when(tenure_stats["tenure_range"] != 0, (col("tenure") - tenure_stats["avg_tenure"]) / tenure_stats["tenure_range"]).otherwise(0)     ).withColumn(         "norm_monthly",         when(monthly_stats["monthly_range"] != 0, (col("MonthlyCharges") - monthly_stats["avg_monthly"]) / monthly_stats["monthly_range"]).otherwise(0)     ).withColumn(         "norm_contract",         when(contract_stats["contract_range"] != 0, (col("contract_score") - contract_stats["avg_contract"]) / contract_stats["contract_score"]).otherwise(0)     )     # 转换为Pandas DataFrame进行K-Means聚类(简化实现,适合毕设场景)     pandas_df = processed_df.select("customerID", "norm_tenure", "norm_monthly", "norm_contract").toPandas()     features = pandas_df[["norm_tenure", "norm_monthly", "norm_contract"]].values     # 简单K-Means聚类(k=4,分四类客户)     from sklearn.cluster import KMeans     kmeans = KMeans(n_clusters=4, random_state=42, n_init=10)     pandas_df["cluster"] = kmeans.fit_predict(features)     # 定义客户分群标签     def get_cluster_label(cluster):         if cluster == 0:             return "高价值忠诚客户"         elif cluster == 1:             return "高消费潜力新客"         elif cluster == 2:             return "低价值风险客户"         else:             return "稳定中等价值客户"     pandas_df["cluster_label"] = pandas_df["cluster"].apply(get_cluster_label)     # 转换回Spark DataFrame并关联流失状态     cluster_df = spark.createDataFrame(pandas_df[["customerID", "cluster_label"]])     cluster_churn_df = cluster_df.join(customer_df.select("customerID", "Churn"), on="customerID", how="inner")     # 计算各分群流失率     cluster_total = cluster_churn_df.groupBy("cluster_label").agg(count("customerID").alias("total"))     cluster_churn = cluster_churn_df.filter(col("Churn") == "Yes").groupBy("cluster_label").agg(count("customerID").alias("churn_count"))     cluster_churn_rate = cluster_total.join(cluster_churn, on="cluster_label", how="left").fillna(0)     cluster_churn_rate = cluster_churn_rate.withColumn("churn_rate", round((col("churn_count") / col("total")) * 100, 2))     # 各分群业务偏好分析(以互联网服务为例)     cluster_service = cluster_df.join(         customer_df.select("customerID", "InternetService", "OnlineSecurity", "TechSupport"),         on="customerID", how="inner"     ).groupBy("cluster_label", "InternetService").agg(count("customerID").alias("service_count"))     # 汇总分群结果     cluster_summary = cluster_churn_rate.select("cluster_label", "total", "churn_count", "churn_rate")     return cluster_summary, cluster_service # 核心功能3:合同与业务办理维度流失分析 def analyze_contract_service_churn(customer_df):     # 合同类型流失率分析     contract_churn = customer_df.groupBy("Contract", "Churn").agg(count("customerID").alias("count"))     contract_total = contract_churn.groupBy("Contract").agg(sum("count").alias("total")).withColumnRenamed("Contract", "c")     contract_churn_rate = contract_churn.filter(col("Churn") == "Yes").join(         contract_total, col("Contract") == col("c"), "left"     ).withColumn("churn_rate", round((col("count") / col("total")) * 100, 2))     contract_result = contract_churn_rate.select("Contract", "churn_rate").orderBy("churn_rate", ascending=False)     # 支付方式流失分析     payment_churn = customer_df.groupBy("PaymentMethod", "Churn").agg(count("customerID").alias("count"))     payment_total = payment_churn.groupBy("PaymentMethod").agg(sum("count").alias("total")).withColumnRenamed("PaymentMethod", "p")     payment_churn_rate = payment_churn.filter(col("Churn") == "Yes").join(         payment_total, col("PaymentMethod") == col("p"), "left"     ).withColumn("churn_rate", round((col("count") / col("total")) * 100, 2))     payment_result = payment_churn_rate.select("PaymentMethod", "churn_rate").orderBy("churn_rate", ascending=False)     # 捆绑业务数量与流失关系分析     # 计算每个客户开通的增值服务数量     service_churn_df = customer_df.withColumn(         "service_count",         when(col("OnlineSecurity") == "Yes", 1).otherwise(0) +         when(col("OnlineBackup") == "Yes", 1).otherwise(0) +         when(col("DeviceProtection") == "Yes", 1).otherwise(0) +         when(col("TechSupport") == "Yes", 1).otherwise(0) +         when(col("StreamingTV") == "Yes", 1).otherwise(0) +         when(col("StreamingMovies") == "Yes", 1).otherwise(0)     )     # 服务数量分段     service_churn_df = service_churn_df.withColumn(         "service_segment",         when(col("service_count") == 0, "0项服务").when(col("service_count") <= 2, "1-2项服务").when(col("service_count") <= 4, "3-4项服务").otherwise("5-6项服务")     )     # 计算各分段流失率     service_churn = service_churn_df.groupBy("service_segment", "Churn").agg(count("customerID").alias("count"))     service_total = service_churn.groupBy("service_segment").agg(sum("count").alias("total")).withColumnRenamed("service_segment", "s")     service_churn_rate = service_churn.filter(col("Churn") == "Yes").join(         service_total, col("service_segment") == col("s"), "left"     ).withColumn("churn_rate", round((col("count") / col("total")) * 100, 2))     service_result = service_churn_rate.select("service_segment", "churn_rate").orderBy("service_segment")     # 技术支持服务流失分析     tech_churn = customer_df.groupBy("TechSupport", "Churn").agg(count("customerID").alias("count"))     tech_total = tech_churn.groupBy("TechSupport").agg(sum("count").alias("total")).withColumnRenamed("TechSupport", "t")     tech_churn_rate = tech_churn.filter(col("Churn") == "Yes").join(         tech_total, col("TechSupport") == col("t"), "left"     ).withColumn("churn_rate", round((col("count") / col("total")) * 100, 2))     tech_result = tech_churn_rate.select("TechSupport", "churn_rate").orderBy("TechSupport")     return contract_result, payment_result, service_result, tech_result

基于大数据的电信客户流失数据分析系统(Spark+Spring+Vue+Echarts)-结语

💟💟如果大家有任何疑虑,欢迎在下方位置详细交流。