赞
踩
数据集网址:https://tianchi.aliyun.com/competition/entrance/231784/information
参考了:Datawhale 零基础入门数据挖掘,更多详情在https://tianchi.aliyun.com/notebook/95457
import warnings # #导入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
train_data=pd.read_csv(train_path,sep=' ')
test_data=pd.read_csv(test_path,sep=' ') # 列与列之间是通过空格分隔的
查看数据形状:
train_data.shape
查看数据前几行和后几行,对数据大致有一个了解
train_data.head()
train_data.tail()
查看每一列的个数count、平均值mean、方差std、最小值min、中位数25% 50% 75% 、以及最大值。看这个信息主要是瞬间掌握数据的大概的范围以及每个值的异常值的判断
train_data.describe()
train_data.info()
返回了列名,每一列非空值数量以及列的类型
train_data.isnull().sum()
missing = Train_data.isnull().sum() #统计缺失值
missing = missing[missing > 0] # 找到有缺失值的列
missing.sort_values(inplace=True) # 按照缺失值数量排序
missing.plot.bar() # 柱状图显示
排序后的结果:
可视化:
分析: 通过以上两句可以很直观的了解哪些列存在 “nan”, 并可以把nan的个数打印,主要的目的在于 nan存在的个数是否真的很大,如果很小一般选择填充,如果使用lgb等树模型可以直接空缺,让树自己去优化,但如果nan存在的过多、可以考虑删掉
矩阵图展示:空白越多说明缺失越严重
msno.matrix(train_data)
柱状图展示:
msno.bar(train_data)
train_data.info() # 查看结果发现发现除了notRepairedDamage 为object类型其他都为数字,猜测notRepairedDamage这一列中有异常值
train_data['notRepairedDamage'].value_counts() # 统计notRepairedDamage这一列的值及其对应的数量
notRepairedDamage的含义是汽车是否有损坏,-也是缺失值,鉴于很多模型对nan都有处理,这里先不做处理,转换成nan
train_data['notRepairedDamage'].replace('-',np.nan,inplace=True) # inplace=True表示在原始数据上直接操作
可以看到seller列值这两个类别特征严重倾斜,一般不会对预测有什么帮助,故可以先删掉,当然你也可以继续挖掘,但是一般意义不大
train_data['seller'].value_counts()
还有offerType列,所有值都一样,故也不会对结果产生什么影响,可以删去
train_data['offerType'].value_counts()
删除列:
del train_data['seller']
del train_data['offerType']
train_data['price'].value_counts()
分别用无界约翰逊分布,正态分布、对数正态分布来拟合我们的数据
无界约翰逊分布拟合:
# Scipy是一个用于科学计算的Python库,它提供了许多用于数值计算、优化、插值、统计和信号处理的功能
import scipy.stats as st
plt.figure(1) # 创建一个新的图形窗口
plt.title('Johnson SU') # 设置图形的标题为 'Johnson SU'
# 函数绘制概率密度分布图
sns.distplot(y, kde=False, fit=st.johnsonsu)
# y: 这是要绘制分布的数据。
# kde=False: 禁用核密度估计曲线,只绘制直方图。
# fit=st.johnsonsu: 在这里,st.johnsonsu 表示使用 Johnson SU 分布进行拟合,下图中的曲线就是Johnson SU 分布拟合的
补充:无界约翰逊分布(Unbounded Johnson Distribution)是一种统计概率分布,它是有界约翰逊分布的一种扩展,用于建模不受限制的随机变量。这种分布的特点是能够适应多种分布形状,包括对称、右偏和左偏的形状。约翰逊分布是通过对原始随机变量进行适当的变换,使其服从正态分布。无界约翰逊分布是指这种变换没有对随机变量的范围(上下界)进行限制,因此是“无界”的
正态分布拟合:
plt.figure(1)
plt.title('Normal')
sns.distplot(y, kde=False, fit=st.norm)
可以看出正态分布拟合的效果不怎么好
对数正态分布拟合:
plt.figure(1)
plt.title('Normal')
sns.distplot(y, kde=False, fit=st.lognorm)
效果也还行
分析:价格不服从正态分布,所以在进行回归之前,它必须进行转换。虽然对数变换做得很好,但最佳拟合是无界约翰逊分布
plt.hist(train_data['price'], orientation = 'vertical',histtype = 'bar', color ='orange')
plt.show()
# orientation='vertical': 这个参数指定了直方图的方向。在这里,设置为 'vertical' 表示垂直方向的直方图。
# histtype='bar': 这个参数指定了直方图的类型。在这里,设置为 'bar' 表示使用条形(bar)来表示直方图。
# color ='orange': 这个参数指定了直方图的颜色。在这里,设置为 'red' 表示直方图的颜色为红色。
# plt.show(): 这个函数用于显示图形。在 Matplotlib 中,你需要调用 plt.show() 才能实际显示图形。
plt.hist(np.log(train_data['price']), orientation = 'vertical',histtype = 'bar', color ='orange')
plt.show()
■ 偏度(skewness),是描述数据分布形态的统计量,其描述的是某总体取值分布的对称性,简单来说就是数据的不对称程度,正态分布的偏度为0
■ 峰度又称峰态系数。偏度是描述某变量所有取值分布形态陡缓程度的统计量,简单来说就是数据分布顶的尖锐程度。峰度为0表示该总体数据分布与正态分布的陡缓程度相同;峰度 >0表示该总体数据分布与正态分布相比较为陡峭,为尖顶峰
train_data.skew()
train_data.kurt()
偏度可视化:
sns.distplot(train_data.skew(),color='blue',axlabel="skewness")
峰度可视化:
sns.distplot(train_data.kurt(),color='green',axlabel="kurtosis")
特征分为类别特征和数字特征,一般分开进行分析
这里需要根据实际意义人为来区分:
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()可以计算每个列的类别数量
for cat in categorical_features:
print("{}的特征分布如下:".format(cat))
print("{}特征一共有{}个值,每个值的数量如下:".format(cat,train_data[cat].nunique()))
print(train_data[cat].value_counts())
■ 箱型图:箱形图(也称盒图,箱线图等),因为形状长得像一个箱子而得名。它是用于显示一组数据分散情况的统计图,可以通过这种图直观的探索数据特征。
■ 箱线图判断异常值的标准以四分位数和四分位距为基础,四分位数具有一定的耐抗性,多达25%的数据可以变得任意远而不会很大地扰动四分位数,所以异常值不会影响箱形图的数据形状。箱线图识别异常值的结果比较客观,能够准确稳定地描绘出数据的离散分布情况,同时也利于数据的清洗。
■ 补充:
①箱线图是针对连续型变量的,解读时候重点关注平均水平、波动程度和异常值。
②当箱子被压得很扁,或者有很多异常的时候,试着做对数变换。
③当只有一个连续型变量时,并不适合画箱线图,直方图是更常见的选择。
④箱线图最有效的使用途径是作比较,配合一个或者多个定性数据,画分组箱线图
# 因为 name和 regionCode的类别太稀疏了,这里我们把不稀疏的几类画一下 categorical_features = ['model', 'brand', 'bodyType', 'fuelType', 'gearbox', 'notRepairedDamage'] for c in categorical_features: # 将每个分类特征的数据类型转换为 Pandas 中的 'category' 类型 train_data[c] = train_data[c].astype('category') if train_data[c].isnull().any(): # 如果包含缺失值,则新增一个类别'MISSING'作为缺失值 train_data[c] = train_data[c].cat.add_categories(['MISSING']) # 用'MISSING'填充缺失值 train_data[c] = train_data[c].fillna('MISSING') # 自定义的箱线图绘制函数 def boxplot(x, y, **kwargs): sns.boxplot(x=x, y=y) x=plt.xticks(rotation=90) # 将 x 轴标签旋转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) g = g.map(boxplot, "value", "price")
还可以使用小提琴图、柱状图等多种图表来可视化,这里不再一一赘述。
numeric_features.append('price')
numeric_data=train_data[numeric_features] # 带标签的数字特征数据集
correlation=numeric_data.corr() # 计算各列之间的相关性
print(correlation['price'].sort_values(ascending=False),'\n') # 打印预测值price与各个特征之间的相关性,并降序排序
plt.title('Correlation of Numeric Features with Price')
sns.heatmap(correlation,square = True)
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']
# pairplot 函数,用于绘制一组变量之间的散点图矩阵
# size=2: 指定每个子图的大小为2。
# kind='scatter': 指定绘制散点图。
# diag_kind='kde': 对角线上的图形使用核密度图(Kernel Density Estimate)来表示单变量分布
sns.pairplot(Train_data[columns],size = 2 ,kind ='scatter',diag_kind='kde')
plt.show()
# 创建了一个包含多个子图的图形,按照5行2列的网格排列,figsize 参数指定了整个图形的大小
fig, ((ax1, ax2), (ax3, ax4), (ax5, ax6), (ax7, ax8), (ax9, ax10)) = plt.subplots(nrows=5, ncols=2, figsize=(24, 20))
# 这一行创建了一个新的数据框 v_12_scatter_plot,其中包含目标变量 'price' 和特征 'v_12'。pd.concat 函数用于在水平方向上连接两个数据框
v_12_scatter_plot = pd.concat([y_train,train_data['v_12']],axis = 1)
# 在第一个子图 ax1 上绘制了 'v_12' 与 'price' 的散点图和线性回归拟合线
sns.regplot(x='v_12',y = 'price', data = v_12_scatter_plot,scatter= True, fit_reg=True, ax=ax1)
# x='v_12', y='price': 指定 x 轴和 y 轴的变量。
# data=v_12_scatter_plot: 指定绘图数据。
# scatter=True: 表示显示散点图。
# fit_reg=True: 表示显示线性回归拟合线。
# ax=ax1: 指定要在哪个子图上进行绘制,这里是第一个子图 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)
这里仅展示两个:
import pandas as pd
from ydata_profiling import ProfileReport
train_path="..."
train_data=pd.read_csv(train_path,sep=' ')
pfr = ProfileReport(train_data)
pfr.to_file("./example.html")
数据探索有利于我们发现数据的一些特性,数据之间的关联性,对于后续的特征构建是很有帮助的。
对于数据的初步分析(直接查看数据,或.sum(), .mean(),.descirbe()等统计函数)可以从:样本数量,训练集数量,是否有时间特征,是否是时许问题,特征所表示的含义(非匿名特征),特征类型(字符类似,int,float,time),特征的缺失情况(注意缺失的在数据中的表现形式,有些是空的有些是”NAN”符号等),特征的均值方差情况。
分析记录某些特征值缺失占比30%以上样本的缺失处理,有助于后续的模型验证和调节,分析特征应该是填充(填充方式是什么,均值填充,0填充,众数填充等),还是舍去,还是先做样本分类用不同的特征模型去预测。
对于异常值做专门的分析,分析特征异常的label是否为异常值(或者偏离均值较远或者事特殊符号),异常值是否应该剔除,还是用正常值填充,是记录异常,还是机器本身异常等。
对于Label做专门的分析,分析标签的分布情况等。
进步分析可以通过对特征作图,特征和label联合做图(统计图,离散图),直观了解特征的分布情况,通过这一步也可以发现数据之中的一些异常值等,通过箱型图分析一些特征值的偏离情况,对于特征和特征联合作图,对于特征和label联合作图,分析其中的一些关联性。
分析的时候,训练集,测试集,标签我们都要做相应的处理和分析,上述只展示了训练集,望周知
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。