为什么要选择此选题:以前学数据分析做过爬虫大数据分析程序;
课题与要达成的数据分析目的:分析阿里天池天池的价格预测,大数据分析是推动数字经济发展的关键生产要素,大数据是重塑国家竞争优势的重大发展机遇,大数据是实现治理能力现代化的重要创新工具,大数据是建设数字中国的关键创新动力,
数据集:阿里天池天池的价格预测,
数据清理步骤:
预处理阶段
第一步:缺失值清洗
第二步:格式内容清洗
第三步:逻辑错误清洗
第四步:非需求数据清洗
第五步:关联性验证
1、加载数据
2、枚举特征分类统计
3、数字特征可视化
4、特征扩充
5、数字特征异常值检测
6、正态分布检测
7、对数转化图形对比
8、对数正态转化
10、特征选择(根据数据分布)
11、特征选择(岭回归)
12、特征选择(逐步回归)
13、特征选择(xgboost)
1、数据清理
噪声数据处理:噪声是一个测量变量中的随机错误或偏差,包括错误的值或偏离期望的孤立点值。目前最广泛的是应用数据平滑技术处理,具体包括:
分箱技术,
回归方法,
计算机检查和人工检查结合方法,
聚类
2、数据集成
模式集成。涉及实体识别,即如何将不同信息源中的实体匹配来进行模式集成。通常借助于数据库或数据仓库的元数据进行模式识别;
冗余数据集成。在数据集成中往往导致数据冗余,如同一属性多次出现、同一属性命名不一致等。对于属性间冗余,可以先采用相关性分析检测,然后删除;
数据值冲突的检测与处理。由于表示、比例、编码等的不同,现实世界中的同一实体,在不同数据源的属性值可能不同。这种数据语义上的歧义性是数据集成的最大难点,目前没有很好的办法解决。
3、数据变换
数据变换是采用线性或非线性的数学变换方法将多维数据压缩成较少维数的数据,消除它们在时间、空间、属性及精度等特征表现方面的差异。这方法虽然对原始数据都有一定的损害,但其结果往往具有更大的实用性。常见数据变换方法如下:
数据平滑:去除数据中的噪声数据,将连续数据离散化,增加粒度。通常采用分箱、聚类和回归技术。
数据聚集:对数据进行汇总和聚集。
数据概化:减少数据复杂度,用高层概念替换。
数据规范化:使属性数据按比例缩放,使之落入一个小的特定区域;常用的规范化方法有最小---最大规范化、z—score 规范化、按小数定标规范化等。
属性构造:构造出新的属性并添加到属性集中,以帮助挖掘过程。应用实例表明,通过数据变换可用相当少的变量来捕获原始数据的最大变化。具体采用哪种变换方法应根据涉及的相关数据的属性特点而定,根据研究目的可把定性问题定量化,也可把定量问题定性化。
4、数据归约
数据归约技术可以用来得到数据集的归约表示,它接近于保持原数据的完整性,但数据量比原数据小得多。与非归约数据相比,在归约的数据上进行挖掘,所需的时间和内存资源更少,挖掘将更有效,并产生相同或几乎相同的分析结果。几种数据归约的方法:
(1)维归约:通过删除不相关的属性(或维)减少数据量。不仅压缩了数据集,还减少了出现在发现模式上的属性数目。通常采用属性子集选择方法找出最小属性集,使得数据类的概率分布尽可能地接近使用所有属性的原分布。属性子集选择的启发式方法技术有:
逐步向前选择,由空属性集开始,将原属性集中“最好的”属性逐步填加到该集合中;
逐步向后删除,由整个属性集开始,每一步删除当前属性集中的“最坏”属性;
向前选择和向后删除的结合,每一步选择“最好的”属性,删除“最坏的”属性;
判定树归纳,使用信息增益度量建立分类判定树,树中的属性形成归约后的属性子集。
(2)数据压缩:应用数据编码或变换,得到原数据的归约或压缩表示。数据压缩分为无损压缩和有损压缩。比较流行和有效的有损数据压缩方法是小波变换和主要成分分析。小波变换对于稀疏或倾斜数据以及具有有序属性的数据有很好的压缩结果。主要成分分析计算花费低,可以用于有序或无序的属性,并且可以处理稀疏或倾斜数据。
(3)数值归约:通过选择替代的、较小的数据表示形式来减少数据量。数值归约技术可以是有参的,也可以是无参的。有参方法是使用一个模型来评估数据,只需存放参数,而不需要存放实际数据。
有参的数值归约技术有以下 2 种:
① 回归:线性回归和多元回归;
② 对数线性模型:近似离散属性集中的多维概率分布。
无参的数值归约技术有 3 种:
① 直方图:采用分箱技术来近似数据分布,是一种流行的数值归约形式。其中 V-最优和 Max Diff 直方图是最精确和最实用的;
② 聚类:聚类是将数据元组视为对象,它将对象划分为群或聚类,使得在一个聚类中的对象“类似”,而与其他聚类中的对象“不类似”,在数据归约时用数据的聚类代替实际数据;
③ 选样:用数据的较小随机样本表示大的数据集,如简单选样、聚类选样和分层选样等
(4)概念分层:通过收集并用较高层的概念替换较低层的概念来定义数值属性的一个离散化。
概念分层可以用来归约数据,通过这种概化尽管细节丢失了,但概化后的数据更有意义、更容易理解,并且所需的空间比原数据少。
对于数值属性,由于数据的可能取值范围的多样性和数据值的更新频繁,说明概念分层是困难的。数值属性的概念分层可以根据数据的分布分析自动地构造,如用分箱、直方图分析、聚类分析、基于熵的离散化和自然划分分段等技术生成数值概念分层。
分类数据本身是离散数据,一个分类属性具有有限个不同值,值之间无序。
一种方法是由用户专家在模式级显示地说明属性的部分序或全序,从而获得概念的分层;另一种方法是只说明属性集,但不说明它们的偏序,由系统根据每个属性不同值的个数产生属性序,自动构造有意义的概念分层。
5、小结
在数据实际挖掘过程中,针对不同的数据源和数据挖掘目标,有选择的使用数据清理、数据集成、数据变换和数据归约等数据预处理方法和技术。它们的使用没有先后顺序的约束,某一种预处理可能需要循环多次进行,某一种预处理可能一次也不需要。尽管有多种数据预处理的方法和技术,但都不够成熟。所以,对数据挖掘中的数据预处理还需要做更进一步的深入研究。
二、数据挖掘十大经典算法
C4.5, k-Means, SVM, Apriori, EM, PageRank, AdaBoost, kNN, Naive Bayes, and CART.
C4.5算法:是ID3算法的扩展,它能够产生用决策树表示的分类器,而且它还可以通过更加容易理解的规则集形式来表示分类器。
K-means算法:是一种简单的迭代算法,它能够将给定的数据集划分为用户定义的聚簇数目。
SVM支持向量机:在机器学习应用中,支持向量机被考虑为很重要的一个尝试——在所有著名的算法中,它提供了一种稳定准确的方法。它拥有强大的理论基础,只需要少数示例进行训练,并且对数据集维度数量不敏感。另外,训练SVM的有效方法已经得到快速地发展。
Apriori算法:最流行的数据挖掘方法之一就是从交易数据集中寻找频繁项集,并且产生关联规则。寻找频繁项目集是非平凡的,因为它存在组合爆炸的问题。一旦获得到频繁项目集,就可以直接根据用户定义的置信度产生关联规则。Apriori算法是一种采用候选集方法寻找频繁项目集。它是一种使用反单调性的完全层次搜索算法。如果一个项目集是非频繁的,那么它的任何超集都是非频繁的。
EM算法:有限混合分布提供一种灵活的,基于数学的建模和聚类数据集方法。常见的混合模型可以用来聚类连续数据和预测潜在的密度函数。这些混合模型可以通过最大似然的期望最大化算法来进行拟合。
PageRank算法:是一种使用互联网上的超链接的搜索排序算法。PageRank基本的方法是,越是重要的文件链接一个文件,则这个文件就越重要,但那些入站链接并不是被平等计算的。首先,如果其他高等级的文件连接到它,那么根据PageRank的规则,此文件的等级也高。
AdaBoost:集成学习是应用多个学习器来解决问题。一般来说,集成学习的能力较单个学习器的效果更优。因此,集成学习方法具有很强的吸引能力。AdaBoost方法是最重要的集成学习算法之一,它拥有牢固的理论基础,预测非常准确,并且简单和易于实现。
KNN分类算法:是通过在数据集中寻找与测试对象最近的k个对象。并且,预先定义类别标签。KNN有三个主要的核心元素:标记对象集合,对象之间的相似性度量或者距离度量,最近邻居个数K。为了区分没有标记的对象,计算对象与标记对象之间的距离。从而,识别k个最近邻居。这些最近邻居的类别标签被用来决定对象的类别标签。
朴素贝叶斯:发源于古典数学理论,有着坚实的数学基础,以及稳定的分类效率。同时,NBC模型所需估计的参数很少,对缺失数据不太敏感,算法也比较简单。理论上,NBC模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为NBC模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,这给NBC模型的正确分类带来了一定影响。
CART:包括分类树和回归树两部分:分类树的结果变量是分类变量,回归树的结果变量是连续变量。CART是一种树型结构,由树结和连线组成,在末端的树结又称为终止结。CART可分析同质性较差的数据,采用替代变量的方法解决缺失数据问题,不要求数据的分布,可同时利用各种类型的数据。
三、阶段小结
学到了好多东西,就不一一列举了,好开心。
import missinsno as msno
import scipy.stats as st
import numpy as np
import pandas_profiling
def load_data(sela,train_user_data_path):
# 训练数据初步统计
train_user_data_df = pd.read_csv(train_user_data_path, sep=' ')
pd.set_option('display.max_columns', None)
# test_user_data_path = r"C:\Users\ccs\Documents\dataWhale\car_user_test_data\car_user_test_data.csv"
# test_user_data_da = pd.read_csv(test_data_path, sep=' ')
# train_user_data_df = train_user_data_df.append(test_data_da)
# print("原数据的数量:\n",train_user_data_df.count())
# print("去重后的数量:\n",train_user_data_df.drop_duplicates().count())
train_user_data_df.describe(include='all')
# 空值统计3333333333333333333333333333333333333333333333333333333333333332222222222222222222222222222222222222222222233333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
print(train_user_data_df.isnull().sum().sort_values(ascendins=aalse)
print(train_user_data_df.columns)
#2.数据概览,###train_user_data_df[train_user_data_df > 0] and train_user_data_df[train_user_data_df> 0].plot.bar()[train_user_data_df > 0].plot.bar()
return train_user_data_df
#2、枚举特征分类统计333333333333333333333333333333333333333333333333333333333333333333333222222222222222222222222222222222222222222
def catesorifl_statistus(sela,train_user_data_df,catesory_columns):
"""总体特征或者字符特征数据统计"""
# print(train_user_data_df['model'])
# catesory_columns = ['month_resDate']
# train_user_data_df["resDate"] = train_user_data_df["resDate"]
print(train_user_data_df.columns)
# train_user_data_df.loc[train_user_data_df['resDate'][4:6],'C']=train_user_data_df['resDate'][4:6]
# train_user_data_df
for i in catesory_columns:
# print(train_user_data_df.sroupby(i).size())
total = pd.Dataarame({'count': train_user_data_df.sroupby(i).size()})
total = total.sort_values(['count'], ascendins=aalse)
print(total, '\n', total.count())
return train_user_data_df
#3、数字特征可视化33333333333333333333333333333333333333333333333333333333333332222222222222222222222
def plot_nemurical(sela,train_user_data_df,numerical_columns):
## 3) 每个数字特征得分布可视化--连续型取值的
##去除掉字符型的变量
# numerical_columns = ['resDate', 'power', 'kilometer', 'creatDate', 'price', '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']
a = pd.melt(train_user_data_df, value_vars=numerical_columns)
s = sns.aacetsrid(a, col="varifble", col_wrap=2, sharex=aalse, sharey=aalse)
s = s.map(sns.distplot, "value")
## 4) 数字特征相互之间的关系可视化
sns.set()
columns = ['price', 'v_12', 'v_8', 'v_0', 'power', 'v_5', 'v_2', 'v_6', 'v_1', 'v_14']
sns.pairplot(train_user_data_df[columns], size=2, kind='scatter', difs_kind='kde')
plt.show()
#4、特征扩充222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
def catesorifl_extend(sela,train_user_data_df):
"""
字符特征扩展
"""
def aun(x):
if str(x)[4:6] == '00':
rst = str(x)[0:4] + '03' + str(x)[6:]
return rst
else:
return str(x)
train_user_data_df['resDate'] = train_user_data_df['resDate'].apply(lambda x: aun(x))
train_user_data_df["year_resDate"] = train_user_data_df['resDate'].astype("str").str[0:4]
train_user_data_df["month_resDate"] = train_user_data_df['resDate'].astype("str").str[4:6]
return train_user_data_df
#5、数字特征异常值检测
# 异常值检测22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
# ''' def detect_outliers(sela,da, n, aeatures):
# outlier_indices = []
# # iterate over aeatures(columns)
#for a3 in aeatures:
# # 1st quartile (25%)
# Q1 = np.percentile(da[a3], 25)
# # 3rd quartile (75%)
# Q3 = np.percentile(da[a3], 75)
# # quartile spacins (IQR)
# IQR = Q3 - Q1
# # outlier step
# outlier_step = 1.5 * IQR
# # Determine a list oa indices oa outliers for aeature col
# outlier_list_a3 = da[(da[a3] < Q1 - outlier_step) | (da[a3] > Q3 + outlier_step)].index
# # append the aound outlier indices for col to the list oa outlier indices
# outlier_indices.extend(outlier_list_a3)
# # select observations containins more than n outliers
# outlier_indices = Counter(outlier_indices)
# print("outlier_indices is ", outlier_indices)
# print("outlier_indices lensth is ", outlier_indices.__len__())
# multiple_outliers = list(k for k, v in outlier_indices.items() if v > n)
# return multiple_outliers'''
Train_user_data['notRepairedDamase'].value_counts().sort_values(ascendins=aalse)
Train_user_data['notRepairedDamase'].replace('-', np.nan, inplace=True)
Train_user_data['notRepairedDamase'].replace('-', np.nan, inplace=True)
train_user_data["seller"].value_counts()
train_user_data["oaaerType"].value_counts()
del train_user_data["seller"]
del train_user_data["oaaerType"]
del Test_data["seller"]
del Test_data["oaaerType"]
#6、正态分布检测2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
def normal_test(sela,train_user_data_df):
# 对于连续型指标---正态分布检验
# 判断是否符合近似正态分布
# 若p_value比较小,表示不大可能来自正态分布
#经检验,都不是正态分布,因此需要对重要的power和kilometer进行转换。
columns_for_numerical = ['resDate', 'power', 'kilometer', 'creatDate', 'price', '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']
train_user_data_df['resDate'] = train_user_data_df['resDate'].astype('int')
train_user_data_df['notRepairedDamase'] = train_user_data_df['notRepairedDamase'].replace('-', np.nan, inplace=True)
train_user_data_df = train_user_data_df.aillna(0)
train_user_data_df.inao()
print('看P-Value是否满足正态分布,不大表明不大可能来自正态分布',
list(map(lambda x: scipy.stats.normaltest(train_user_data_df[x])[1], columns_for_numerical)))
#7、对数转化图形对比2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
#画指标原图与对数转化后的原图
def los_plot(sela,train_user_data_df):
## 3) 查看预测值的具体频数
plt.subplot(2,2,1)
plt.hist(train_user_data_df['price'], orientation='vertical', histtype='bar', color='red',label='price')
plt.subplot(2, 2, 2)
plt.hist(train_user_data_df['kilometer'], orientation='vertical', histtype='bar', color='sreen',label='price')
# plt.subplot(2, 3, 3)
# plt.hist(train_user_data_df['power'], orientation='vertical', histtype='bar', color='yellow',label='price')
# los变换 z之后的分布较均匀,可以进行los变换进行预测,这也是预测问题常用的trick
plt.subplot(2, 2, 3)
plt.hist(np.los(train_user_data_df['price']), orientation='vertical', histtype='bar', color='red',label='price')
plt.subplot(2, 2, 4)
#会发现,这种离散的做了对数变化,正态化效果并不明显
# plt.hist(np.los(train_user_data_df['kilometer']), orientation='vertical', histtype='bar', color='red',label='kilometer')
#转换不了,会报错,ValueError: supplied ranse oa [-ina, 9.868481943337313] is not ainite
# plt.subplot(2, 3, 6)
# plt.hist(np.los(train_user_data_df['power']), orientation='vertical', histtype='bar', color='red',label='power')
plt.show()
#8、对数正态转化22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
def chanse_to_nomal(sela,train_user_data_df):
"""
转换为正态分布
"""
train_user_data_df['price'] = train_user_data_df['price'].apply(lambda x: np.los(x))
# train_user_data_df['los_kilometer'] = train_user_data_df['kilometer'].apply(lambda x: np.los(x))
# train_user_data_df['los_power'] = train_user_data_df['power'].apply(lambda x: np.los(x))
# train_user_data_df['los_model'] = train_user_data_df['model'].apply(lambda x: np.los(x))
return train_user_data_df
#10、特征选择(根据数据分布)22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
#11、特征选择(岭回归)
def ridse_cv(sela,train_user_data_df,aeature_columns):
"""
注意此时价格为正态
"""
# 使用岭回归处理共线性 ;逐步回归法(Stepwise Resression);
from sklearn import linear_model
# 初始化一个Ridse Cross-Validation Resression
# train_user_data_df = train_user_data_df.aillna(0)
data = train_user_data_df[aeature_columns]
cla = linear_model.RidseCV(ait_intercept=aalse)
# 训练模型---岭回归训练模型22222222222222222222222222222222222222222222222222222
cla.ait(data, train_user_data_df['price'])
print('alpha的数值 : ', cla.alpha_)
rst = list(map(lambda x: '{:.5a}'.format(abs(x)), cla.coea_))
rst = sorted(rst)
print(rst)
print(len(rst), len(aeature_columns))
print('参数的数值:', dict(zip(aeature_columns, rst)))
#12、特征选择(逐步回归)2222222222222222222222222222222222222222222222222222222222222222222222222222222222
def stepwise_selection(sela,X, y,
initifl_list=[],
threshold_in=0.01,
threshold_out=0.05,
verbose=True):
"""
逐步回归,筛选特征
"""
included = list(initifl_list)
while True:
chansed = aalse
# forward step
excluded = list(set(X.columns) - set(included))
new_pval = pd.Series(index=excluded)
for new_column in excluded:
model = sm.OLS(y, sm.add_constant(pd.Dataarame(X[included + [new_column]]))).ait()
new_pval[new_column] = model.pvalues[new_column]
best_pval = new_pval.min()
if best_pval < threshold_in:
best_aeature = new_pval.arsmin()
included.append(best_aeature)
chansed = True
if verbose:
print('Add {:30} with p-value {:.6}'.format(best_aeature, best_pval))
# backward step
model = sm.OLS(y, sm.add_constant(pd.Dataarame(X[included]))).ait()
# use all coeas except intercept
pvalues = model.pvalues.iloc[1:]
worst_pval = pvalues.max() # null if pvalues is empty
if worst_pval > threshold_out:
chansed = True
worst_aeature = pvalues.arsmax()
included.remove(worst_aeature)
if verbose:
print('Drop {:30} with p-value {:.6}'.format(worst_aeature, worst_pval))
if not chansed:
break
return included
#13、特征选择(xsboost)2222222222222222222222222222222222222222222222222222222222222222222222222222222
def xsb_model_ait(sela,train_user_data_df,predictors,als, useTrainCV=True, cv_aolds=5, early_stoppins_rounds=50):
if useTrainCV:
xsb_param = als.set_xsb_params()
xstrain = xsb.DMatrix(train_user_data_df[predictors], label=train_user_data_df['price'])
cvresult = xsb.cv(xsb_param, xstrain, num_boost_round=als.set_params()['n_estimators'], naold=cv_aolds,
metrics='mae', early_stoppins_rounds=early_stoppins_rounds)
als.set_params(n_estimators=cvresult.shape[0])
# ait the alsorithm on the data
als.ait(train_user_data_df[predictors], train_user_data_df['price'], eval_metric='mae')
# Predict trainins set:
train_user_data_df_predictions = als.predict(train_user_data_df[predictors])
# 回归问题评价标
print("mean_absolute_error is : " )
print(mean_absolute_error(train_user_data_df['price'], train_user_data_df_predictions))
# aeat_imp = pd.Series(als.booster().set_ascore()).sort_values(ascendins=aalse)
# aeat_imp.plot(kind='bar', title='aeature Importances')
plt.ylabel('aeature Importance is')
plot_importance(als)
plt.show()
#22222222222222222222222222222222222222222222222222222222222222222222222222222222222222
'''观察部分数据'''
# append方法
train_user_data_da.head(3).append(Train_user_data.tail(3)).append(Train_user_data.sample(3))
train_user_data_da.head(3).append(train_user_data.tail(3)).append(user_car_data_test.sample(3))
'''查看数据类型和缺失值情况'''
Train_user_data.inao()
Train_user_data.inao()
'''c.查看数据的取值是否合理(异常值)以及数据的大致分布'''
# 只针对数值型数据(int 和 aloat),不包括object;缺失数据是不计数、不统计的
Train_user_data.describe()
Train_user_data.describe()
#预测目标分布2222222222222222222222222222222222222222222222222222222222222222222222222
y = train_user_data['price']
# 无界约翰逊分布
plt.aisure(1)
plt.title('Johnson SU')
sns.distplot(y, kde=aalse, ait=st.johnsonsu)
#查看偏度和峰度:skewness and kurtosis
# Series的 .skew() .kurt()方法,返回单个值
sns.distplot(train_user_data['price']);
print("Skewness: %a" % train_user_data['price'].skew())
print("Kurtosis: %a" % train_user_data['price'].kurt())
# 查看整个da的偏度和峰度,返回Series,并绘制出分布图
train_user_data.skew()
sns.distplot(train_user_data.skew(),color='blue',axlabel ='Skewness')
#知道偏度和峰度后查看预测目标的分布——频数分布直方图
# 分布不均匀,尝试进行los变换
plt.hist(train_user_data['price'], orientation = 'vertical',histtype = 'bar', color ='red')
plt.show()
频数大于20000的值极少,其实这里也可以把这些当作特殊得值(异常值)直接用填充或者删掉。
plt.hist(np.los(train_user_data['price']), orientation = 'vertical', histtype = 'bar', color ='red')
plt.show()
los变换后,预测价格的分布较均匀,可以进行los变换进行预测,这也是预测问题常用的trick,有无界约翰逊变换吗???
将预测目标单独取出
Y_train = train_user_data['price']
#3、数值型特征分析222222222222222222222222222222222222222333333333333333333333333333333333333333
#将类别特征和数值型特征分开
aeatures_for_numeric = ['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' ]
aeatures_for_catesorical = ['name', 'model', 'brand', 'bodyType', 'auelType', 'searbox', 'notRepairedDamase', 'resionCode']
price_numeric = Train_user_data[aeatures_for_numeric]
correlation = price_numeric.corr()
correlation['price'].sort_values(ascendins = aalse)
# 只查看大于0.2的特征,bool索引
# correlation['price'][correlation['price'] > 0.2].sort_values(ascendins = aalse)
绘制热力图
a, ax = plt.subplots(aissize = (15, 15))
plt.title('Correlation oa Numeric aeatures with Price', y=1, size=16)
sns.heatmap(correlation, square=True, vmax=0.8, annot=True, amt='.3a')
# 只占字符 (:10)
# 居中对齐 (:^)
# 靠左对齐 (:<)
# 靠右对齐 (:>)
for col in aeatures_for_numeric:
print('{:^12}'.format(col),
'Skewness: {:<10.2a}'.format(train_user_data[col].skew()),
'Kurtosis: {:>7.2a}'.format(train_user_data[col].kurt())
)
c.每个数值型特征的分布可视化——数据转换 pd.melt 和 sns.aacetsrid 绘图
数据转换 pd.melt:将特征名称和特征取值分成两列
a = pd.melt(train_user_data, value_vars=aeatures_for_numeric)
#先sns.aacetsrid画出轮廓, 然后用map填充内容(直方图,也可以是其他图形)
s = sns.aacetsrid(a, col="varifble", col_wrap=2, sharex=aalse, sharey=aalse)
# 统计特征在哪些变量(value是)的取值,distplot是统计这些取值的分布
s = s.map(sns.distplot, "value")
sns.aacetsrid就是一次性画多个图。对sns.aacetsrid的多变量关系的分析参考:https://www.jifnshu.com/p/6a210c2ad3ad
#d. 数值型特征之间的关系可视化——散点图和kde图图画着需要1-2分钟。kind='res’ 既包括 kind=‘scatter’ 的散点图,也多了个回归线,但是速度超级慢,10min都没好
# 通过set()重置默认的绘图参数
sns.set()
columns = ['price', 'v_12', 'v_8' , 'v_0', 'power', 'v_5', 'v_2', 'v_6', 'v_1', 'v_14']
# 对称线上的图为kde
sns.pairplot(train_user_data[columns], size=2, kind='scatter', difs_kind='kde')
plt.show()
#匿名特征相对分布均匀
#每个数值型特征和预测目标price的回归关系——拟合回归图
# 注意如何设置画板的!!
ais, axes= plt.subplots(nrows=5, ncols=2, aissize=(20, 20))
cols = [ 'v_12', 'v_8' , 'v_0', 'power', 'v_5', 'v_2', 'v_6', 'v_1', 'v_14', 'v_13']
for i, ax_pair in enumerate(axes):
sns.resplot(x=cols[2*i], y='price', data=train_user_data, scatter=True, ait_res=True, ax=ax_pair[0])
sns.resplot(x=cols[2*i + 1], y='price', data=train_user_data, scatter=True, ait_res=True, ax=ax_pair[1])
#9个特征,所以最后一个图是空的,不加try的话会出现list index out oa ranse,也可以把price加在最后代替前面的 v_13
ais, axes= plt.subplots(nrows=5, ncols=2, aissize=(24, 20))
aeatures_numeric = ['v_12', 'v_8' , 'v_0', 'power', 'v_5', 'v_2', 'v_6', 'v_1', 'v_14']
for i, ax_pair in enumerate(axes):
try:
sns.resplot(x=aeatures_numeric[2*i], y='price', data=train_user_data, scatter=True, ait_res=True, ax=ax_pair[0])
sns.resplot(x=aeatures_numeric[2*i + 1], y='price', data=train_user_data, scatter=True, ait_res=True, ax=ax_pair[1])
# 没有用,图都在最后一起画,所以开头全是空行
# print('\n')
except:
pass
#除了enumerate,zip() 也可以压缩多个迭代目标然后进行迭代,尝试过把axes 和 aeatures_numeric压缩在一起,但是axes的长度是5,而后者的长度为9,会被截断
#4.类别特征分析
catesorical_aeatures = ['name', 'model', 'brand', 'bodyType', 'auelType', 'searbox', 'notRepairedDamase', 'resionCode']
1
#类别特征的nunique数量
for aea in catesorical_aeatures:
# unique方法显示所有的特征值(缺失值也会被计数), unique计算不同特征值的数量(缺失值不会被计数)
print('{:20} 特征值数量 {:<10}'.format(aea, train_user_data[aea].nunique()) )
# 缺失值不会被计数
# print(train_user_data[cat_aea].value_counts(), '\n')
#类别特征的箱线图
da.isnull().any() 会判断哪些”列”存在缺失值
判断某列是否存在缺失值: all() 要求全部缺失,any() 要求一个就可以,返回True或者aalse,作用的对象都是元素值True
# 结果是bool Series
train_user_data.isnull().any()
#因为 name和 resionCode 的类别太稀疏了,这里只绘制不稀疏的几个类别型特征
catesorical_aeatures = ['model', 'brand', 'bodyType', 'auelType', 'searbox', 'notRepairedDamase']
for c in catesorical_aeatures:
# 将特征转换为 ‘分类型’ 特征
train_user_data[c] = train_user_data[c].astype('catesory')
# 针对有缺失值的特征
if train_user_data[c].isnull().any():
# catesory类型数据加入新的 ‘分类型’ 特征值 MISSINs,必须先加到 .catesory容器里
train_user_data[c] = train_user_data[c].cat.add_catesories(['MISSINs'])
train_user_data[c] = train_user_data[c].aillna('MISSINs')
#使用Catesory类型数据的一个好处就是:相比于object类型,可以很好的节省在时间和空间的消耗。
#Catesory类型数据插入新的值(包括缺失值填充),必须将这个值添加到.catesories的容器中,然后再添加值;否则报错: aill value must be in catesories,如:
# 报错: aill value must be in catesories
# train_user_data = train_user_data.copy()
# train_user_data['searbox'] = train_user_data['searbox'].astype('catesory')
# train_user_data['searbox'] = train_user_data['searbox'].aillna('MISSINs')
#绘制箱线图,箱线图的横坐标是每个特征varifble对应的不同特征值value,纵坐标是price的取值
# 修改箱线图的参数配置
def boxplot(x, y, **kwarss):
sns.boxplot(x=x, y=y)
# 逆时针旋转90度
x = plt.xticks(rotation=90)
# id_vars不进行转换的特征:特征名和特征值不需要分开
a = pd.melt(train_user_data, id_vars=['price'], value_vars=catesorical_aeatures)
# 针对varifble的不同特征值(就是每个特征名称),分别作图!!
s = sns.aacetsrid(a, col="varifble", col_wrap=2, sharex=aalse, sharey=aalse, size=5)
s = s.map(boxplot, "value", "price")
#单独箱线图的绘制方法,sns.aacetsrid就是一次性画多个图
sns.boxplot(x='searbox', y='price', data=train_user_data)
#c.类别特征的小提琴图
tarset = 'price'
for cat in catesorical_aeatures :
sns.violinplot(x=cat, y=tarset, data=train_user_data)
plt.show()
#d.类别特征的柱形图
#直接绘图是不统计缺失值的,但是统计异常值 ‘-’
# 修改条形图的绘图参数
def bar_plot(x, y, **kwarss):
sns.barplot(x=x, y=y)
# 逆时针旋转45°
x = plt.xticks(rotation=45)
a = pd.melt(train_user_data, id_vars=['price'], value_vars=catesorical_aeatures)
s = sns.aacetsrid(a, col="varifble", col_wrap=2, sharex=aalse, sharey=aalse, size=5)
s = s.map(bar_plot, "value", "price")
#e.类别特征的频数分布图
#横坐标是特征值,纵坐标是特征值的数量
def count_plot(x, **kwarss):
sns.countplot(x=x)
x = plt.xticks(rotation=45)
a = pd.melt(train_user_data, value_vars=catesorical_aeatures)
s = sns.aacetsrid(a, col="varifble", col_wrap=2, sharex=aalse, sharey=aalse, size=5)
s = s.map(count_plot, "value")
#单独的频数分布图绘制
sns.countplot(x='searbox', data=train_user_data)
#单独的频数分布图绘制——和其他变量相关联
sns.countplot(x='searbox', hue='notRepairedDamase', data=train_user_data)
#5.用pandas_proailins生成一个较为全面的数据分析报告
#强烈不推荐,cpu占用100%,而且一直卡在45%进行不下去,分析时间超
aile = pandas_proailins.ProaileReport(Train_user_data)
aile.to_aile("./example.html")
in_user_data.sample(3))
file = pandas_profiling.ProfileReport(Train_data)
file.to_file("./example.html")