数据探索在机器学习中一般被称为EDA(Exploratory Data Analysis),
对已有的数据,特别是调查或观察得来的原始数据,在尽量少的先验假定下进行探索,
通过作图、制表、方程拟合、计算特征量等手段探索数据的结构和规律的一种数据分析方法。
missingno是“缺失值可视化处理”库,方便我们直接观察缺失值。
seaborn是一个可以理解成为更为简便的matplotlib的库
## 导入相关库
## 基础工具
import numpy as np
import pandas as pd
import warnings
import matplotlib
import matplotlib.pyplot as plt
import seaborn as sns
import missingno as msno
from scipy.special import jn
from IPython.display import display, clear_output
import time
warnings.filterwarnings('ignore')
%matplotlib inline
#模型预测的
from sklearn import linear_model
from sklearn import preprocessing
from sklearn.svm import SVR
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
import lightgbm as lgb
import xgboost as xgb
#数据降维处理
from sklearn.decomposition import PCA, FastICA, FactorAnalysis, SparsePCA
#参数搜索和评价的
from sklearn.model_selection import GridSearchCV, cross_val_score, StratifiedKFold, train_test_split
from sklearn.metrics import mean_squared_error, mean_absolute_error
#通过Pandas对数据进行读取
Train_data=pd.read_csv('used_car_train_20200313.csv', sep=' ')
TestA_data=pd.read_csv('used_car_testA_20200313.csv', sep=' ')
主要查看数据的列名,以及每列的含义。此处使用head() 和 tail() 函数
训练数据
训练数据集共有共150000个样本, 30列特征(31列是30列特征+1列标签价格)。
31个数据列的属性依次为:
使用info()函数查看数据类型
数据类型为float64 的有20个, 数据类型为 int64的有9个, 剩下1个object类(notRepairedDamage特征)
查看数据分布使用describe()函数,关于数值列的统计量(对于非数值的列就无法统计了),个数count、平均值mean、方差std、最小值min、中位数25% 50% 75% 、以及最大值
看这个信息主要是瞬间掌握数据的大概的范围以及每个值的异常值的判断,比如有的时候会发现
9999999, -1 等值这些其实都是nan的另外一种表达方式,需要注意。
训练数据
注意到有且仅有notRepairedDamage特征的类型是object,因此上面describe得到的数据统计特征里没有统计这个,所以最后describe得到的形状是8x30而不是8x31。
共有四个特征存在缺失值。如果nan的数量存在的很小一般选择填充,如果使用lgb等树模型可以直接空缺,让树自己去优化,但如果nan存在的过多、可以考虑删掉。
非数值类型的特征数据需要额外考虑,因为 如果非数值类型的数据值为其它符号比如 ‘-’ ,有有些空值会用 ‘-’ 表示,X.isnull().sum()函数却视为非空值。
‘-’ 即为缺失值,替换成nan
在之前的统计中,notRepairedDamage特征是没有统计到有空缺值的,在替换为nan值以后再统计:
可见notRepairedDamage特征的缺失值变为了最多!
使用value_counts() 查看数值类型的特征,是否存在严重倾斜的特征,一般不会对预测有什么帮助,可以先删掉
删除
## 1) 总体分布概况(无界约翰逊分布等)
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)
可以看到价格不服从正态分布,因此在进行回归之前,它必须进行转换。最佳拟合是约翰逊分布。
查看频数, 大于20000得值极少,其实这里也可以把这些当作特殊得值(异常值)直接用填充或者删掉
把特征分为数字特征和类别特征
Y_train = Train_data['price']
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',]
利用nunique统计各特征中不同的值的数量
## 3) 每个数字特征得分布可视化
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")
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()
#多变量互相回归关系可视化
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)
v_8_scatter_plot = pd.concat([Y_train,Train_data['v_8']],axis = 1)
sns.regplot(x='v_8',y = 'price',data = v_8_scatter_plot,scatter= True, fit_reg=True, ax=ax2)
v_0_scatter_plot = pd.concat([Y_train,Train_data['v_0']],axis = 1)
sns.regplot(x='v_0',y = 'price',data = v_0_scatter_plot,scatter= True, fit_reg=True, ax=ax3)
power_scatter_plot = pd.concat([Y_train,Train_data['power']],axis = 1)
sns.regplot(x='power',y = 'price',data = power_scatter_plot,scatter= True, fit_reg=True, ax=ax4)
v_5_scatter_plot = pd.concat([Y_train,Train_data['v_5']],axis = 1)
sns.regplot(x='v_5',y = 'price',data = v_5_scatter_plot,scatter= True, fit_reg=True, ax=ax5)
v_2_scatter_plot = pd.concat([Y_train,Train_data['v_2']],axis = 1)
sns.regplot(x='v_2',y = 'price',data = v_2_scatter_plot,scatter= True, fit_reg=True, ax=ax6)
v_6_scatter_plot = pd.concat([Y_train,Train_data['v_6']],axis = 1)
sns.regplot(x='v_6',y = 'price',data = v_6_scatter_plot,scatter= True, fit_reg=True, ax=ax7)
v_1_scatter_plot = pd.concat([Y_train,Train_data['v_1']],axis = 1)
sns.regplot(x='v_1',y = 'price',data = v_1_scatter_plot,scatter= True, fit_reg=True, ax=ax8)
v_14_scatter_plot = pd.concat([Y_train,Train_data['v_14']],axis = 1)
sns.regplot(x='v_14',y = 'price',data = v_14_scatter_plot,scatter= True, fit_reg=True, ax=ax9)
v_13_scatter_plot = pd.concat([Y_train,Train_data['v_13']],axis = 1)
sns.regplot(x='v_13',y = 'price',data = v_13_scatter_plot,scatter= True, fit_reg=True, ax=ax10)
用pandas_profiling生成一个较为全面的可视化和数据报告,最终打开html文件