【算法竞赛学习】数据分析达⼈赛3:汽车产品聚类分析
赛题背景
赛题以竞品分析为背景,通过数据的聚类,为汽车提供聚类分类。对于指定的车型,可以通过聚类分析到其竞品车型。通过这道赛题,⿎励学习者利⽤车型数据,进⾏车型画像的分析,为产品的定位,竞品分析提供数据决策。
赛题数据
赛题任务
选⼿需要对该汽车数据进⾏聚类分析,并到vokswagen汽车的相应竞品。要求选⼿在天池实验室中⽤notebook完成以上任务,并分享到⽐赛论坛。(聚类分析是常⽤的数据分析⽅法之⼀,不仅可以帮助我们对⽤户进⾏分组,还可以帮我们对产品进⾏分组(⽐如竞品分析)这⾥的聚类个数选⼿可以根据数据集的特点⾃⼰指定,并说明聚类的依据)
⼀、数据探索
了解数据类型及基本情况
数据质量检查:主要包括检查数据中是否有错误,如拼写有误等
对空值、重复值、异常值等检测
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
#⾼清显⽰图⽚
%matplotlib inline
%config InlineBackend.figure_format="retina"
#保证可以显⽰中⽂字体
#正常显⽰负号
#获取数据
car_ad_csv('./car_price.csv')
car_price.head()
#查看数据类型和⾮空、重复值
car_price.info()
car_price.duplicated().sum()
数据集中共205⾏记录,26个字段;没有空值,重复数据为0。
其中,数据类型dtypes: float64(8), int64(8), object(10);
数据特征具体可区分为3⼤类:
第⼀类:汽车ID类属性
1 Car_ID 车号
3 CarName 车名
第⼆类:类别型变量(10个)
2 Symboling 保险风险评级
4 fueltype 燃料类型
5 aspiration 发动机吸⽓形式
6 doornumber 车门数
7 carbody 车⾝型式
8 drivewheel 驱动轮
9 enginelocation 发动机位置
15 enginetype 发动机型号
16 cylindernumber ⽓缸数
18 fuelsystem 燃油系统
第三类:连续数值型变量(14个)
10 wheelbase 轴距
11 carlength 车长
12 carwidth 车宽
13 carheight 车⾼
14 curbweight 整备质量(汽车净重)
17 enginesize 发动机尺⼨
19 boreratio ⽓缸横截⾯⾯积与冲程⽐
20 stroke 发动机冲程
21 compressionratio 压缩⽐
22 horsepower 马⼒
23 peakrpm 最⼤功率转速
24 citympg 城市⾥程(每加仑英⾥数)
25 highwaympg ⾼速公路⾥程(每加仑英⾥数)
26 price(Dependent variable) 价格(因变量)
1.2 检查变量特征取值情况
1.2.1 检查类别型变量
查看类别属性特征分类取值情况(并检查信息拼写错误等)
# 提取类别变量的列名
cate_columns=['symboling','fueltype','aspiration','doornumber','carbody','drivewheel','enginelocation','enginetype','fuelsystem','cylindernumber']
#打印类别变量每个分类的取值情况
for i in cate_columns:
print(i)
print(set(car_price[i]))
由上⾯可检查类别型特征数据是否有拼写错误,还可知道特征的具体分类情况;
分类取值具有⼤⼩意义的,如:
①保险风险评级Symboling的取值范围为:0、 1、2、3、-2、-1,虽是分类特征但其取值是有⼤⼩意义的;
②⽓缸数cylindernumber取值:{‘three’, ‘six’, ‘eight’, ‘five’, ‘four’, ‘twelve’, ‘two’},这7个取值也是有⼤⼩意义的,在同等缸径下,缸数越多,排量越⼤,功率越⾼;在同等排量下,缸数越多,缸径越⼩,转速可以提⾼,从⽽获得较⼤的提升功率;
其他分类取值没有⼤⼩意义的,如:
车门数doornumber分’two’、 'four’两类,因车门数是跟车外形设计有关,如公务⽤途的轿车为四门,⽽运动⽤途跑车为两门,完全是不同类型的车型,其取值没有⼤⼩意义,只是分类;
fueltype 燃料类型分’gas’和’diesel’两类,等等只是类别上属性的分类。
可看到有很多命名是不规则的,需要修正。如:‘toyouta’, ‘maxda’, ‘porcshce’,‘Nissan’, ‘vw’,‘vokswagen’.
#⽓缸数可使⽤具体的数值替换分类
car_price['cylindernumber']=place({'two':2,'three':3,'four':4,'five':5,'six':6,'eight':8,'twelve':12})
1.2.2 检查数值型变量
查看数值型变量取值情况,并检查是否有异常值
#提取变量特征数据(除了'car_ID'和'CarName')
car_df=car_price.drop(['car_ID','CarName'],axis=1)
#查看连续数值型情况,并是检查否有异常值
#对数据进⾏描述性统计
car_df.describe()
从上⾯数据看,数据集不存在违背常理的异常值
#还可以描绘数据集的箱线图,查看异常值
#提取连续数值型数据的列名
num_cols=lumns.drop(cate_columns)
print(num_cols)
#绘制连续数值型数据的箱线图,检查异常值
import seaborn as sns
fig=plt.figure(figsize=(12,8))
i=1
for col in num_cols:
ax=fig.add_subplot(3,5,i)
sns.boxplot(data=car_df[col],ax=ax)
i=i+1
plt.title(col)
plt.subplots_adjust(wspace=0.4,hspace=0.3)
小型汽车图片plt.show()
由各特征的箱线图可知,部分特征存在离点,但不存在特别明显的离点,可接受。#去重查看CarName
print(car_price['CarName'].drop_duplicates())#验证是否object全部改为数值类型
1.3 检查特征数据之间的逻辑关系
分析特征之间是否存在逻辑关系,是否可以进⾏数据特征融合或拆分等等。
1.3.1 由carName拆分品牌信息
由CarName数据组成信息,第⼀个英⽂为其车型的品牌
#利⽤split,由CarName拆出品牌信息
carBrand=car_price['CarName'].str.split(expand=True)[0]
#查看汽车品牌名称(过滤重复)
print(set(carBrand))
由CarName的信息可看出:
1、去重后的CarName有147个记录,说明有重复命名的车名,不是唯⼀值;
2、可由CarName的组成信息,第⼀个英⽂为其品牌,可以split出汽车的品牌
3、CarName部分命名不规则,有错误,如:Nissan,maxda,;(但考虑到赛题中任务为‘到vokswagen汽车的相应竞品’,不确定其中的‘vokswagen’是故意特指id为183的CarName中‘vokswagen rabbit’,还是⼤众volkswagen 的错误拼写,所以不修改CarName中的错误,只在导出的品牌名中修改)
#修改品牌名称的不规则命名
place({'porcshce':'porsche','vokswagen':'volkswagen','Nissan':'nissan','maxda':'mazda','vw':'volkswagen','toyouta':'toyota'})
print(set(carBrand))
#将carBrand放⼊原数据集中
car_price['carBrand']=carBrand
1.3.2 根据车长划分车型⼤⼩
在汽车销售等实际业务中,很多消费者购买需求有时会根据考虑车型的⼤⼩来考虑。
欧系分类,按德国标准,车型⼤⼩可按照车长,轴距划分为6类:
1、微型车(A00):车长⼩于3.7M;轴距⼩于:2.35M;
2、⼩型车(A0):车长⼩于4.3M;轴距⼩于:2.5M;
3、紧凑型车(A):车长⼩于4.6M;轴距⼩于:2.7M;
4、中型车(B):车长⼩于4.9M;轴距⼩于:2.8M;
5、中⼤型车(C):车长⼩于5.1M;轴距⼩于:2.9M;
6、豪华车(D):车长⼤于5.1M;轴距⼤于:2.9M。
⽽要注意,数据集中车长宽⾼和轴距单位均为英⼨,需要进⾏单位的转换:1英⼨=0.0254⽶。
按车⾝长度分类界限:微型车: A00 <145.67 ;⼩型车: A0 <169.29 ;紧凑型车:A <181.10 ;中型车: B <192.91 ;中⼤型车:C <200.79 ;⼤型车: D >200.79
# 由上⾯描述性统计可知,车⾝长范围为141.1~208.1英⼨之间,可划分为6类
bins=[min(car_df.carlength)-0.01,145.67,169.29,181.10,192.91,200.79,max(car_df.carlength)+0.01]
label=['A00','A0','A','B','C','D']
carSize=pd.cut(car_df.carlength,bins,labels=label)
print(carSize)
#将车型⼤⼩分类放⼊数据集中
car_price['carSize']=carSize
car_df['carSize']=carSize
车型⼤⼩分类,为Categories (6, object): [‘A00’ < ‘A0’ < ‘A’ < ‘B’ < ‘C’ < ‘D’],其取值有⼤⼩的意义
当有车型⼤⼩分类后,选择特征聚类时,车⾝的长和宽可剔除,⽽在同类车型中车⾼和轴距则可当为车⾝空间舒适性度量来分析
#查看数值型特征的相关系数
df_corr=()
df_corr