day 6 数据可视化

一、基础先行

1、找到连续特征

1. 观察数据描述

查看数据样本:最直接的方法是先查看数据的一小部分样本。如用pandas库读取数据后,用head() 方法查看前几行数据。通过观察这几行数据,可以直观地判断哪些列看起来像是连续特征。例如,“年龄” 列的值可能是 25、30、35 这样的连续数值。

使用 decsribe() 方法:生成数据集中数值列的统计摘要,包括计数、均值、标准差、最小值、25% 分位数、50% 分位数(中位数)、75% 分位数和最大值。一般来说,具有连续数值特征的列,输出中会呈现均值、标准差等统计量,而且数值范围比较连续。对于离散特征,输出的信息更侧重于频次、众数等统计量 。

2. 根据数据类型判断

使用dtypes属性:通常,float64 和int64 类型的数据列很可能是连续特征,但也不完全绝对,需要结合实际情况判断。有些整数类型可能是离散计数变量,比如 “家庭人口数”,虽然是整数类型,但属于离散特征(取值不连续性、有限取值范围、更类似分类数据)

3. 领域知识辅助判断

结合业务背景:了解数据所代表的业务领域知识非常重要。例如,在医疗数据分析中,“血压” 值是连续特征,因为它可以在一定范围内连续取值,反映人体健康指标的连续变化;而 “疾病类别” 则是离散特征,因为疾病种类是有限的不同类别。

# 首先查看都有什么特征
import pandas as pd
data = pd.read_csv('data.csv')
data.head()

# 找到所有的连续特征(不完全准确)
continuous_features = []
for i in data.columns:
    if data[i].dtype != 'object':
        continuous_features.append(i)
continuous_features

# 或者更简单的方法(不完全准确)
continuous_features = data.select_dtypes(include=['float64', 'int64']).columns.tolist()
continuous_features

2、select_dtypes() 方法

是 pandas 库中 DataFrame 对象的一个方法,用于根据数据类型选择 DataFrame 的列。它在数据预处理和分析过程中非常有用,能帮助快速筛选出特定数据类型的列进行集中处理。

DataFrame.select_dtypes(include=None, exclude=None)

include:指定要包含的数据类型。可以是单个数据类型(如 ‘float64’)、数据类型的列表(如[ 'float64' , 'int64' ]),或者是 numpy 数据类型对象(如 np.number)。

exclude:指定要排除的数据类型。比如,想获取除了 object (通常用于表示字符串)类型之外的所有列,就可以使用 exclude='object'。

3、matplotlib 库

Matplotlib 是 Python 中一个非常流行且强大的绘图库,它能将数据可视化,更容易理解数据的模式、趋势和关系 。

1、绘图流程

  • 导入库:导入 import matplotlib.pyplot as plt,plt 是常用的别名,方便后续调用函数。

  • 准备数据:将要绘制的数据整理好,比如要画折线图,就准备好 x 轴和 y 轴对应的数据列表。

  • 调用绘图函数:根据想绘制的图形调用相应函数,像画折线图用 plt.plot(x, y) , x 是 x 轴数据,y 是 y 轴数据;画散点图用 plt.scatter(x, y)。

  • 设置图形属性:可以设置很多属性让图形更好看、更易读。比如给图形加标题 plt.title(‘图表标题’) ,给 x 轴、y 轴加标签 plt.xlabel(‘x轴标签’),plt.ylabel(‘y轴标签’) ,还能调整线条颜色、数据点形状等。

  • 显示图形:最后用 plt.show() 显示绘制好的图形。

 2、子图绘制

Matplotlib 能在一个图形窗口中绘制多个子图,方便对比不同数据。比如,同时展示不同城市的气温和降水量变化,就可以在一个大图形里创建两个子图,一个画气温折线图,另一个画降水量柱状图。通过 plt.subplot() 函数来指定子图的布局和位置。

4、seaborn库

是基于 Matplotlib 的 Python 数据可视化库 。它能轻松创建具有吸引力且信息丰富的统计图形。

1、主要图形类型:

  • 关系图

    • 散点图(scatterplot:和 Matplotlib 的散点图类似,用于展示两个变量之间的关系。不过 Seaborn 的散点图可以更方便地添加颜色、形状等维度来展示更多变量信息。

    • 折线图(lineplot:可展示数据随时间或其他连续变量的变化趋势。与 Matplotlib 不同,Seaborn 的折线图能自动处理多个数据点的聚合,比如计算均值并绘制带有置信区间的折线,不仅能看到平均趋势,还能了解到数据的可靠程度和波动范围。

  • 分布图

    • 直方图(histplot:用于展示数据在不同区间的分布频率。Seaborn 的直方图不仅可以绘制简单的频数分布,还能通过参数设置添加核密度估计曲线(KDE),更直观地展示数据分布形态。

    • 箱线图(boxplot:和 Matplotlib 箱线图功能相似,展示数据的中位数、四分位数和异常值。Seaborn 的箱线图在多组数据比较时优势明显,可以轻松按类别分组展示,像比较不同班级学生成绩分布时,能清晰看出班级间成绩的集中程度和离散情况。

    • 小提琴图(violinplot:结合了箱线图和核密度估计图的特点,既能展示数据的分布中心、离散程度和异常值,又能展示数据的概率密度分布。

  • 分类图

    • 柱状图(barplot:方便比较不同类别数据的数量或数值大小以及展示不同类别在总体中所占的比例情况。Seaborn 的柱状图可以轻松添加误差条,还能按多个类别进行分组展示。比如比较不同品牌不同型号产品的销量,可通过分组柱状图清晰呈现。

2、绘图流程

  • 导入库:一般使用 import seaborn as sns,sns 是常用别名。同时通常也会导入  matplotlib.pyplot 用于显示图形。

  • 准备数据:整理好要可视化的数据,通常是 pandas 库的 DataFrame 格式,方便 Seaborn 根据列名来映射变量。

  • 调用绘图函数:根据要绘制的图形类型调用相应函数,设置好变量映射、颜色、标签等参数。

  • 设置图形属性:可进一步设置图形标题、坐标轴标签、图例等属性。

  • 显示图形:使用 plt.show()  显示绘制好的图形。

二、单特征分布可视化

# 导入可视化库
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd

# 设置全局字体为支持中文的字体 (例如 SimHei)
plt.rcParams['font.sans-serif'] = ['SimHei']
# 解决负号'-'显示为方块的问题
plt.rcParams['axes.unicode_minus'] = False

sns.boxplot(x=data['Annual Income'])
plt.title('年收入 箱线图')  # 使用中文标题
plt.xlabel('年收入')      # x轴使用中文标签
plt.show()

箱线图结论:

中位数位置:箱线图中,箱体中间的线代表中位数。从图中看,中位数靠近箱体左侧,说明大部分数据集中在较低收入区间 。

数据离散程度:箱体较短,表明数据的中间 50%(即IQR)分布比较集中,说明收入数据在中间部分波动较小。

离群点情况:右侧的须较长且有多个离群点(圆圈表示),说明高收入端数据离散程度大,存在一些收入远高于大部分人群的个体 。

箱线图绘制过程:

数据排序:首先将数据从小到大进行排序。例如:3, 7, 8, 5, 12, 14, 21, 13, 18 ,排序后为:3, 5, 7, 8, 12, 13, 14, 18, 21 。然后计算四分位数:

下四分位数(Q1):排序后的数据样本中处于 25% 位置的数字。计算方法:如果数据个数为 n,当 n × 25% 不是整数时,向上取整,该位置对应的数据就是 Q1;当 n × 25% 是整数时,Q1 是该位置和下一个位置数据的平均值。对于上面的数据,n = 9,9 × 25% = 2.25,向上取整为 3,所以 Q1 = 7 。

中位数(Q2):将数据排序后,处于中间位置的数。如果数据个数 n 为奇数,中位数就是第 (n + 1) / 2 位置的数据;如果 n 为偶数,中位数是第 n / 2 和 (n / 2 + 1) 位置数据的平均值。对于上述数据,n = 9,中位数是第 (9 + 1) / 2 = 5 位置的数据,即 Q2 = 12 。

上四分位数(Q3):与 Q1 类似,是处于 75% 位置的数字。计算方法同 Q1,9 × 75% = 6.75,向上取整为 7,所以 Q3 = 14 。

绘制箱体:以 Q1 和 Q3 为边界绘制箱体,箱体中间画一条线表示中位数 Q2。在该例中,箱体的范围是从 7 到 14 ,中间的线在 12 的位置。

确定须(whiskers)的范围:一般情况下,下须的终点是 Q1 - 1.5 × IQR(IQR = Q3 - Q1,即四分位距)与数据中的最小值之间的较大值;上须的终点是 Q3 + 1.5 × IQR 与数据中的最大值之间的较小值。对于上述数据,IQR = 14 - 7 = 7 ,Q1 - 1.5 × IQR = 7 - 1.5 × 7 = -3.5 ,数据中的最小值是 3,所以下须终点是 3;Q3 + 1.5 × IQR = 14 + 1.5 × 7 = 24.5 ,数据中的最大值是 21,所以上须终点是 21 。如果数据中有值小于 Q1 - 1.5 × IQR 或者大于 Q3 + 1.5 × IQR ,这些值被视为异常值。在绘制箱线图时,异常值用离散点表示,不包含在须的范围内。

绘制须和异常值:根据上述确定的须的范围,从箱体两端绘制竖线到须的终点。同时,将异常值用离散点绘制在须的范围之外。


# 绘制直方图
sns.histplot(data['Years in current job'])
plt.title('在当前工作年限 直方图')
plt.xlabel('在当前工作年限')
plt.ylabel('员工数量')
plt.xticks(rotation=45, ha='right')  # 旋转45度,并右对齐
plt.show()

直方图与条形图:

直方图:用于展示连续型数据的分布。如人的身高、体重,温度等,这些数据在一定区间内可以取任意值。矩形之间紧密相连没有间隙。横轴表示分组区间,纵轴通常表示频数或频率。重点在于展示数据在各个区间内的分布情况,帮助我们了解数据的集中趋势、离散程度以及分布形状(是否对称、有无峰值等)。

条形图:适用于展示离散型数据,即数据是由不同类别组成。像不同的水果种类、不同的城市名称、不同的学科等。各个条形之间存在明显的间隙,横轴表示不同的类别,纵轴表示与该类别对应的数值。主要用于比较不同类别之间的数值大小关系。可以很直观地看出哪个类别在某个指标上表现更突出,哪个类别相对较弱。

三、特征与标签关系可视化

# 设置图形的大小为宽 8 英寸,高 6 英寸
plt.figure(figsize=(8, 6))

# 使用 seaborn 库绘制箱线图,指定箱线图的 x 轴、y 轴和使用的数据集
sns.boxplot(x='Credit Default', y='Annual Income', data=data)

# 设置图形的标题
plt.title('Annual Income vs. Credit Default')

# 设置 x 轴的标签
plt.xlabel('Credit Default')

# 设置 y 轴的标签
plt.ylabel('Annual Income')

# 显示绘制好的图形
plt.show()

箱线图结论:

整体离散程度:两组数据(信用违约值为 0 和 1 )都存在较多离群点,说明高收入个体较多,年收入数据离散程度大 。

箱体区间:信用违约值为 0 和 1 时,箱体位置和长度相近,说明在两种信用违约状态下,中间 50% 的个体年收入分布范围类似,且集中程度相似。

中位数:两组数据箱体中的横线(代表中位数)位置接近,表明信用违约值为 0 和 1 的个体,年收入中位数相差不大。

因果关联:从图中无法明显看出信用违约状态(0 或 1 )与年收入之间存在强关联。因为不同信用违约状态下,年收入的分布特征(如中位数、离散程度等 )差异不显著。


# 小提琴图
plt.figure(figsize=(8, 6))
sns.violinplot(x='Credit Default', y='Annual Income', data=data)
plt.title('Annual Income vs. Credit Default')
plt.xlabel('Credit Default')
plt.ylabel('Annual Income')
plt.show()

小提琴图是将核密度估计和箱线图元素结合绘制出来的,从而直观展示数据的分布形态、集中趋势(如中位数 )、离散程度(如四分位数间距 )以及概率密度等信息 。

小提琴图结论:

年收入分布:图中展示了信用违约值为 0 和 1 时对应的年收入分布情况。小提琴图的宽度反映了数据的分布密度 ,越宽表示该年收入区间的数据点越密集。可以看出,年收入数据在不同信用违约状态下都有一定的分布范围,并非集中在某一个值。

集中趋势:图中黑色粗线代表中位数,可见信用违约值为 0 和 1 时,年收入中位数位置相近,说明不同信用违约状态下,年收入的中间水平差异不大。

离散程度:小提琴图的延展范围体现数据离散程度,两侧图形延展范围类似,表明信用违约值为 0 和 1 的情况下,年收入数据离散程度大致相同 。

对比关系:对比左右两侧图形,整体形态和位置差异不明显,意味着信用违约状态(0 或 1 )与年收入之间没有明显的分布差异,难以看出二者存在强关联。

小提琴图绘制过程:

先对不同信用违约类别(0 和 1 )下的年收入数据分别进行核密度估计,得到各自的概率密度函数曲线。然后以年收入取值范围为横轴,密度为纵轴,将曲线沿着数轴展开并绘制镜像,得到小提琴体。再在小提琴体中间对称轴位置,添加箱线图元素 。即:

连续变量直方图:

# 带核密度估计曲线的阶梯状直方图,用核密度估计完成边缘的柔和化
plt.figure(figsize=(8, 6))
sns.histplot(x='Annual Income', hue='Credit Default', data=data, kde=True, element="step")
plt.title('Annual Income vs. Credit Default')
plt.xlabel('Annual Income')
plt.ylabel('Count')
plt.show()

sns.histplot() 函数用于绘制直方图。
x='Annual Income':指定绘制直方图的数据列。
hue='Credit Default':根据 data 数据集中名为 Credit Default 的列对数据进行分组,不同组的数据会用不同的颜色在直方图中显示,这样可以比较不同信用违约状态下的年收入分布。
kde=True:表示在直方图上同时绘制核密度估计曲线(KDE),用于展示数据的概率密度分布。
element="step":指定直方图绘制元素为阶梯状,即柱子的边界是阶梯状,而不是填充的矩形。

结论:

年收入分布特征:

整体趋势:对于信用违约值为 0(蓝色)和 1(橙色)的群体 ,年收入分布均呈现出左偏态。即大部分人的年收入集中在较低区间,随着年收入增加,人数逐渐减少。

峰值差异:信用违约值为 0 的群体,年收入分布的峰值更高且更靠左,说明未发生信用违约的人群中,在较低年收入区间的人数占比更大且更为集中。

年收入与信用违约关系

分布重叠:两种颜色的分布曲线有明显重叠部分,表明仅依据年收入难以完全区分是否会发生信用违约,存在年收入相同但信用违约状态不同的情况。

差异趋势:在较低年收入区间,信用违约值为 0 的人数明显多于值为 1 的人数;但随着年收入增加,信用违约值为 1 的群体人数占比相对增加,说明高收入人群中发生信用违约的比例相对有所上升 ,不过总体上高收入人群无论是违约还是未违约数量都较少。

离散变量条形图:

plt.figure(figsize=(8, 6))
sns.countplot(x='Number of Open Accounts', hue='Credit Default', data=data)
plt.title('Number of Open Accounts vs. Credit Default')
plt.xlabel('Number of Open Accounts')
plt.ylabel('Count')
plt.show()

 从上图可以看出值太多不美观,可以采用分组:

# 根据数据调整分组
data['Open Accounts Group'] = pd.cut(data['Number of Open Accounts'], bins=[0, 5, 10, 15, 20, float('inf')], labels=['0-5', '6-10', '11-15', '16-20', '20+']) 

plt.figure(figsize=(10, 6))
sns.countplot(x='Open Accounts Group', hue='Credit Default', data=data)
plt.title('Number of Open Accounts (Grouped) vs. Credit Default')
plt.xlabel('Number of Open Accounts Group')
plt.ylabel('Count')
plt.show()

!!!虽然未结清账户数量是离散变量,但在数据分析中,常通过分组(类似分箱)简化数据分布,避免因离散值过多导致可视化结果杂乱。

本质是 “离散变量的分组聚合”,与连续变量分箱(将连续区间划分为离散段)的逻辑类似,但离散变量分组的对象本身已是整数,分组仅为了聚合统计,而非强制离散化。

连续特征处理

import pandas as pd
# feature_1 是连续特征
data = {'feature_1': [1, 5, 10, 15, 20, 25, 30, 35, 40, 45]}
df = pd.DataFrame(data)
# 将 feature_1 分为 3 个区间
df['feature_1_binned'] = pd.cut(df['feature_1'], bins=3, labels=['Low', 'Medium', 'High'])
print(df)
# 输出:
feature_1 feature_1_binned
0          1              Low
1          5              Low
2         10              Low
3         15              Low
4         20           Medium
5         25           Medium
6         30           Medium
7         35             High
8         40             High
9         45             High

特征分组(分箱,Binning):默认按照等宽分箱:将数据的值域(最大值-最小值)均匀划分为指定数量的区间(bins),每个区间的宽度相等。

pd.cut() 方法:

是 Pandas 库中一个非常实用的函数,主要用于将连续型数据进行离散化处理,也就是把连续的数据划分成不同的区间(箱子),并为每个区间赋予一个标签。

语法:pd.cut(x, bins, right=True, labels=None, retbins=False, precision=3, include_lowest=False, duplicates='raise', ordered=True)

x:需要进行分箱操作的一维数组,可以是 Pandas 的 Series 或 Numpy 的数组。

bins:用于定义分箱的方式,可将数据划分为指定数量的等宽区间,例如 bins=3 表示将数据划分为 3 个等宽的区间。也可指定分箱的边界。例如 bins=[0, 3, 6, 10] 表示将数据划分为 [0, 3),[3, 6),[6, 10] 这 3 个区间。

labels:用于为每个区间指定标签。可以是一个列表或者数组,长度要与分箱的数量一致。如果不指定,默认使用区间的字符串表示。


@浙大疏锦行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值