其他分享
首页 > 其他分享> > “零基础入门数据挖掘 - 二手车交易价格预测”学习赛的Task02-学习日志

“零基础入门数据挖掘 - 二手车交易价格预测”学习赛的Task02-学习日志

作者:互联网

文章目录


前言

本文章为天池“零基础入门数据挖掘 - 二手车交易价格预测”学习赛的Task02-学习日志,旨在了解EDA的分析步骤,通过分析数据,对数据清洗,了解变量间的相互关系以及变量与预测值之间的存在关系,并通过数据处理和特征工程提高预测的可靠性。 学习网址:[添加链接描述](https://github.com/datawhalechina/team-learning-data-mining/blob/master/SecondHandCarPriceForecast/Task2%20%E6%95%B0%E6%8D%AE%E5%88%86%E6%9E%90.md)

一、EDA学习思维导图

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


二、EDA是什么?

EDA定义:探索性数据分析(Exploratory Data Analysis,简称EDA),是一种通过可视化方法概括性分析数据集的主要特征的分析方法,通常使用形式化建模或假设检验的方法,探索性数据分析是上世纪六十年代美国统计学家John Tukey提出。 EDA作用:EDA不同于初始数据分析(IDA),其更集中于检查模型拟合和假设检验所需的假设,以及处理缺少的值,了解变量间的相互关系以及变量与预测值之间的存在关系,并根据需要进行变量转换。

二、EDA分析步骤

1.载入数据库

在这里插入图片描述

1.1代码如下:

import warnings
warnings.filterwarnings('ignore')

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import missingno as msno

1.2导入库常见问题

Q1:如后期需要使用的lightgbm库需要通过pip下载,下载需通过CMD,直接输入pip会报错:在这里插入图片描述
A1:需进入pip.exe所在文件夹路径,复制路径(通常在python/anaconda的Scripts文件夹中),转到该文件夹,再运行pip 安装:在这里插入图片描述
注:下载时间过长会被墙,将安装包下载至本地Scripts文件夹中安装,安装地址:添加链接描述


## 2.读入数据及预览 ![在这里插入图片描述](https://www.icode9.com/i/ll/?i=2021041615562178.jpg#pic_center)

2.1读入数据

代码如下:

path = 'D:/python/ItemofSecondHandCarPriceForecast/Data/data/'
Train_data = pd.read_csv(path+'used_car_train_20200313.csv', sep=' ')
TestA_data = pd.read_csv(path+'used_car_testA_20200313.csv', sep=' ')

注:参数1为数据所在路径


2.2数据预览

数据预览代码如下:

Train_data.head().append(Train_data.tail())

注:简略预览数据前五行和后五行,输出结果如下

SaleID	name	regDate	model	brand	bodyType	fuelType	gearbox	power	kilometer	...	v_5	v_6	v_7	v_8	v_9	v_10	v_11	v_12	v_13	v_14
0	0	736	20040402	30.0	6	1.0	0.0	0.0	60	12.5	...	0.235676	0.101988	0.129549	0.022816	0.097462	-2.881803	2.804097	-2.420821	0.795292	0.914762
1	1	2262	20030301	40.0	1	2.0	0.0	0.0	0	15.0	...	0.264777	0.121004	0.135731	0.026597	0.020582	-4.900482	2.096338	-1.030483	-1.722674	0.245522
2	2	14874	20040403	115.0	15	1.0	0.0	0.0	163	12.5	...	0.251410	0.114912	0.165147	0.062173	0.027075	-4.846749	1.803559	1.565330	-0.832687	-0.229963
3	3	71865	19960908	109.0	10	0.0	0.0	1.0	193	15.0	...	0.274293	0.110300	0.121964	0.033395	0.000000	-4.509599	1.285940	-0.501868	-2.438353	-0.478699
4	4	111080	20120103	110.0	5	1.0	0.0	0.0	68	5.0	...	0.228036	0.073205	0.091880	0.078819	0.121534	-1.896240	0.910783	0.931110	2.834518	1.923482
149995	149995	163978	20000607	121.0	10	4.0	0.0	1.0	163	15.0	...	0.280264	0.000310	0.048441	0.071158	0.019174	1.988114	-2.983973	0.589167	-1.304370	-0.302592
149996	149996	184535	20091102	116.0	11	0.0	0.0	0.0	125	10.0	...	0.253217	0.000777	0.084079	0.099681	0.079371	1.839166	-2.774615	2.553994	0.924196	-0.272160
149997	149997	147587	20101003	60.0	11	1.0	1.0	0.0	90	6.0	...	0.233353	0.000705	0.118872	0.100118	0.097914	2.439812	-1.630677	2.290197	1.891922	0.414931
149998	149998	45907	20060312	34.0	10	3.0	1.0	0.0	156	15.0	...	0.256369	0.000252	0.081479	0.083558	0.081498	2.075380	-2.633719	1.414937	0.431981	-1.659014
149999	149999	177672	19990204	19.0	28	6.0	0.0	1.0	193	12.5	...	0.284475	0.000000	0.040072	0.062543	0.025819	1.978453	-3.179913	0.031724	-1.483350	-0.342674

数据规模代码如下:

Train_data.shape

注:预览数据矩阵规模,结果如下

(50000, 30)

3.总数据概述

在这里插入图片描述

3.1 描述各变量的特征值
代码如下

Train_data.describe()

结果如下

SaleID	name	regDate	model	brand	bodyType	fuelType	gearbox	power	kilometer	...	v_5	v_6	v_7	v_8	v_9	v_10	v_11	v_12	v_13	v_14
count	50000.000000	50000.000000	5.000000e+04	50000.000000	50000.000000	48587.000000	47107.000000	48090.000000	50000.000000	50000.000000	...	50000.000000	50000.000000	50000.000000	50000.000000	50000.000000	50000.000000	50000.000000	50000.000000	50000.000000	50000.000000
mean	174999.500000	68542.223280	2.003393e+07	46.844520	8.056240	1.782185	0.373405	0.224350	119.883620	12.595580	...	0.248669	0.045021	0.122744	0.057997	0.062000	-0.017855	-0.013742	-0.013554	-0.003147	0.001516
std	14433.901067	61052.808133	5.368870e+04	49.469548	7.819477	1.760736	0.546442	0.417158	185.097387	3.908979	...	0.044601	0.051766	0.195972	0.029211	0.035653	3.747985	3.231258	2.515962	1.286597	1.027360
min	150000.000000	0.000000	1.991000e+07	0.000000	0.000000	0.000000	0.000000	0.000000	0.000000	0.500000	...	0.000000	0.000000	0.000000	0.000000	0.000000	-9.160049	-5.411964	-8.916949	-4.123333	-6.112667
25%	162499.750000	11203.500000	1.999091e+07	10.000000	1.000000	0.000000	0.000000	0.000000	75.000000	12.500000	...	0.243762	0.000044	0.062644	0.035084	0.033714	-3.700121	-1.971325	-1.876703	-1.060428	-0.437920
50%	174999.500000	52248.500000	2.003091e+07	29.000000	6.000000	1.000000	0.000000	0.000000	109.000000	15.000000	...	0.257877	0.000815	0.095828	0.057084	0.058764	1.613212	-0.355843	-0.142779	-0.035956	0.138799
75%	187499.250000	118856.500000	2.007110e+07	65.000000	13.000000	3.000000	1.000000	0.000000	150.000000	15.000000	...	0.265328	0.102025	0.125438	0.079077	0.087489	2.832708	1.262914	1.764335	0.941469	0.681163
max	199999.000000	196805.000000	2.015121e+07	246.000000	39.000000	7.000000	6.000000	1.000000	20000.000000	15.000000	...	0.291618	0.153265	1.358813	0.156355	0.214775	12.338872	18.856218	12.950498	5.913273	2.624622

注:describe种有每列的统计量,个数count、平均值mean、标准差std、最小值min、中位数25% 50% 75% 、以及最大值


3.2 了解数据类型及空值情况
代码如下

Train_data.describe()

结果如下

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 150000 entries, 0 to 149999
Data columns (total 31 columns):
SaleID               150000 non-null int64
name                 150000 non-null int64
regDate              150000 non-null int64
model                149999 non-null float64
brand                150000 non-null int64
bodyType             145494 non-null float64
fuelType             141320 non-null float64
gearbox              144019 non-null float64
power                150000 non-null int64
kilometer            150000 non-null float64
notRepairedDamage    150000 non-null object
regionCode           150000 non-null int64
seller               150000 non-null int64
offerType            150000 non-null int64
creatDate            150000 non-null int64
price                150000 non-null int64
v_0                  150000 non-null float64
v_1                  150000 non-null float64
v_2                  150000 non-null float64
v_3                  150000 non-null float64
v_4                  150000 non-null float64
v_5                  150000 non-null float64
v_6                  150000 non-null float64
v_7                  150000 non-null float64
v_8                  150000 non-null float64
v_9                  150000 non-null float64
v_10                 150000 non-null float64
v_11                 150000 non-null float64
v_12                 150000 non-null float64
v_13                 150000 non-null float64
v_14                 150000 non-null float64
dtypes: float64(20), int64(10), object(1)
memory usage: 35.5+ MB

注:info()用以了解数据type及nan情况


4.判断和处理数据缺失和异常

在这里插入图片描述
4.1 异常值检测常用方法

(1)简单统计:利用pandas.describe()+散点图发现异常值;
(2)3σ原则:此方法数据分布需要服从正态分布或者近似正态分布,正态分布99.730020%的数据在[u-3σ,u-3σ]内,如果在3σ之外根据小概率原理可判定为异常值;
(3)箱线图法:离四分位数构成箱子较远的值
(4)基于模型检测:需构建概率分布模型,根据分布将低概率判定为异常点
(5)基于近邻度的离群点检测:确定数据集的有意义的邻近性来度量异常值
(6)基于密度的异常检测
(7)基于聚类的异常检测
(8)专门的离群点检测
(9) 孤立森林(可列为学习重点)
(10)Robust Random Cut Forest
以上方法根据可大侠的“数据分析–异常值处理”总结链接如下:添加链接描述


4.2 常见异常值及对应检测方法

4.2.1存在nan的情况

4.2.1.1列表直观了解:简要了解“nan”是否过多

代码如下

Train_data.isnull().sum()

结果如下

SaleID                  0
name                    0
regDate                 0
model                   1
brand                   0
bodyType             4506
fuelType             8680
gearbox              5981
power                   0
kilometer               0
notRepairedDamage       0
regionCode              0
seller                  0
offerType               0
creatDate               0
price                   0
v_0                     0
v_1                     0
v_2                     0
v_3                     0
v_4                     0
v_5                     0
v_6                     0
v_7                     0
v_8                     0
v_9                     0
v_10                    0
v_11                    0
v_12                    0
v_13                    0
v_14                    0
dtype: int64

将上述列表可视化代码如下

missing = Train_data.isnull().sum()
missing = missing[missing > 0]
missing.sort_values(inplace=True)
missing.plot.bar()
plt.show()

结果如下

在这里插入图片描述

注:也可以根据info函数结果查看


4.2.1.2缺省值(nan)可视化:missingno模块
通常通过missingno模块实现nan值可视化,常用函数如下,本次主要学习matrix和bar。

- msno.matrix
- msno.bar
- msno.heatmap
- msno.dendrogram

msno.matrix代码如下

msno.matrix(Train_data.sample(250))
plt.show()

msno.matrix结果如下
在这里插入图片描述
msno.bar代码如下

msno.bar(Train_data.sample(1000))
plt.show()

msno.bar结果如下
在这里插入图片描述


4.2.2存在空缺值的情况“-”
根据info结果得知只有’notRepairedDamage’的数据类型为object,其可能存在空缺值,需要读取’notRepairedDamage’的取值。

'notRepairedDamage’取值代码如下

Train_data['notRepairedDamage'].value_counts()

结果如下

0.0    111361
-       24324
1.0     14315
Name: notRepairedDamage, dtype: int64

‘ - ’也为空缺值,对于空值可直接处理,但本次baseline将其替换为nan

替换代码如下

Train_data['notRepairedDamage'].replace('-', np.nan, inplace=True)
Train_data['notRepairedDamage'].value_counts()

结果如下:

0.0    111361
1.0     14315
Name: notRepairedDamage, dtype: int64

注:
1.replace用法
第一个参数是这是要进行更换的旧子串,第二个参数是这是新的子串,将取代旧的子字符串,第三个参数是替换多少次,默认是全部X.repalce(old,new,max);
2.inplace参数的理解:
修改一个对象:
inplace=True:不创建新的对象,直接对原始对象进行修改;
inplace=False:对数据进行修改,创建并返回新的对象承载其修改结果。


4.2.2 存在严重倾斜数据情况
有的特征数据会有严重倾斜,一般不会对预测有什么帮助,故先删除。

倾斜数据取值代码如下

Train_data["seller"].value_counts()

结果如下

0    149999
1         1
Name: seller, dtype: int64

Train_data[“offerType”].value_counts()

Train_data["seller"].value_counts()

5.了解预测值的总体分布

在这里插入图片描述
5.1 绘图了解大概分布

分布绘图代码如下

TRP=Train_data['price']
TRP_co=Train_data['price'].value_counts()
print(TRP)
print(TRP_co)

## 总体分布概况(无界约翰逊分布等)
import scipy.stats as st
y = Train_data['price']
plt.figure(1); plt.title('Johnson SU') #绘制画布
sns.distplot(y, kde=False, fit=st.johnsonsu)#根据数据于画布上作图
plt.figure(2); plt.title('Normal')
sns.distplot(y, kde=False, fit=st.norm)
plt.figure(3); plt.title('Log Normal')
sns.distplot(y, kde=False, fit=st.lognorm)
plt.show()

结果如下
在这里插入图片描述

结果分析:由上图可知价格不服从正态分布,所以在进行回归之前,它必须进行转换。虽然对数变换做得很好,但最佳拟合是无界约翰逊分布。(约翰逊设计的分布体系包括由变换产生三族分布,根据分布体系可将非正态数据变化为正态数据统计方法中常要求观察值服从正太分布,质量特征分布如果与正态分布产生偏离,对控制两类错误等会产生严重影响,当样本数据表明特征服从N,可将非正态转化为正态,而运用约翰逊体系能确定所需变换函数。)

注-上述函数知识补充:
1.figure(num=None, figsize=None, dpi=None, facecolor=None, edgecolor=None, frameon=True)

- num:图像编号或名称,数字为编号 ,字符串为名称 ;
- figsize:指定figure的宽和高,单位为英寸;
- dpi参数指定绘图对象的分辨率,即每英寸多少个像素,缺省值为80 1英寸等于2.5cm,A4纸是 21*30cm的纸张;
facecolor:背景颜色 edgecolor:边框颜色 frameon:是否显示边框

2.seaborn的displot()集合了matplotlib的hist()与核函数估计kdeplot的功能,
增加了rugplot分布观测条显示与利用scipy库fit拟合参数分布的新颖用途,具体用法如下:

seaborn.distplot(a, bins=None, hist=True, kde=True, rug=False, fit=None, hist_kws=None, kde_kws=None, rug_kws=None, fit_kws=None, color=None, vertical=False, norm_hist=False, axlabel=None, label=None, ax=None)

- 参数:
- a:绘图数据(Series, 1d-array, or list)
- bins:设置矩形图数量
- hist: 控制是否显示条形图
- kde:控制是否显示核密度估计图
- rug: 控制是否显示观测的小细条(边际毛毯)
- fit: 控制拟合的参数分布图形
- vertical: 显示正交控制

学习链接添加链接描述


5.2 偏度和峰度

单个特征偏度和风度获取代码如下:

sns.distplot(Train_data['price']);
print("Skewness: %f" % Train_data['price'].skew())
print("Kurtosis: %f" % Train_data['price'].kurt())

结果如下:

Skewness: 3.346487
Kurtosis: 18.995183

结果分析:函数分布图为右偏尖峰图,结果与图形一致。
在这里插入图片描述

注-知识补充:

- 偏度定义中包括正态分布(偏度=0),右偏分布(也叫正偏分布,其偏度>0),左偏分布(也叫负偏分布,其偏度<0)。

- 峰度(peakedness;kurtosis)又称峰态系数。表征概率密度分布曲线在平均值处峰值高低的特征数。直观看来,峰度反映了峰部的尖度。随机变量的峰度计算方法为:随机变量的四阶中心矩与方差平方的比值。峰度包括正态分布(峰度值=3),厚尾(峰度值>3),瘦尾(峰度值<3)。注意,个别的软件会将峰度值减3,ArcGIS默认正态分布的峰度为3,MS Excel的计算公式与上面略有不同。


偏度和风度可视化代码如下:

Train_data.skew(), Train_data.kurt()
sns.distplot(Train_data.skew(),color='blue',axlabel ='Skewness')

结果如下:
在这里插入图片描述


5.3 查看预测具体频数

查看预测值的具体频数代码如下:

plt.hist(Train_data['price'], orientation = 'vertical',histtype = 'bar', color ='red')
plt.show()

结果如下:
在这里插入图片描述
结果分析:由上图可知图形右偏严重,可将大于20000得值作特殊得值(异常值)直接用填充或者删掉,上述进行log变换之后的分布较均匀,也可以进行log变换进行预测。


6.了解各变量(即不同类别)数据分布及分析

在这里插入图片描述-通过对数据分析,本次数据主要包括数字特征和类型特征,因此先进行label的分离再依次对不同的数据进行分析。


6.1 分离label即预测值

查看不同类型所包含的变量代码如下:

Y_train = Train_data['price']
numeric_features = Train_data.select_dtypes(include=[np.number])
numeric_features.columns
categorical_features = Train_data.select_dtypes(include=[np.object])
categorical_features.columns
numeric_features = ['power', 'kilometer', 'v_0', 'v_1', 'v_2', 'v_3', 'v_4', 'v_5', 'v_6', 'v_7', 'v_8', 'v_9', 'v_10', 'v_11', 'v_12', 'v_13','v_14' ]

categorical_features = ['name', 'model', 'brand', 'bodyType', 'fuelType', 'gearbox', 'notRepairedDamage', 'regionCode',]

6.2 数字特征分析

6.2.1相关性分析
相关性分析代码如下:

numeric_features.append('price')
price_numeric = Train_data[numeric_features]
correlation = price_numeric.corr()
print(correlation['price'].sort_values(ascending = False),'\n')

结果如下:

price        1.000000
v_12         0.692823
v_8          0.685798
v_0          0.628397
power        0.219834
v_5          0.164317
v_2          0.085322
v_6          0.068970
v_1          0.060914
v_14         0.035911
v_13        -0.013993
v_7         -0.053024
v_4         -0.147085
v_9         -0.206205
v_10        -0.246175
v_11        -0.275320
kilometer   -0.440519
v_3         -0.730946
Name: price, dtype: float64 

相关性分析可视化代码如下:

f , ax = plt.subplots(figsize = (7, 7))

plt.title('Correlation of Numeric Features with Price',y=1,size=16)

sns.heatmap(correlation,square = True,  vmax=0.8)

结果如下:

在这里插入图片描述
注:
sort_values()用法:

.sort_values(by=‘##’,axis=0,ascending=True,inplace=False, na_position=‘last’)

-by: 指定列名(axis=0或’index’)或索引值(axis=1或’columns’)
-axis:若axis=0或’index’,则按照指定列中数据大小排序;若axis=1或’columns’,
则按照指定索引中数据大小排序,默认axis=0
-ascending:是否按指定列的数组升序排列,默认为True,即升序排列
-inplace:是否用排序后的数据集替换原来的数据,默认为False,即不替换
-na_position:{‘first’,‘last’},设定缺失值的显示位置


6.2.2 特征值偏度和峰值及可视化

偏度和峰值获取代码如下:

for col in numeric_features:
    print('{:15}'.format(col), 
          'Skewness: {:05.2f}'.format(Train_data[col].skew()) , 
          '   ' ,
          'Kurtosis: {:06.2f}'.format(Train_data[col].kurt())  
         )
plt.show()
         #{:15}——位置映射,相当于{0:15},对应于format中的'',15为字符宽度

结果如下:

power           Skewness: 65.86     Kurtosis: 5733.45
kilometer       Skewness: -1.53     Kurtosis: 001.14
v_0             Skewness: -1.32     Kurtosis: 003.99
v_1             Skewness: 00.36     Kurtosis: -01.75
v_2             Skewness: 04.84     Kurtosis: 023.86
v_3             Skewness: 00.11     Kurtosis: -00.42
v_4             Skewness: 00.37     Kurtosis: -00.20
v_5             Skewness: -4.74     Kurtosis: 022.93
v_6             Skewness: 00.37     Kurtosis: -01.74
v_7             Skewness: 05.13     Kurtosis: 025.85
v_8             Skewness: 00.20     Kurtosis: -00.64
v_9             Skewness: 00.42     Kurtosis: -00.32
v_10            Skewness: 00.03     Kurtosis: -00.58
v_11            Skewness: 03.03     Kurtosis: 012.57
v_12            Skewness: 00.37     Kurtosis: 000.27
v_13            Skewness: 00.27     Kurtosis: -00.44
v_14            Skewness: -1.19     Kurtosis: 002.39
price           Skewness: 03.35     Kurtosis: 019.00

偏度峰度可视化代码如下:
f = pd.melt(Train_data, value_vars=numeric_features)
g = sns.FacetGrid(f, col="variable",  col_wrap=2, sharex=False, sharey=False)
g = g.map(sns.distplot, "value")
plt.show()

结果如下:
在这里插入图片描述
结果分析:由上图可以看出致使price呈现右偏和尖峰的主要原因可能是power。

数字特征相互之间的关系可视化如下:

sns.set()
columns = ['price', 'v_12', 'v_8' , 'v_0', 'power', 'v_5',  'v_2', 'v_6', 'v_1', 'v_14']
sns.pairplot(Train_data[columns],size = 2 ,kind ='scatter',diag_kind='kde')
plt.show()

结果如下:
在这里插入图片描述


6.2.3 多变量之间的关系可视化


6.3 类型特征分析

6.3.1 unique分布
特征nunique分布代码如下:

for cat_fea in categorical_features:
    print(cat_fea + "的特征分布如下:")
    print("{}特征有个{}不同的值".format(cat_fea, Train_data[cat_fea].nunique()))
    print(Train_data[cat_fea].value_counts())

部分结果如下:

name的特征分布如下:
name特征有个99662不同的值
708       282
387       282
55        280
1541      263
203       233
         ... 
5074        1
7123        1
11221       1
13270       1
174485      1
Name: name, Length: 99662, dtype: int64

注:也可根据此表画出可视化分布图并判断特殊值


6.3.2 类别特征可视化

6.3.2.1 箱形图可视化
代码如下:

for cat_fea in categorical_features:
    print(cat_fea + "的特征分布如下:")
    print("{}特征有个{}不同的值".format(cat_fea, Train_data[cat_fea].nunique()))
    print(Train_data[cat_fea].value_counts())

部分结果如下:
在这里插入图片描述


6.3.2.2 小提琴图可视化
小提琴图 (Violin Plot)是用来展示多组数据的分布状态以及概率密度。这种图表结合了箱形图和密度图的特征,主要用来显示数据的分布形状。其和箱形图类似,但箱形图的所有绘图组件都对应于实际数据点,而小提琴形图具有底层分布的核密度估计。在数据量非常大不方便一个一个展示的时候小提琴图特别适用。

代码如下:

catg_list = categorical_features
target = 'price'
for catg in catg_list :
    sns.violinplot(x=catg, y=target, data=Train_data)
    plt.show()

部分结果如下:

在这里插入图片描述


6.3.2.2 柱形图可视化
代码如下:

def bar_plot(x, y, **kwargs):
    sns.barplot(x=x, y=y)
    x=plt.xticks(rotation=90)

f = pd.melt(Train_data, id_vars=['price'], value_vars=categorical_features)
g = sns.FacetGrid(f, col="variable",  col_wrap=2, sharex=False, sharey=False, size=5)
g = g.map(bar_plot, "value", "price")

部分结果如下:

在这里插入图片描述


6.3.2.2 每个类别频数可视化(count_plot)

特征nunique分布代码如下:

def count_plot(x,  **kwargs):
    sns.countplot(x=x)
    x=plt.xticks(rotation=90)

f = pd.melt(Train_data,  value_vars=categorical_features)
g = sns.FacetGrid(f, col="variable",  col_wrap=2, sharex=False, sharey=False, size=5)
g = g.map(count_plot, "value")
plt.show()

7.总数据概述

代码如下:

import pandas_profiling
pfr = pandas_profiling.ProfileReport(Train_data)
pfr.to_file("./example.html")

部分结果如下:

HBox(children=(FloatProgress(value=0.0, description='variables', max=29.0, style=ProgressStyle(description_wid…

标签:150000,non,null,如下,学习,Train,数据挖掘,Task02,data
来源: https://blog.csdn.net/SummerT1996/article/details/115748503