二手车价格预测_01_EDA

  1. 大致思路
  2. 分析工具
  3. 一些会经常用到的代码片段
    1. 基操
    2. 导入数据
    3. 总览数据
    4. 寻找缺省值
    5. 预测值的分布
    6. 分离两种特征
    7. 数字特征
    8. 类别特征

EDA (Exploratory Data Analysis)是机器学习中拿到数据时第一步要做的,好的数据分析为我们之后进一步处理数据和特征工程打下良好的基础。因为绝大多数人并不拥有能深入理解数据内涵的专业背景,所以必须经过数据分析的完整流程来对数据有初步的探索。

大致思路

这里翻译下Medium上这篇博客(Medium访问限制的可以试试这个保存的页面)中提到的EDA思路,可以当作每次分析时自己问自己还有哪些工作可以做:

  • 数据集的特点:
    数据集有多大?(自己的设备能否带的动)有哪些数据类型?有哪些feature?label是什么形式的?
  • 数据集的统计数据:
    每个变量的大致范围?均值/中位数/四分位点分别在哪?
  • 错误、缺省数据和离群点
    通过统计和可视化的方式找出这些数据点,以备之后进一步处理
  • feature和label的分布
    对于数字型的feature,它是什么分布?对于类别型的feature,如果它的label也是数字形式的话,又是什么分布?
  • 类别型feature的频率
    每种label出现的大致频率
  • feature间的关系
    有/无相关性?强/弱相关性?

分析工具

分析工具上主要是Python的pandas、matplotlib、seaborn包,有时还要用到scikit-learn包中的一些统计工具。
也有一些提高效率的GUI式工具,比如我逛github发现的banboolib,可惜收费
作为一个初学的菜鸟,我基本都是在jupyterlab里面运行代码,可以打开多个页面一面写代码看结果,一面copy参考公开的kernel

一些会经常用到的代码片段

基操

1
2
3
4
#coding:utf-8
import warnings
warnings.filterwarnings('ignore')
%matplotlib inline
1
2
3
# 让jupyter一个cell里有多个输出指令时可以多行输出
from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity = "all"
1
2
3
4
5
%%javascript
# 设置输出>9999时才出现滑动窗口
//IPython.OutputArea.auto_scroll_threshold = 9999;
# 设置不出现滑动窗口 true, auto, false
IPython.OutputArea.prototype._should_scroll = function(){return false}
1
2
3
4
5
# 导入常用的库
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns

导入数据

1
2
3
4
5
#coding:utf-8
path = '你的文件地址'
# 本地可以直接cd到目录里再启动jupyter
Train_data = pd.read_csv(path+'训练集.csv', sep=' ')
Test_data = pd.read_csv(path+'测试集.csv', sep=' ')

总览数据

1
2
3
4
5
6
7
# 数据的头尾
# 数据大小
Train_data.head()
//Train_data.head().append(Train_data.tail())
Train_data.shape
Test_data.head()
Test_data.shape
1
2
3
4
5
6
# 返回包括均值/标准差/最大/最小值/中位数/四分位点等一堆统计量
Train_data.describe()
Test_data.describe()
# 返回各个变量的数据类型
Train_data.describe()
Test_data.describe()

寻找缺省值

1
2
Train_data.isnull().sum()
Test_data.isnull().sum()
1
2
3
4
5
6
# 画图找_1
# 显示有nan的变量并排序
missing = Train_data.isnull().sum()
missing = missing[missing > 0]
missing.sort_values(inplace=True)
missing.plot.bar()
1
2
3
4
5
6
# 画图找_2
import missingno as msno
# 画个矩阵
msno.matrix(Train_data.sample(250))
# 画个条形图
msno.bar(Train_data.sample(1000))
1
2
3
4
5
6
# 注意object对象空缺值可能没被发现
Train_data['怀疑对象'].value_counts()
Test_data['怀疑对象'].replace('-', np.nan, inplace=True)
# 问题太大的/严重倾斜的可以直接删了
del Train_data["删了这个"]
del Test_data["删了这个"]

预测值的分布

这个还不懂,后面数据处理特征工程部分再研究

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 直接看
Train_data['price'].value_counts()
# 拟合分布
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.hist(Train_data['price'], orientation = 'vertical',histtype = 'bar', color ='red')
plt.show()

分离两种特征

1
2
numeric_features = []
categorical_features = []

数字特征

1
2
3
4
5
6
# 与预测变量相关性分析
numeric_features.append('price')
price_numeric = Train_data[numeric_features]
correlation = price_numeric.corr()
print(correlation['price'].sort_values(ascending = False),'\n')
del price_numeric['price']
1
2
3
4
5
6
# 与预测变量回归分析
fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6), (ax7, ax8), (ax9, ax10)) = plt.subplots(nrows=5, ncols=2, figsize=(24, 20))
# ['v_12', 'v_8' , 'v_0', 'power', 'v_5', 'v_2', 'v_6', 'v_1', 'v_14']
v_12_scatter_plot = pd.concat([Y_train,Train_data['v_12']],axis = 1)
sns.regplot(x='v_12',y = 'price', data = v_12_scatter_plot,scatter= True, fit_reg=True, ax=ax1)
# 后面省略
1
2
3
4
5
6
7
# 数字特征偏度峰度
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())
)
1
2
3
4
# 每个特征的分布
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")
1
2
3
4
5
# 数字特征相互之间的关系可视化
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()

类别特征

1
2
3
4
5
# 特征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())

小提琴图比箱线图多了由宽度表示的频率

1
2
3
4
5
6
7
# 类别特征相对于预测量
# 小提琴图可视化
catg_list = categorical_features
target = 'price'
for catg in catg_list :
sns.violinplot(x=catg, y=target, data=Train_data)
plt.show()
1
2
3
4
5
6
7
8
# 类别特征的每个类别频数可视化(count_plot)
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")

转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 carlos@sjtu.edu.cn

目录
×

恰饭