目标检测XML格式探索性数据分析(EDA)模板

1、探索性数据分析介绍

探索性数据分析是拿到原始数据后,通过技术手段帮助自己更好的理解数据、提取出“好特征”、建立初步模型的过程。
探索性数据分析(Exploratory Data Analysis,EDA)主要的工作是:对数据进行清洗,对数据进行描述(描述统计量,图表),查看数据的分布,比较数据之间的关系,培养对数据的直觉,对数据进行总结等。

在统计学中,探索性数据分析(EDA)是一种分析 数据集以总结其主要特征的方法,通常使用统计图形和其他数据可视化方法。可以使用或不使用统计模型,但主要是 EDA 用于查看数据可以告诉我们超出正式建模的内容,从而对比传统的假设检验。自 1970 年以来, John Tukey一直在推广探索性数据分析,以鼓励统计学家探索数据,并可能提出可能导致新数据收集和实验的假设。EDA 不同于初始数据分析 (IDA), 更侧重于检查模型拟合和假设检验所需的假设,并根据需要处理缺失值和进行变量转换。

在这里插入图片描述

2、数据处理

2.1 解压数据集

这个voc128数据集,是我从yolov5的coco128的yolo格式转换而来,可用于一些模型验证。

!unzip -oq /home/aistudio/data/data162811/voc128.zip -d work/

2.1 将voc的xml格式转换为csv

为了更便于进行数据分析,可将xml的一些数据转换为csv格式进行操作。

import os
import glob
import pandas as pd
import xml.etree.ElementTree as ET
import matplotlib.pyplot as plt
import seaborn as sns

定义并实现xml转换csv格式的功能函数

def xml_to_csv(path):
    """Iterates through all .xml files (generated by labelImg) in a given directory and combines them in a single Pandas datagrame.

    Parameters:
    ----------
    path : {str}
        The path containing the .xml files
    Returns
    -------
    Pandas DataFrame
        The produced dataframe
    """
    classes_names = []
    xml_list = []
    for xml_file in glob.glob(path + "/*.xml"):
        tree = ET.parse(xml_file)
        root = tree.getroot()
        for member in root.findall("object"):
            classes_names.append(member[0].text)
            value = (
                root.find("filename").text,
                int(root.find("size")[0].text),
                int(root.find("size")[1].text),
                member[0].text,
                int(member[4][0].text),
                int(member[4][1].text),
                int(member[4][2].text),
                int(member[4][3].text),
            )
            xml_list.append(value)
    column_name = [
        "filename",
        "width",
        "height",
        "class",
        "xmin",
        "ymin",
        "xmax",
        "ymax",
    ]
    xml_df = pd.DataFrame(xml_list, columns=column_name)
    classes_names = list(set(classes_names))
    classes_names.sort()
    return xml_df, classes_names
# 主运行函数
def run(inputDir,outputFile,labelMapDir):
    if inputDir is None:
        inputDir = os.getcwd()
    if outputFile is None:
        outputFile = inputDir + "/labels.csv"

    os.makedirs(os.path.dirname(outputFile), exist_ok=True)
    xml_df, classes_names = xml_to_csv(inputDir)
    xml_df.to_csv(outputFile, index=None)
    print("Successfully converted xml to csv.")
    if labelMapDir:
        os.makedirs(labelMapDir, exist_ok=True)
        label_map_path = os.path.join(labelMapDir, "label_map.pbtxt")
        print("Generate `{}`".format(label_map_path))

        # Create the `label_map.pbtxt` file
        pbtxt_content = ""
        for i, class_name in enumerate(classes_names):
            pbtxt_content = (
                pbtxt_content
                + "item {{\n    id: {0}\n    name: '{1}'\n}}\n\n".format(
                    i + 1, class_name
                )
            )
        pbtxt_content = pbtxt_content.strip()
        with open(label_map_path, "w") as f:
            f.write(pbtxt_content)
inputDir = 'work/voc128/Annotations'
outputFile = 'work/Annotations.csv'
labelMapDir = 'work/'
run(inputDir, outputFile, labelMapDir)
Successfully converted xml to csv.
Generate `work/label_map.pbtxt`

3、使用Pandas进行数据分析

下面使用Pandas对csv进行数据分析

3.1 读取csv并显示

df_data = pd.read_csv('work/Annotations.csv')
print(df_data.info())
print(df_data.describe())
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 929 entries, 0 to 928
Data columns (total 8 columns):
 #   Column    Non-Null Count  Dtype 
---  ------    --------------  ----- 
 0   filename  929 non-null    object
 1   width     929 non-null    int64 
 2   height    929 non-null    int64 
 3   class     929 non-null    object
 4   xmin      929 non-null    int64 
 5   ymin      929 non-null    int64 
 6   xmax      929 non-null    int64 
 7   ymax      929 non-null    int64 
dtypes: int64(6), object(2)
memory usage: 58.2+ KB
None
            width      height        xmin       ymin        xmax        ymax
count  929.000000  929.000000  929.000000  929.00000  929.000000  929.000000
mean   595.254037  477.569429  251.427341  198.16577  353.397201  307.895587
std     79.209865   91.966002  172.535352  115.98576  169.402088  131.950915
min    333.000000  218.000000    0.000000    0.00000    6.000000   18.000000
25%    591.000000  427.000000  108.000000  111.00000  215.000000  214.000000
50%    640.000000  480.000000  236.000000  197.00000  361.000000  303.000000
75%    640.000000  484.000000  387.000000  274.00000  484.000000  392.000000
max    640.000000  640.000000  628.000000  596.00000  640.000000  640.000000

3.2 查看前5条数据

sample_for_plotting = df_data[['width','height','class', 'xmin','ymin','xmax','ymax']]
data_head = sample_for_plotting.head()
data_head
widthheightclassxminyminxmaxymax
0600500bird426192558368
1600500bird128104223271
2600500bird265126365289
3600500bird243271340391
4600500bird114319206480
plotting_group= sample_for_plotting.groupby('class')
data_class_head = plotting_group.head()
data_class_head
widthheightclassxminyminxmaxymax
0480640sports ball207238254287
1480640person165107394379
2480640person15781211190
3480640person64198121234
4480640person135148175230
........................
886423640toothbrush18857266279
887423640toothbrush6381146264
894640480refrigerator428171525309
912640480microwave377227430257
913640480oven274263321297

301 rows × 7 columns

3.3 分别查看各列信息

这里分别查看各列的信息,例如xmin、xmax,ymin、ymax。

# xmin
data_xmin = df_data.groupby('class').mean()['xmin']
data_xmin
class
airplane          168.833333
backpack          224.500000
banana            106.000000
baseball bat      247.250000
baseball glove    275.428571
                     ...    
tv                236.500000
umbrella          203.722222
vase              227.500000
wine glass        160.312500
zebra              72.500000
Name: xmin, Length: 71, dtype: float64
# ymin
data_ymin = df_data.groupby('class').mean()['ymin']
data_ymin
class
airplane           62.000000
backpack          277.333333
banana            374.000000
baseball bat      256.750000
baseball glove    199.000000
                     ...    
tv                232.500000
umbrella           87.555556
vase              104.500000
wine glass        164.375000
zebra             155.000000
Name: ymin, Length: 71, dtype: float64
# xmax
data_xmax = df_data.groupby('class').mean()['xmax']
data_xmax
class
airplane          579.833333
backpack          284.500000
banana            378.000000
baseball bat      286.250000
baseball glove    299.142857
                     ...    
tv                412.500000
umbrella          317.555556
vase              327.500000
wine glass        205.875000
zebra             363.750000
Name: xmax, Length: 71, dtype: float64
# ymax
data_ymax = df_data.groupby('class').mean()['ymax']
data_ymax
class
airplane          266.666667
backpack          350.500000
banana            566.000000
baseball bat      300.250000
baseball glove    220.571429
                     ...    
tv                388.000000
umbrella          187.055556
vase              226.500000
wine glass        240.625000
zebra             382.000000
Name: ymax, Length: 71, dtype: float64

3.4 统计各列频次

下面统计各类出现的频次,这就是在voc格式数据集中各类别的标记个数。

# 计算class标记频次
count = pd.value_counts(df_data['class'])
count
person      254
car          46
cup          36
chair        35
book         29
           ... 
horse         2
banana        1
scissors      1
bear          1
skis          1
Name: class, Length: 71, dtype: int64

3.5 绘制直方图

直方图(Histogram),又称质量分布图,是一种统计报告图,由一系列高度不等的纵向条纹或线段表示数据分布的情况。 一般用横轴表示数据类型,纵轴表示分布情况。
直方图是数值数据分布的精确图形表示。 这是一个连续变量(定量变量)的概率分布的估计,并且被卡尔·皮尔逊(Karl Pearson)首先引入。它是一种条形图。 为了构建直方图,第一步是将值的范围分段,即将整个值的范围分成一系列间隔,然后计算每个间隔中有多少值。 这些值通常被指定为连续的,不重叠的变量间隔。 间隔必须相邻,并且通常是(但不是必须的)相等的大小。
直方图也可以被归一化以显示“相对”频率。 然后,它显示了属于几个类别中的每个案例的比例,其高度等于1。

通过绘制直方图来直观的查看width、height等数据。

df_data.hist(figsize=(20,30)) 
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x7faa4a947090>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7faa4a8ef910>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x7faa4a8a5250>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7faa4a8cfb50>],
       [<matplotlib.axes._subplots.AxesSubplot object at 0x7faa4a883490>,
        <matplotlib.axes._subplots.AxesSubplot object at 0x7faa4a8834d0>]],
      dtype=object)

在这里插入图片描述

3.6 绘制箱形图

箱形图(Box-plot)又称为盒须图、盒式图或箱线图,是一种用作显示一组数据分散情况资料的统计图。因形状如箱子而得名。在各种领域也经常被使用,常见于品质管理。它主要用于反映原始数据分布的特征,还可以进行多组数据分布特征的比 较。箱线图的绘制方法是:先找出一组数据的上边缘、下边缘、中位数和两个四分位数;然后, 连接两个四分位数画出箱体;再将上边缘和下边缘与箱体相连接,中位数在箱体中间。

通过箱形图,我们可以分析其数据异常值、偏态和尾重、数据的形状等。

sns.boxplot(x="class", y="xmin", data = df_data)
sns.boxplot(x="class", y="xmax", data = df_data)
sns.boxplot(x="class", y="ymin", data = df_data)
sns.boxplot(x="class", y="ymax", data = df_data)
<matplotlib.axes._subplots.AxesSubplot at 0x7faa48f104d0>

在这里插入图片描述

sns.boxplot(x="class", y="width", data = df_data)
sns.boxplot(x="class", y="height", data = df_data)
<matplotlib.axes._subplots.AxesSubplot at 0x7faa4295bed0>

在这里插入图片描述

3.7 绘制散点图

散点图是指在回归分析中,数据点在直角坐标系平面上的分布图,散点图表示因变量随自变量而变化的大致趋势,据此可以选择合适的函数对数据点进行拟合。
用两组数据构成多个坐标点,考察坐标点的分布,判断两变量之间是否存在某种关联或总结坐标点的分布模式。散点图将序列显示为一组点。值由点在图表中的位置表示。类别由图表中的不同标记表示。散点图通常用于比较跨类别的聚合数据。

散点图可以提供关键信息是:
1、变量之间是否存在数量关联趋势
2、如果存在关联趋势,是线性还是曲线的
3、如果有某一个点或者某几个点偏离大多数点,也就是离群值,通过散点图可以一目了然。从而可以进一步分析这些离群值是否可能在建模分析中对总体产生很大影响。

sns.pairplot(df_data)
<seaborn.axisgrid.PairGrid at 0x7faa4119c710>

在这里插入图片描述

3.8 查看各列离散程度

displot()集合了matplotlib的hist()与核函数估计kdeplot的功能,增加了rugplot分布观测条显示与利用scipy库fit拟合参数分布的新颖用途。

sns.distplot(df_data['ymin'])
sns.distplot(df_data['ymax'])
<matplotlib.axes._subplots.AxesSubplot at 0x7faa401adc50>

在这里插入图片描述

sns.distplot(df_data['xmin'])
sns.distplot(df_data['xmax'])
<matplotlib.axes._subplots.AxesSubplot at 0x7faa4004d450>

在这里插入图片描述

sns.distplot(df_data['width'])
sns.distplot(df_data['height'])
<matplotlib.axes._subplots.AxesSubplot at 0x7faa3ffe0e50>

在这里插入图片描述

3.9 查看heatmap

Heatmap 可以用颜色变化来反映二维矩阵或表格中的数据信息,它可以直观地将数据值的大小以定义的颜色深浅表示出来。

常根据需要将数据进行聚类,将聚类后的数据表示在heatmap图上,通过颜色的梯度及相似程度来反映数据的相似性和差异性。

热图是展示数据表达差异非常直观的方法,

corr= df_data.corr()
sns.heatmap(corr, annot=True)
<matplotlib.axes._subplots.AxesSubplot at 0x7faa3fe80390>

在这里插入图片描述

4、pandas_profiling生成数据分析报告

这个方法墙裂推荐!!

pandas_profiling是第三方库,是基于pandas的DataFrame数据类型,可以简单快速地进行探索性数据分析,这个库只需要三行代码就可以生成数据EDA报告。
对于数据集的每一列,pandas_profiling会提供以下统计信息:

1)、概要:数据类型,唯一值,缺失值,内存大小
2)、分位数统计:最小值、最大值、中位数、Q1、Q3、最大值,值域,四分位

3)、描述性统计:均值、众数、标准差、绝对中位差、变异系数、峰值、偏度系数

4)、最频繁出现的值,直方图/柱状图

5)、相关性分析可视化:突出强相关的变量,Spearman, Pearson矩阵相关性色阶图

并且这个报告可以导出为HTML,非常方便查看。

!pip install pandas_profiling
import numpy as np
import pandas as pd
from pandas_profiling import ProfileReport
def generate_profile_pandas(file_names, file_type):
    # 读取数据
    df = pd.read_csv(file_names)
    # 数据分析
    profile = ProfileReport(df, title="Data Report", explorative=True)
    if file_type == 'html':
        # html分析报告生成
        profile.to_file("your_report.html")
    elif file_type == 'json':
        # json分析报告生成
        # As a JSON string
        json_data = profile.to_json()
        # As a file
        # profile.to_file("your_report.json")
    elif file_type == 'jupyter':
        # jupyernotebook分析报告生成
        profile.to_widgets()
        profile.to_notebook_iframe()
file_name = '/home/aistudio/work/Annotations.csv'
file_type = 'jupyter'
generate_profile_pandas(file_name, file_type)
## 直接在这里运行会有错误,建议在本地运行。
#保存在work/your_report.html,可下载到本地查看。

在这里插入图片描述

在这里插入图片描述

5、使用sweetviz生成数据报告

Sweetviz是一个开放源代码Python库,可生成精美的高密度可视化文件,以单行代码启动EDA(探索性数据分析)。

输出是一个完全独立的HTML应用程序,该系统围绕快速可视化目标值和比较数据集而构建。

其目标是帮助快速分析目标特征,训练与测试数据以及其他此类数据表征任务

!pip install sweetviz
import sweetviz as sv
import pandas as pd
file_name = '/home/aistudio/work/Annotations.csv'

# 读取数据
df = pd.read_csv(file_name)
my_report = sv.analyze(df)
# Default arguments will generate to "SWEETVIZ_REPORT.html"
my_report.show_html()

在这里插入图片描述

6、总结

探索性数据分析就是利用各种技术手段(大部分都是利用数据可视化)探索数据内部结构和规律的一种数据分析方法和理念。

探索性数据分析的过程大致分为3步:

数据分类
数据可视化
洞察数据

第一步:数据分类
当我们拿到数据后,第一步就是把这些数据进行分类,然后用不同方法来处理不同类型的数据。

第二步:数据可视化
为了更好的洞察数据,我们可以将数据可视化,从而更好的观察数据的特点。
数据等级属性描述性统计图表定类离散、无序频率占比、众数条形图、饼图定序有序类别、比较频率、众数、中位数、百分位数条形图、饼图定距数字差别有意义频率、众数、中位数、均值、标准差条形图、饼图、箱线图定比连续均值、标准差条形图、曲线图、饼图、箱线图

第三步:洞察数据
数据的可视化可以帮助我们更好的洞察数据,我们可以更高效的发现哪些数据更重要,不同数据之间可能存在的关系,哪些数据会相互影响…

此文章为搬运
原项目链接

Logo

学大模型,用大模型上飞桨星河社区!每天8点V100G算力免费领!免费领取ERNIE 4.0 100w Token >>>

更多推荐