• DataWhale《零基础入门数据挖掘》第二次打卡


    在这里插入图片描述

    第二次打卡(3月22日-3月24日)

    菜鸡的学习之路^__^(自己学习,复习使用)
    Task2:数据的探索性分析(EDA)

    1.1 EDA要做什么

    首先我们需要明白EDA要做什么:

    1. 了解数据大致表达了什么
    2. 挖掘数据结构(结构化;图像化)
    3. 初步分理处一些重要特征
    4. 挖掘离群数据和异常数据
    5. 初步确定可以用那些模型

    1.2 具体内容

    1. 载入各种数据科学以及可视化库:
    • 数据科学库 pandas、numpy、scipy;
    • 可视化库 matplotlib、seabon;
    • 其他;
    1. 载入数据:
    • 载入训练集和测试集;
    • 简略观察数据(head()+shape);
    1. 数据总览:
    • 通过describe()来熟悉数据的相关统计量
    • 通过info()来熟悉数据类型
    1. 判断数据缺失和异常:
    • 查看每列的存在nan情况
    • 异常值检测
    1. 了解预测值的分布:
    • 总体分布概况(无界约翰逊分布等)
    • 查看skewness and kurtosis
    • 查看预测值的具体频数
    1. 特征分为类别特征和数字特征,并对类别特征查看unique分布
    2. 数字特征分析:
    • 相关性分析
    • 查看几个特征得
    • 偏度和峰值
    • 每个数字特征得分布可视化
    • 数字特征相互之间的关系可视化
    • 多变量互相回归关系可视化
    1. 类型特征分析:
    • unique分布
    • 类别特征箱形图可视化
    • 类别特征的小提琴图可视化
    • 类别特征的柱形图可视化类别
    • 特征的每个类别频数可视化(count_plot)
    1. 用pandas_profiling生成数据报告

    2.3 代码

    载入数据科学以及可视化库

    import numpy as np
    import pandas as pd
    import warnings
    import os,sys
    
    project_path = os.path.dirname(os.path.abspath("__file__")) 
    # 设置动态路径
    # 获取当前文件路径的上一级目录
    warnings.filterwarnings('ignore')
    pd.set_option('display.max_columns', None) # 设置DataFrame的输出显示,显示所有列
    
    # 载入数据集
    train_data = pd.read_csv(project_path + r'used_car_train_20200313.csv', sep=' ')
    test_data = pd.read_csv(project_path + r'used_car_testA_20200313.csv', sep=' ')
    
    print('train_data_shape:', train_data.shape)
    print('test_data_shape:', test_data.shape)
    
    train_data_shape: (150000, 31)
    test_data_shape: (50000, 30)
    
    train_data.head()
    

    在这里插入图片描述

    train_data.describe()
    # price一列
    # 均值:5923
    # 标准差:7501
    # 最小值: 11
    # 最大值:99999,偏离程度有点大
    

    在这里插入图片描述

    首先把训练集读取进来看看各列的情况,主要看一下预测目标price的情况,发现均值在5900左右,标准差在7500左右,然而最大值居然有99999,可以看出事情并不简单,回归问题最怕离群点。(心里仿佛受到一万点打击。。。。)

    # 画图看看
    import matplotlib.pyplot as plt
    import seaborn as sns
    
    plt.figure()
    sns.distplot(train_data['price'])
    plt.figure()
    train_data['price'].plot.box()
    plt.show()
    
    在这里插入图片描述 在这里插入图片描述

    直接画图看一下,发现事情并不简单,可以看出数据的分布并不是标准的正态分布,远处的离群点看起来并不少,训练起来估计误差会很大,训练的时候可以考虑把这些离群点去掉。但如果测试集也有类似的点,那就没办法了,回归场景里面,一个离群点带来的误差可能会拖垮整个数据集上的指标分数。

    import gc
    print(test_data.shape)
    print(train_data.shape)
    
    (50000, 30)
    (150000, 31)
    
    df = pd.concat([train_data, test_data], axis=0, ignore_index=True)
    del train_data, test_data
    gc.collect()
    df.head()
    

    在这里插入图片描述

    把测试集也读进来看看全数据情况

    # 把特征分为3类
    date_cols = ['regDate', 'creatDate']
    category_cols = [
        'name', 'model', 'brand', 'bodyType', 'fuelType', 'gearbox',
        'notRepairedDamage', 'regionCode', 'seller', 'offerType'
    ]
    number_cols = ['power', 'kilometer'] + ['v_{}'.format(i) for i in range(15)]
    cols = date_cols + category_cols + number_cols
    
    tmp = pd.DataFrame()
    tmp['count'] = df[cols].count().values  # 每一个特征样本数目统计
    tmp['missing_rate'] = (df.shape[0] - tmp['count']) / df.shape[0]  # 每一个特征样本缺失率
    tmp['nunique'] = df[cols].nunique().values  # 每一个特征不同取值数目
    tmp['max_value_counts'] = [df[f].value_counts().values[0]
                               for f in cols]  # 每个特征最大值出现次数
    tmp['max_value_counts_prop'] = tmp['max_value_counts'] / df.shape[
        0]  # 每个特征最大值出现率
    tmp['max_value_counts_value'] = [df[f].value_counts().index[0]
                                     for f in cols]  # 每个特征最大值
    tmp.index = cols  # 修改index
    tmp
    # seller, offerType两个特征可以删除了,就1个值,没啥用
    

    在这里插入图片描述

    把特征分成三部分,分别是日期特征、类别特征、数值特征。然后看看每一维特征的缺失率、n unique等信息,可以发现seller、offerType这两个特征可以删掉了,所有样本就一个取值,没什么用。从这里还可以发现匿名特征里面的v_0到v_4、v_10到v_14感觉长的有点像,貌似有很多相似的地方。

    from tqdm import tqdm # 进度条配置
    
    # 日期处理函数
    def date_proc(x):
        m = int(x[4:6])
        if m == 0:
            m = 1
        return x[:4] + '-' + str(m) + '-' + x[6:]
    
    for f in tqdm(date_cols):
        df[f] = pd.to_datetime(df[f].astype('str').apply(date_proc))
        df[f + '_year'] = df[f].dt.year
        df[f + '_month'] = df[f].dt.month
        df[f + '_day'] = df[f].dt.day
        df[f + '_dayofweek'] = df[f].dt.dayofweek
    

    在这里插入图片描述

    把日期列处理一下,提取年、月、日、星期等信息。这里有些日期异常的样本,月份出现了0,因此需要开个函数单独处理一下。

    plt.figure()
    plt.figure(figsize=(16, 6))
    i = 1
    for f in date_cols:
        for col in ['year', 'month', 'day', 'dayofweek']:
            plt.subplot(2, 4, i)
            i += 1
            v = df[f + '_' + col].value_counts()
            fig = sns.barplot(x=v.index, y=v.values)
            for item in fig.get_xticklabels():
                item.set_rotation(90)
            plt.title(f + '_' + col)
    plt.tight_layout()
    plt.show()
    

    在这里插入图片描述

    看一下这些日期相关的特征的分布,可以看出汽车上线时间的年份(creatDate_year)基本上都是2016年,这个特征也没什么用了。creatDate_month基本上只有3、4两个月的,可以暂且保留,不过这种情况还是挺奇怪的,难道大家都热衷于在3月份卖车么?也可能跟行业有关吧,不懂。

    # 进行特征删改
    category_cols.remove('seller')
    category_cols.remove('offerType')
    date_cols = [
        'regDate_year', 'regDate_month', 'regDate_day', 'regDate_dayofweek',
        'creatDate_month', 'creatDate_day', 'creatDate_dayofweek'
    ]
    
    # 看一下各个数值特征跟price的相关性
    corr1 = abs(df[~df['price'].isnull()][['price'] + date_cols + number_cols].corr())
    plt.figure(figsize=(10, 10))
    sns.heatmap(corr1, linewidths=0.1, cmap=sns.cm.rocket_r)
    

    在这里插入图片描述

    看一下各个数值特征跟price的相关性。跟price相关性比较高的有汽车注册年份(regDate_year),应该可以理解为车越新,价格越高;汽车已行驶公里数(kilometer)也还行,应该可以理解为跑的路程越多,车就越旧,价格就越低;匿名特征里面的v_0、v_3、v_8、v_12看起来跟price的相关性很高,原因就不知道了。除了跟price的相关性,还可以发现有些特征跟特征之间的相关性也很高,比如v_1跟v_6、v_2跟v_7、v_3跟v_8、v_4跟v_9等,这些特征之间可能存在冗余现象,训练的时候可以依据效果尝试去掉一部分,或者拆分成两部分,做模型融合。

    # 看看15维匿名特征在训练集和测试集上的分布
    plt.figure()
    plt.figure(figsize=(15, 15))
    i = 1
    for f in number_cols[2:]:
        plt.subplot(5, 3, i)
        i += 1
        sns.distplot(df[~df['price'].isnull()][f],
                     label='train',
                     color='y',
                     hist=False)
        sns.distplot(df[df['price'].isnull()][f],
                     label='test',
                     color='g',
                     hist=False)
    plt.tight_layout()
    plt.show()
    

    在这里插入图片描述

    看看15维匿名特征分别在训练集和测试集上的分布,如果发现分布不一致的,可以尝试处理。但是貌似这15维特征在训练集和测试集上的分布基本上都挺一致的,无论多奇怪的分布,两个数据集上都挺一致。

    plt.figure()
    plt.figure(figsize=(20, 18))
    i = 1
    for f in category_cols + date_cols + number_cols:
        if df[f].nunique() <= 50:
            plt.subplot(5, 3, i)
            i += 1
            v = df[~df['price'].isnull()].groupby(f)['price'].agg({f + '_price_mean': 'mean'}).reset_index()
            fig = sns.barplot(x=f, y=f + '_price_mean', data=v)
            for item in fig.get_xticklabels():
                item.set_rotation(90)
    plt.tight_layout()
    plt.show()
    

    在这里插入图片描述

    简单看几个nunique比较小的特征上面的price的均值的分布。可以发现regDate_year和kilometer的趋势变化很明显,这也对应了上面的相关性分布,这两个特征跟price的相关性都挺高。kilometer应该是被离散化过的,只保留了整数。

    2.4 总结

    数据探索在机器学习中我们一般称为EDA(Exploratory Data Analysis):

    是指对已有的数据(特别是调查或观察得来的原始数据)在尽量少的先验假定下进行探索,通过作图、制表、方程拟合、计算特征量等手段探索数据的结构和规律的一种数据分析方法。

    数据探索有利于我们发现数据的一些特性,数据之间的关联性,对于后续的特征构建是很有帮助的。

    1. 对于数据的初步分析(直接查看数据,或.sum(), .mean(),.descirbe()等统计函数)可以从:样本数量,训练集数量,是否有时间特征,是否是时许问题,特征所表示的含义(非匿名特征),特征类型(字符类似,int,float,time),特征的缺失情况(注意缺失的在数据中的表现形式,有些是空的有些是”NAN”符号等),特征的均值方差情况。

    2. 分析记录某些特征值缺失占比30%以上样本的缺失处理,有助于后续的模型验证和调节,分析特征应该是填充(填充方式是什么,均值填充,0填充,众数填充等),还是舍去,还是先做样本分类用不同的特征模型去预测。

    3. 对于异常值做专门的分析,分析特征异常的label是否为异常值(或者偏离均值较远或者事特殊符号),异常值是否应该剔除,还是用正常值填充,是记录异常,还是机器本身异常等。

    4. 对于Label做专门的分析,分析标签的分布情况等。

    5. 进步分析可以通过对特征作图,特征和label联合做图(统计图,离散图),直观了解特征的分布情况,通过这一步也可以发现数据之中的一些异常值等,通过箱型图分析一些特征值的偏离情况,对于特征和特征联合作图,对于特征和label联合作图,分析其中的一些关联性。

    参考内容:

    1. Datawhale 零基础入门数据挖掘-Task2 数据分析
    2. 详解seaborn中的kdeplot、rugplot、distplot与jointplot
    3. 机器学习实战:基于Scikit-Learn和TensorFlow
    4. 【机器学习】菜菜的sklearn课堂

    关于Datawhale:

    Datawhale是一个专注于数据科学与AI领域的开源组织,汇集了众多领域院校和知名企业的优秀学习者,聚合了一群有开源精神和探索精神的团队成员。Datawhale 以“for the learner,和学习者一起成长”为愿景,鼓励真实地展现自我、开放包容、互信互助、敢于试错和勇于担当。同时 Datawhale 用开源的理念去探索开源内容、开源学习和开源方案,赋能人才培养,助力人才成长,建立起人与人,人与知识,人与企业和人与未来的联结。

    在此特别感谢DataWhale提供的学习机会,为其开源精神点赞,希望自己能在自己的努力下不断进步,很幸运能遇到DataWhale这么优秀的平台。加油加油!!!!
    在这里插入图片描述

  • 相关阅读:
    洛谷 P1089.津津的储蓄计划
    AcWing 786.第k个数
    差分
    AcWing 798.差分矩阵
    AcWing 797.差分
    AcWing 796.子矩阵的和
    Python 初始—(项目 目录结构)
    Python 初始—(迭代器和生成器)
    Python 初始—(装饰器)
    Python 初始—(高阶函数)
  • 原文地址:https://www.cnblogs.com/Jack-Tim-TYJ/p/12831935.html
Copyright © 2020-2023  润新知