SQL项目实战:银行客户分析

news2024/11/17 20:22:56

大家好,本文将与大家分享一个SQL项目,即根据从数据集收集到的信息分析银行客户流失的可能性。这些洞察来自个人信息,如年龄、性别、收入和人口统计信息、银行卡类型、产品、客户信用评分以及客户在银行的服务时间长短等。对于银行而言,了解如何留住客户比寻找其他客户更有利。

客户流失是指客户或顾客的流失。公司通常将其作为关键业务指标之一,因为恢复的长期客户对公司的价值远远高于新招募的客户。客户流失有两种类型:自愿流失和非自愿流失。自愿流失是由于客户决定转向其他公司或服务提供商,而非自愿流失则是由于客户搬迁到长期护理机构、死亡或搬迁到较远的地方等情况造成的。

本文将集中讨论自愿流失,因为它可能是由于公司与客户关系中公司可以控制的因素造成的,例如如何处理账单互动或如何提供售后帮助。

数据集

本文使用的是customer_churn_records表,该表包含多列,customerid是表的主键。

  1. RowNumber:对应记录(行)编号

  2. CustomerId:客户的ID编号

  3. Surname:客户的姓氏

  4. CreditScore:客户信用行为预测值

  5. Geography:客户所在地

  6. Gender:客户的性别信息

  7. Age:客户的年龄信息

  8. Tenure:客户在银行的使用年限

  9. Balance:客户账户中的余额信息

  10. NumOfProducts:客户购买的产品数量

  11. HasCrCard:客户是否拥有信用卡

  12. IsActiveMember:客户是否处于活跃状态

  13. EstimatedSalary(估计工资):客户的估计工资金额

  14. Exited:客户是否离开银行

  15. Complain:客户是否有投诉

  16. Satisfaction Score:客户对银行的满意度评分

  17. Card Type:客户持有的银行卡类型

  18. Points Earned:客户使用信用卡获得的积分

# 显示表中的列 = customer_churn_records

q='''
  
  SELECT * FROM customer_churn_records

'''

df = pd.read_sql(q,engine_postgresql)
df.head()

 查询客户流失率

导入软件包:

import psycopg2 # PostgreSQL数据库适配器
import pandas as pd # 用于分析数据
from sqlalchemy import create_engine # 促进Python程序与数据库之间的通信

首先,本文根据已退出的列计算有多少客户流失。

# 统计是否流失/退出的客户总数

q='''
  
  WITH temp_churn AS(
    SELECT exited,
    CASE 
       WHEN exited = 1 THEN 'Churn'
       ELSE 'Not Churn'
    END AS STATUS
    from customer_churn_records
    )
  
  SELECT STATUS,
  COUNT(exited) as Total
  FROM temp_churn
  GROUP BY 1

'''

df = pd.read_sql(q,engine_postgresql)
df.head()

可以发现在10000名客户中,有近20%从银行退出或流失。尽管这个数字并不算很大,但如果现在还不能解决这个问题,它可能会增长得更多。

现在,本文将从活跃客户、性别、人口统计、年龄、临时工龄、信用分数、产品数量、满意度分数、投诉、是否有信用卡、卡类型、已获积分、预估薪资和余额等多个方面来检查客户流失状况的类型。

# 统计有多少活跃客户流失

q=''' 

  WITH temp_isactivemember AS(
    SELECT exited,
    CASE 
       WHEN isactivemember = 1 THEN 'Active'
       ELSE 'Not Active'
    END AS isactivemember
    from customer_churn_records
    )
  
  SELECT isactivemember,
  COUNT (CASE WHEN exited = 1 THEN 1 END) AS Churn,
  COUNT (CASE WHEN exited = 0 THEN 1 END) AS Not_Churn
  FROM temp_isactivemember
  GROUP BY 1

'''

df = pd.read_sql(q,engine_postgresql)
df

# 根据性别计算是否流失/退出的客户总数

q='''
  
  SELECT gender,
  COUNT(gender) as Total,
  COUNT(case when exited = 1 then 1 end) as Churn,
  COUNT(case when exited = 0 then 1 end) as Not_churn
  FROM customer_churn_records
  GROUP BY 1

'''

df = pd.read_sql(q,engine_postgresql)
df.head()

# 根据人口统计数据计算流失客户的数量

q=''' 

  SELECT geography,
  COUNT (CASE WHEN exited = 1 THEN 1 END) AS Churn,
  COUNT (CASE WHEN exited = 0 THEN 1 END) AS Not_Churn
  FROM customer_churn_records
  GROUP BY 1

'''

df = pd.read_sql(q,engine_postgresql)
df

 

#根据年龄组计算流失客户的数量

q=''' 

    SELECT 
    CASE 
        WHEN age <= 20 THEN 'Group <= 20'
        WHEN age >= 21 AND age <= 40 THEN 'Group 21-40'
        WHEN age >= 41 AND age <= 60 THEN 'Group 41-60'
        ELSE 'Group > 60'
    END AS age_category,
    COUNT(CASE WHEN exited = 1 then 1 end) as Churn,
    COUNT(CASE WHEN exited = 0 then 1 end) as Not_Churn
    FROM customer_churn_records
    GROUP BY 1
    ORDER BY 1

'''

df = pd.read_sql(q,engine_postgresql)
df

 

# 根据他们成为客户的时间计算是否流失/退出的客户总数

q='''
  
  WITH temp_tenure AS(
    SELECT tenure,
    CASE 
       WHEN exited = 1 THEN 'Churn'
       ELSE 'Not Churn'
    END AS STATUS
    from customer_churn_records
    )
  
  SELECT STATUS,
  AVG(tenure) as Average_tenure
  FROM temp_tenure
  GROUP BY 1
  
'''

df = pd.read_sql(q,engine_postgresql)
df.head()

 

# 根据客户使用银行产品的数量,计算有多少客户流失

q='''

   WITH temp_bankprod AS(
    SELECT numofproducts,
    CASE 
       WHEN exited = 1 THEN 'Churn'
       ELSE 'Not Churn'
    END AS STATUS
    from customer_churn_records
    )
  
  SELECT STATUS,
  AVG(numofproducts) as avg_numofproducts
  FROM temp_bankprod
  GROUP BY 1
  
'''

df = pd.read_sql(q,engine_postgresql)
df.head()

 

# 根据客户 对银行的满意度得分的平均得分,计算有多少客户流失

q='''

   WITH temp_satisfaction AS(
    SELECT satisfaction_score,
    CASE 
       WHEN exited = 1 THEN 'Churn'
       ELSE 'Not Churn'
    END AS STATUS
    from customer_churn_records
    )
  
  SELECT STATUS,
  AVG(satisfaction_score) as satisfaction_level
  FROM temp_satisfaction
  GROUP BY 1
  
'''

df = pd.read_sql(q,engine_postgresql)
df.head()

 

# 根据客户的投诉量,统计有多少客户流失

q='''

   WITH temp_complain AS(
    SELECT complain,
    CASE 
       WHEN exited = 1 THEN 'Churn'
       ELSE 'Not Churn'
    END AS STATUS
    from customer_churn_records
    )
  
  SELECT STATUS,
  COUNT(complain) as complain
  FROM temp_complain
  GROUP BY 1
  
'''

df = pd.read_sql(q,engine_postgresql)
df.head()

 

# 根据客户是否拥有信用卡计算有多少客户流失

q=''' 

    WITH temp_hascrcard AS(
    SELECT hascrcard,
    CASE 
       WHEN exited = 1 THEN 'Churn'
       ELSE 'Not Churn'
    END AS STATUS
    from customer_churn_records
    )
  
  SELECT STATUS,
  COUNT (CASE WHEN hascrcard = 1 THEN 1 END) AS has_creditcard,
  COUNT (CASE WHEN hascrcard = 0 THEN 1 END) AS no_creditcard
  FROM temp_hascrcard
  GROUP BY 1

'''

df = pd.read_sql(q,engine_postgresql)
df

 

# 根据客户的预估工资计算有多少客户流失

q='''

   WITH temp_salary AS(
    SELECT estimatedsalary,
    CASE 
       WHEN exited = 1 THEN 'Churn'
       ELSE 'Not Churn'
    END AS STATUS
    from customer_churn_records
    )
  
  SELECT STATUS,
  AVG(estimatedsalary) as avg_salary,
  MAX(estimatedsalary) as max_salary,
  MIN(estimatedsalary) as min_salary
  FROM temp_salary
  GROUP BY 1
  
'''

df = pd.read_sql(q,engine_postgresql)
df.head()

 

# 根据客户的银行存款余额计算有多少客户流失
#(平均、最高、最低)

q='''

   WITH temp_balance AS(
    SELECT balance,
    CASE 
       WHEN exited = 1 THEN 'Churn'
       ELSE 'Not Churn'
    END AS STATUS
    from customer_churn_records
    )
  
  SELECT STATUS,
  AVG(balance) as avg_balance,
  MAX(balance) as max_balance,
  MIN(balance) as min_balance
  FROM temp_balance
  GROUP BY 1
  
'''

df = pd.read_sql(q,engine_postgresql)
df.head()

 结论

根据上述问题,有一些类别可以帮助确定哪些方面会真正影响客户流失。不管客户在银行停留了多长时间,他们仍然有可能流失,或者说,客户的银行账户上有相当数量的存款,他们仍然有可能流失。

通过分析发现,41至60岁年龄段的客户比其他年龄段的客户更容易流失。为了解决这个问题,银行可以集中精力创造或提升产品和服务,以帮助吸引和维护特定年龄段的客户,比如为年龄较大的客户提供更流畅的服务和最短的排队时间。

持有信用卡的客户往往不会流失,而是会继续留在银行。银行最好通过各种促销活动说服更多的客户申请信用卡,这取决于客户细分,可根据客户的卡种(钻石卡、白金卡、金卡、银卡)、性别、年龄、支出和人口分布进行细分。

留存客户和流失客户的满意度得分有点令人担忧 [ 3.017960 / 2.997547 ],银行需要进行评估,以保持流失客户和留存客户之间的满意度得分差距,并保持活跃客户,因为活跃客户流失的可能性较低。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/816651.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

zookeeper学习(三)基础数据结构

数据模型 在 zookeeper 中&#xff0c;可以说 zookeeper 中的所有存储的数据是由 znode 组成的&#xff0c;节点也称为 znode&#xff0c;并以 key/value 形式存储数据。 整体结构类似于 linux 文件系统的模式以树形结构存储。其中根路径以 / 开头。 进入 zookeeper 安装的 …

如何对反编译的安卓应用进行调试并修改

安卓修改大师可以在没有源代码的情况下&#xff0c;直接反编译已经打包的APK安装包&#xff0c;通过修改SMALI代码实现添加和去除部分功能&#xff0c;并在应用的任何地方添加任意代码&#xff0c;增加任意任何您想实现的功能。通过这种方式&#xff0c;把该应用变为您自己的应…

C++STL库中stack

文章目录 stack的介绍 stack的常用接口 stack的模拟实现 关于栈的相关OJ题 一、stack的介绍 1. stack是一种容器适配器&#xff0c;专门用在具有后进先出操作的上下文环境中&#xff0c;其删除只能从容器的一端进行元素的插入与提取操作。 2. stack是作为容器适配器被实现的&a…

英文论文(sci)解读复现:基于YOLOv5的自然场景下苹果叶片病害实时检测

对于目标检测算法改进&#xff0c;但是应用于什么场景&#xff0c;需要什么改进方法对应与自己的应用场景有效果&#xff0c;并且多少改进点能发什么水平的文章&#xff0c;为解决大家的困惑&#xff0c;此系列文章旨在给大家解读发表高水平学术期刊中的SCI论文&#xff0c;并对…

FitBot-一款先进的以健康为中心的聊天机器人

在健康意识高涨&#xff0c;追求均衡生活方式成为普遍追求的时代&#xff0c;营养问题无疑是核心支柱。然而&#xff0c;饮食计划的复杂性和大量的营养数据往往成为我们实现这种平衡的障碍。例如糖尿病患者&#xff0c;他们需要持续和准确的营养指导来有效管理血糖水平。如果能…

Mendix是如何支持多语言的?

前言 国际化的支持能力&#xff0c;至关重要。这类功能的缺失&#xff0c;将会在市场竞争、用户体验、合作关系以法律法规方面遇到重大挑战&#xff0c;这些都是可能对其成功产生致命影响的问题。 比如在某些国家和地区&#xff0c;政府可能会对不支持本地语言和货币的软件系…

深度学习,神经网络介绍

目录 1.神经网络的整体构架 2.神经网络架构细节 3.正则化与激活函数 4.神经网络过拟合解决方法 1.神经网络的整体构架 ConvNetJS demo: Classify toy 2D data 我们可以看看这个神经网络的网站&#xff0c;可以用来学习。 神经网络的整体构架如下1&#xff1a; 感知器&…

el-table使用xlsx实现导入文件编辑功能

需求&#xff1a;列表根据xlsx文件导入后&#xff0c;和列表进行对比&#xff0c;之后实现编辑功能 1.下载xlsx 我下的是之前的版本&#xff0c;新版不知道兼不兼容&#xff0c;这个包900多k npm install xlsx0.14.5 2.在需要使用表格导入的页面引入 import XLSX from &quo…

从0到1开发go-tcp框架【2-实现Message模块、解决TCP粘包问题、实现多路由机制】

从0到1开发go-tcp框架【2-实现Message模块、解决TCP粘包问题、实现多路由机制】 1 实现\封装Message模块 zinx/ziface/imessage.go package zifacetype IMessage interface {GetMsdId() uint32GetMsgLen() uint32GetMsgData() []byteSetMsgId(uint32)SetData([]byte)SetData…

MySQL数据库 【索引事务】

目录 一、概念 二、索引的优缺点 1、索引的优点 2、索引的缺陷 三、索引的使用 1、查看索引 2、创建索引 3、删除索引 四、索引底层的数据结构 1、B树 2、B树 五、索引事务 1、概念和回滚 2、事务的使用 3、事务的基本特性 4、并发会遇到的问题 &#xff08…

Python程序设计基础:字典与集合(二)

文章目录 一、字典的整体操作1、字典的遍历2、字典的排序3、字典的合并 二、创建与访问集合1、集合的创建2、集合的访问 三、集合的基本操作1、集合的增、删、查2、集合的数学运算 一、字典的整体操作 字典的整体操作是指以字典为操作对象&#xff0c;对字典进行遍历、排序以及…

hdu foreverlasting and fried-chicken

题意&#xff1a; 在一个有n个点和m条边的图中找到形状是上图的子图&#xff0c;输出个数 思路&#xff1a; 仔细观察上图&#xff0c;设第二行的那个点为x&#xff0c;最后一行的点为y&#xff0c;那么可以知道&#xff0c;如果x和y都和相同的所有点中取四个点分别和xy相连…

DUBBO服务多网卡,服务调用失败

如果服务器是多网卡的&#xff0c;比如安装了docker&#xff0c;有一个docker虚拟网卡&#xff0c;一个实体网卡eth0&#xff0c;当我们运行springboot应用后&#xff0c;dubbo注入到zk的地址是 docker虚拟网卡的地址172网段&#xff0c;而不是实际内网地址192网段&#xff0c;…

OpenLayers实战,OpenLayers使用wind-layer插件实现风场动态效果

专栏目录: OpenLayers入门教程汇总目录 前言 本章讲解如何使用OpenLayers的气象风场插件wind-layer实现气象风场动态效果,该插件除了可用于OpenLayers之外,还可用于mapgl、leaflet和cesuim等二维/三维地图引擎,还是很强大的,废话少谈,让我们立刻开始实现吧。 二、依赖和…

如何将论文中的字快速复制出来?图片如何提取文字?

在日常的办公中&#xff0c;我们经常会遇到需要将纸质文件里的文字提取出来&#xff0c;再转换为电子档的情况&#xff0c;如果我们采用手动输入的话&#xff0c;不仅速度太慢&#xff0c;而且还可能因此耽误到后边的工作&#xff0c;是不是已经有小伙伴遇到这种现象&#xff0…

element中tabs组件,click事件点击拿到当前item的所有数据

话不多说&#xff0c;直接上代码&#xff1a; 添加一个:value&#xff0c;然后在用JSON.stringify(item)转一下就可以了&#xff0c;这样就会存在$attrs.value这个里面了。 接着在点击事件里面获取使用el.$attrs.value&#xff0c;注意这里在拿到这个值时&#xff0c;再用JSON…

锌离子荧光探针TSQ,109628-27-5,具有很好的选择性荧光探针

资料编辑|陕西新研博美生物科技有限公司小编MISSwu​ PART1----外观以及性质&#xff1a; 锌离子荧光探针TSQ&#xff08;CAS号&#xff1a;109628-27-5&#xff09;&#xff0c;锌离子荧光探针TSQ是用于检测锌离子的荧光探针。 TSQ与Zn离子结合后&#xff0c;吸收波长和发射波…

如何创建一个SpringBoot项目

欢迎来到南方有乔木的博客&#xff01;&#xff01;&#xff01; 博主主页&#xff1a;点击点击&#xff01;戳一戳&#xff01;&#xff01; 博主名:南方有乔木 博主简介&#xff1a; 一名在校大学生&#xff0c;正在努力学习Java语言编程。穷且意坚&#xff0c;不坠青云之…

sort排序报错:java.lang.UnsupportedOperationException: null

文章目录 问题原因解决方式 问题 Groovy 调用 .sort{} 排序报错:java.lang.UnsupportedOperationException: null solutionScenario2SolutionProcessList.sort { it.idx } 原因 调用的sort的对象是Collections的内部类对象UnmodifiableRandomAcessList 解决方式 调用 coll…

数据结构:单链表的实现(C语言)

个人主页 &#xff1a; 水月梦镜花 个人专栏 &#xff1a; 《C语言》 《数据结构》 文章目录 前言一、单链表实现思路和图解1.节点的定义(SListNode)2.申请一个节点(BuySListNode)3.单链表打印(SListPrint)4.单链表尾插(SListPushBack)5.单链表的头插(SListPushFront)6.单链表的…