KMeans聚类实例分析(汽车产品聚类分析

天池比赛——汽车产品聚类分析(KMeans+PCA


前言

这是天池中一个关于产品聚类分析的比赛,题目给了一个车购买表,整体数据量不大,分析起来比较简单,还是比较有代表性的。

目录

天池比赛——汽车产品聚类分析(KMeans+PCA

前言

零、Notebook中引入包和绘图设置

一、分析df_car_price_dictionary文件

二.分析car_price文件

2.1 分析字符类

2.2 分析数值型数据 

2.3 分析车名和ID

3. 聚类预处理与聚类分析

3.1 编码obejct类型数据

3.2 处理数值型数据

3.3 标准化数值型数据

3.4 整合数据

3.5 PCA降维

 3.6 KMeans聚类分析

 ​

3.7 选择最后的聚类结果,并进行聚类

4. 分析竞品

总结


题目要求:赛题以竞品分析为背景,通过数据的聚类,为汽车提供聚类分类。对于指定的车型,可以通过聚类分析找到其竞品车型。

下面直接开始分析(整体代码是运行在notebook中的)

博客里有一些图片可能看不太清,还有一些展示的部分博客上不方面放出来,如果想看的比较仔细的,可以从下面这个链接,fork我的notebook


、Notebook中引入包和绘图设置

import pandas as pd
from sklearn.preprocessing import LabelEncoder, StandardScaler
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_score
from pylab import *
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
# 去除警告
warnings.filterwarnings("ignore")
# 正常画图
%matplotlib inline
%config InlineBackend.figure_format = 'svg'
# 正常显示负号
plt.rcParams['axes.unicode_minus']=False
# 中文正常显示
mpl.rcParams['font.sans-serif'] = ['SimHei']
pd.set_option('display.max_columns', None)
pd.set_option('display.width', 500)

一、分析df_car_price_dictionary文件

题目中还给了个对应名词的解释表,而且是个不太规则的表,需要处理一下,具体处理如下代码

df_car_price_dictionary = pd.read_excel('./data/car_price_dictionary.xlsx', skiprows=2)
df_car_price = pd.read_csv('./data/car_price.csv')
# 清除掉数据中的缺失值
df_car_price_dictionary.dropna(axis='index', how='all', inplace=True)
df_car_price_dictionary.dropna(axis='columns', how='all', inplace=True)
df_car_price_dictionary.drop('Unnamed: 13', axis=1, inplace=True)
df_car_price_dictionary.drop('DATA DICTONARY', axis=1,inplace=True)
df_car_price_dictionary.drop(28, axis=0, inplace=True)
# #修改列名
df_car_price_dictionary.columns=['名词','解释']
df_car_price_dictionary.set_index('名词', inplace=True)
df_car_price_dictionary
解释
名词
Car_IDUnique id of each observation (Interger)
SymbolingIts assigned insurance risk rating, A value of...
carCompanyName of car company (Categorical)
fueltypeCar fuel type i.e gas or diesel (Categorical)
aspirationAspiration used in a car (Categorical)
doornumberNumber of doors in a car (Categorical)
carbodybody of car (Categorical)
drivewheeltype of drive wheel (Categorical)
enginelocationLocation of car engine (Categorical)
wheelbaseWeelbase of car (Numeric)
carlengthLength of car (Numeric)
carwidthWidth of car (Numeric)
carheightheight of car (Numeric)
curbweightThe weight of a car without occupants or bagga...
enginetypeType of engine. (Categorical)
cylindernumbercylinder placed in the car (Categorical)
enginesizeSize of car (Numeric)
fuelsystemFuel system of car (Categorical)
boreratioBoreratio of car (Numeric)
strokeStroke or volume inside the engine (Numeric)
compressionratiocompression ratio of car (Numeric)
horsepowerHorsepower (Numeric)
peakrpmcar peak rpm (Numeric)
citympgMileage in city (Numeric)
highwaympgMileage on highway (Numeric)
price(Dependent variable)Price of car (Numeric)

二.分析car_price文件

分析题目给的car_price文件,主要是对其中3类进行分析,一类是关于名字ID的,一类是字符型的(dataframe中的object)还有一类是数值型,每一种都有不同的处理方法,需要我们每个逐一处理

先整体分析一下car_price

df_car_price.info()
df_car_price.duplicated().sum()
"""
 #   Column            Non-Null Count  Dtype  
---  ------            --------------  -----  
 0   car_ID            205 non-null    int64  
 1   symboling         205 non-null    int64  
 2   CarName           205 non-null    object 
 3   fueltype          205 non-null    object 
 4   aspiration        205 non-null    object 
 5   doornumber        205 non-null    object 
 6   carbody           205 non-null    object 
 7   drivewheel        205 non-null    object 
 8   enginelocation    205 non-null    object 
 9   wheelbase         205 non-null    float64
 10  carlength         205 non-null    float64
 11  carwidth          205 non-null    float64
 12  carheight         205 non-null    float64
 13  curbweight        205 non-null    int64  
 14  enginetype        205 non-null    object 
 15  cylindernumber    205 non-null    object 
 16  enginesize        205 non-null    int64  
 17  fuelsystem        205 non-null    object 
 18  boreratio         205 non-null    float64
 19  stroke            205 non-null    float64
 20  compressionratio  205 non-null    float64
 21  horsepower        205 non-null    int64  
 22  peakrpm           205 non-null    int64  
 23  citympg           205 non-null    int64  
 24  highwaympg        205 non-null    int64  
 25  price             205 non-null    float64

0
"""

数据没有缺失项和重复项

2.1 分析字符类

# 选出obejct类
df_object = df_car_price.select_dtypes(include='object').drop(columns='CarName')
# 看object类中的类型有啥
for object in df_object.columns:
    print(object, df_object[object].unique())
fueltype ['gas' 'diesel']
aspiration ['std' 'turbo']
doornumber ['two' 'four']
carbody ['convertible' 'hatchback' 'sedan' 'wagon' 'hardtop']
drivewheel ['rwd' 'fwd' '4wd']
enginelocation ['front' 'rear']
enginetype ['dohc' 'ohcv' 'ohc' 'l' 'rotor' 'ohcf' 'dohcv']
cylindernumber ['four' 'six' 'five' 'three' 'twelve' 'two' 'eight']
fuelsystem ['mpfi' '2bbl' 'mfi' '1bbl' 'spfi' '4bbl' 'idi' 'spdi']

我们这里分析一下字符类里的取值,我们从上面的名词解释,可以分析出来,除了cylindernumber(气缸数)这个点的数字,越大越好,可以做为数值型处理,其他都为表示类型,可以使用one-hot编码 

这里我们先直接对cylindernumber 进行编码,然后把他归为数值型数据处理

enc_cylindernumber = {'two':2, 'three':3, 'four':4, 'five':5, 'six':6, 'eight':8, 'twelve': 12}
for index, value in enumerate(df_object['cylindernumber']):
    df_object['cylindernumber'][index] = enc_cylindernumber[value]
df_numeric['cylindernumber'] = df_object['cylindernumber'].astype('int32')
df_object.drop(columns='cylindernumber',inplace=True)

2.2 分析数值型数据 

分析数值型数据,主要是分析数字型数据有无异常值和分析数据间的相关性,为后续聚类降维做准备

从箱线图可以看出,整体上数据没有什么离异点,有异常点的值为price等特征,在汽车行业属于正常现象(有高端车和低端车),所有可以认为数据正常。

然后我们可以去用热力图去分析数据的相关性

df_numeric_corr = df_numeric.corr()
plt.figure(figsize=(10,10))
mask = np.zeros_like(df_numeric_corr, dtype=np.bool)
# 将mask右上三角(列号》=行号)设置为True
mask[np.triu_indices_from(mask)] = True
sns.heatmap(df_numeric_corr,annot=True, mask=mask)
plt.show()

由于我们需要对数据进行聚类,一些强相关的属性可以融合成为一个属性,如carlength(车长),如carwidth(车宽),wheelbase(底盘长度)和curbweight(车净重量),在分析时就可以选择其中一个进行分析即可

相似的还有enginesize(引擎尺寸)和horsepower(马力)和price(价格)

citympg(城市里程)和highwaympg(高速里程)

当然具体是不是强相关的都当做一个属性来处理,得具体分析看效果

2.3 分析车名和ID

因为我们最后是为volkswagen做竞品分析的,所以方便我们做检索,我们要对车名的数据做了解,分析,看看数据有没有问题和处理成我们方便查看的情况。

# 查看有多少种车
s_CarName = df_car_price['CarName']
print(s_CarName.unique())
print(s_CarName.unique().shape)
print("重复的车名:",s_CarName.duplicated().sum())

"""
['alfa-romero giulia' 'alfa-romero stelvio' 'alfa-romero Quadrifoglio'
 'audi 100 ls' 'audi 100ls' 'audi fox' 'audi 5000' 'audi 4000'
 'audi 5000s (diesel)' 'bmw 320i' 'bmw x1' 'bmw x3' 'bmw z4' 'bmw x4'
 'bmw x5' 'chevrolet impala' 'chevrolet monte carlo' 'chevrolet vega 2300'
 'dodge rampage' 'dodge challenger se' 'dodge d200' 'dodge monaco (sw)'
 'dodge colt hardtop' 'dodge colt (sw)' 'dodge coronet custom'
 'dodge dart custom' 'dodge coronet custom (sw)' 'honda civic'
 'honda civic cvcc' 'honda accord cvcc' 'honda accord lx'
 'honda civic 1500 gl' 'honda accord' 'honda civic 1300' 'honda prelude'
 'honda civic (auto)' 'isuzu MU-X' 'isuzu D-Max ' 'isuzu D-Max V-Cross'
 'jaguar xj' 'jaguar xf' 'jaguar xk' 'maxda rx3' 'maxda glc deluxe'
 'mazda rx2 coupe' 'mazda rx-4' 'mazda glc deluxe' 'mazda 626' 'mazda glc'
 'mazda rx-7 gs' 'mazda glc 4' 'mazda glc custom l' 'mazda glc custom'
 'buick electra 225 custom' 'buick century luxus (sw)' 'buick century'
 'buick skyhawk' 'buick opel isuzu deluxe' 'buick skylark'
 'buick century special' 'buick regal sport coupe (turbo)'
 'mercury cougar' 'mitsubishi mirage' 'mitsubishi lancer'
 'mitsubishi outlander' 'mitsubishi g4' 'mitsubishi mirage g4'
 'mitsubishi montero' 'mitsubishi pajero' 'Nissan versa' 'nissan gt-r'
 'nissan rogue' 'nissan latio' 'nissan titan' 'nissan leaf' 'nissan juke'
 'nissan note' 'nissan clipper' 'nissan nv200' 'nissan dayz' 'nissan fuga'
 'nissan otti' 'nissan teana' 'nissan kicks' 'peugeot 504' 'peugeot 304'
 'peugeot 504 (sw)' 'peugeot 604sl' 'peugeot 505s turbo diesel'
 'plymouth fury iii' 'plymouth cricket' 'plymouth satellite custom (sw)'
 'plymouth fury gran sedan' 'plymouth valiant' 'plymouth duster'
 'porsche macan' 'porcshce panamera' 'porsche cayenne' 'porsche boxter'
 'renault 12tl' 'renault 5 gtl' 'saab 99e' 'saab 99le' 'saab 99gle'
 'subaru' 'subaru dl' 'subaru brz' 'subaru baja' 'subaru r1' 'subaru r2'
 'subaru trezia' 'subaru tribeca' 'toyota corona mark ii' 'toyota corona'
 'toyota corolla 1200' 'toyota corona hardtop' 'toyota corolla 1600 (sw)'
 'toyota carina' 'toyota mark ii' 'toyota corolla'
 'toyota corolla liftback' 'toyota celica gt liftback'
 'toyota corolla tercel' 'toyota corona liftback' 'toyota starlet'
 'toyota tercel' 'toyota cressida' 'toyota celica gt' 'toyouta tercel'
 'vokswagen rabbit' 'volkswagen 1131 deluxe sedan' 'volkswagen model 111'
 'volkswagen type 3' 'volkswagen 411 (sw)' 'volkswagen super beetle'
 'volkswagen dasher' 'vw dasher' 'vw rabbit' 'volkswagen rabbit'
 'volkswagen rabbit custom' 'volvo 145e (sw)' 'volvo 144ea' 'volvo 244dl'
 'volvo 245' 'volvo 264gl' 'volvo diesel' 'volvo 246']
(147,)
重复的车名: 58
"""

可以看到车名是有重复的,但具体是登记错误,还是不同的款式,这里我们不好分析,我们就当作是不同的款式处理就好了。 

 我们从车名中,可以划分出对应的公司出来

car_companys = []
for name in df_car_price['CarName']:
    car_companys.append(name.split()[0])

"""
{'Nissan',
 'alfa-romero',
 'audi',
 'bmw',
 'buick',
 'chevrolet',
 'dodge',
 'honda',
 'isuzu',
 'jaguar',
 'maxda',
 'mazda',
 'mercury',
 'mitsubishi',
 'nissan',
 'peugeot',
 'plymouth',
 'porcshce',
 'porsche',
 'renault',
 'saab',
 'subaru',
 'toyota',
 'toyouta',
 'vokswagen',
 'volkswagen',
 'volvo',
 'vw'}
"""

我们可以发现,有些公司名字是错误的,我们需要对其修改并把公司名字列入我们的表格中,方便后续操作,如maxda, porcshce, toyouta, volkswagen, Nissan*

replace_name = {'maxda':'mazda', 'porcshce':'porsche', 'toyouta':'toyota', 'vokswagen':'volkswagen', 'Nissan':'nissan'}
for key in replace_name.keys():
    s_CarName = s_CarName.str.replace(key, replace_name[key])

car_companys = []
for name in df_car_price['CarName']:
    car_companys.append(name.split()[0])

# 将改完名的整合回去
df_car_price['CarName'] = s_CarName
df_car_price['CarCompany'] = car_companys

3. 聚类预处理与聚类分析

这里主要是对字符类的数据进行编码处理,对数值型数据去除冗余数据和标准化处理。然后就是整合数据,对待多维的数据,就需要做PCA降维后,再去做聚类分析。

3.1 编码obejct类型数据

这里就是简单的做一个one-hot编码即可

# 对除了cylindernumber的其他object类进行独热编码
df_enc_object = df_object.drop(columns='CarCompany').copy()
df_enc_object = pd.get_dummies(df_enc_object)

3.2 处理数值型数据

这里要根据上面的分析,去去除掉冗余项,这里就看个人的分析和具体效果了,我这里简单粗暴的去除掉了相关系数高于80%的项

# 根据上面的分析去除carlength,curbweight,wheelbase,enginesize和citympg
df_numeric.drop(columns=['carlength', 'curbweight', 'enginesize', 'citympg'], inplace=True)

3.3 标准化数值型数据

这里标准化数值型数据,由于我们的数据都是有数字意义的,所以不要使用标准化了,而要用归一化

from sklearn.preprocessing import MinMaxScaler
minmax_scaler = MinMaxScaler()
df_scaler_numeric = minmax_scaler.fit_transform(df_numeric)
# 转换为DataFrame格式
df_scaler_numeric = pd.DataFrame(df_scaler_numeric)
df_scaler_numeric.columns = df_numeric.columns

3.4 整合数据

df_train = pd.concat([df_scaler_numeric, df_enc_object],axis=1)

3.5 PCA降维

我们整合后的数据,维度会变大,我们这时候需要PCA来对数据降维,但具体降到多少维度,我们根据解释方差,和二八法则来确定(这也不是标准的法则,需要具体问题具体分析,但我这里也暴力的直接这么用了)

from sklearn.decomposition import PCA
pca = PCA()
df_pca_train = pca.fit_transform(df_train)
pca_var_ration = pca.explained_variance_ratio_
pca_cumsum_var_ration = np.cumsum(pca.explained_variance_ratio_)
print("PCA 累计解释方差")
print(pca_cumsum_var_ration)

"""
PCA 累计解释方差
[0.23314511 0.43849978 0.56306421 0.63555569 0.70014848 0.74826802
 0.79179606 0.82485026 0.84781286 0.86854948 0.88792651 0.90451432
 0.91954628 0.93184813 0.94168537 0.95115811 0.95984862 0.9675858
 0.97423751 0.9789124  0.9830742  0.98645196 0.98952764 0.99166151
 0.99347482 0.99480493 0.99603279 0.99716348 0.99814921 0.99882805
 0.9993374  0.99969817 0.99990424 1.         1.         1.
 1.         1.         1.         1.         1.         1.
 1.        ]
"""

 

 而且二八法则,我们直接选取前8个主成分进行聚类分析。

pca = PCA(n_components=8)
df_8pca_train = pca.fit_transform(df_train)
pca.explained_variance_ratio_.sum()

"""
0.8248502560723865
"""

 3.6 KMeans聚类分析

这里聚成几类,要分析起来也不好确定,但我们可以大概通过SSE手肘法和看轮廓系数来分析

from sklearn.metrics import silhouette_score
# 手肘法和平均轮廓法分析一下聚几类
sse = []
scores = []
for i in range(2, 9):
    kmeans = KMeans(n_clusters=i)
    kmeans.fit(df_8pca_train)
    scores.append(silhouette_score(df_8pca_train, kmeans.labels_, metric='euclidean'))
    sse.append(kmeans.inertia_)
    
x = [i for i in range(2,9)]

plt.figure(figsize=(10, 5))
plt.subplot(1,2,1)
plt.title('KMeans聚类SSE系数')
plt.xlabel('聚类数')
plt.plot(x, sse, 'o-')

plt.subplot(1,2,2)
plt.title('KMeans聚类平均轮廓系数')
plt.xlabel('聚类数')
for i in range(2, 9):
    plt.text(i, scores[i-2], (str(round(scores[i-2], 2))))    
plt.plot(x, scores, 'o-')

 

 这个地方看轮廓系数,明显不好使了,因为聚类数增加,轮廓系数增加,就说明数据的集合属性不是很明显,我们大概通过手肘法,可以看出应该聚为4类或者5类,我们通过可视化分析一下。

def plot_3or2d_KMeans(kmeans, data, dimension):
    colors = ['b','g','r','c','k','m','y','#e24fff','#524C90','#845868']
    kmeans_center = kmeans.cluster_centers_[:,0:3]
    kmeans_labels = kmeans.labels_
    #fig = plt.figure(figsize=(6,6))
    if dimension == 3:
        ax = plt.axes(projection='3d')
    elif dimension == 2:
        ax = plt.axes()
        
    for i in range(kmeans.labels_.max()+1):
        labels = np.nonzero(kmeans_labels == i)
        for label in labels:
            if dimension == 3:
                ax.scatter3D(data[:,0][label], data[:, 1][label], 
                             data[:, 2][label], 
                             marker='.',s=30,lw=0,alpha=0.7, color=colors[i])
        
                ax.scatter3D(kmeans_center[:,0][i], kmeans_center[:, 1][i], kmeans_center[:, 2][i], 
                         marker='o', color='w', alpha=1,s=100, edgecolor='k')
                plt.title('聚类数为{},取前3维特征可视化分析'.format(kmeans.labels_.max()+1))
                
            if dimension == 2:
                ax.scatter(data[:, 0][label], data[:, 1][label],
                          marker='.',s=30,lw=0,alpha=0.7, color=colors[i])
                ax.scatter(kmeans_center[:,0][i], kmeans_center[:, 1][i], 
                         marker='o', color='w', alpha=1,s=100, edgecolor='k')
                plt.title('聚类数为{},取前2维特征可视化分析'.format(kmeans.labels_.max()+1))
    plt.show()
 

df_0to3_pca_train = df_8pca_train[:, 0:3] 
df_0to2_pca_train = df_8pca_train[:, 0:2] 
# kmeans = KMeans(n_clusters=3)
# kmeans.fit(df_8pca_train)
# plot_3or2d_KMeans(kmeans, df_0to2_pca_train, 2)
for i in range(2, 8):
    kmeans = KMeans(n_clusters=i)
    kmeans.fit(df_8pca_train)
    plot_3or2d_KMeans(kmeans, df_0to3_pca_train, 3)
    plot_3or2d_KMeans(kmeans, df_0to2_pca_train, 2)
    
    

 

我们粗略的取前三维的信息进行可视化分析,从可视化图可以看出,当聚为5类的时候,有两个类别的中心点过于靠近,会导致类别边界不明显,所以我们最后选择聚为4类

3.7 选择最后的聚类结果,并进行聚类

kmeans = KMeans(n_clusters=4)
kmeans.fit(df_8pca_train)
kmeans_pred = kmeans.fit_predict(df_8pca_train)

df_result = df_car_price.copy()
df_result['km_result'] = kmeans_pred
df_result

4. 分析竞品

我们聚完类后,就可以去分析我们指定的车型所在类的,和知道它所属类别中的其他竞品,进而去进一步的分析。下面就只分析其中一个类别了

df_result_pivot_table = df_result.pivot_table(index='CarCompany', columns='km_result', values='car_ID', aggfunc=np.count_nonzero).fillna(0)
km_result0123
CarCompany
alfa-romero3.00.00.00.0
audi0.01.06.00.0
bmw8.00.00.00.0
buick4.00.00.04.0
chevrolet0.02.01.00.0
dodge0.05.04.00.0
honda0.07.06.00.0
isuzu0.01.03.00.0
jaguar3.00.00.00.0
mazda5.05.05.02.0
mercury1.00.00.00.0
mitsubishi0.09.04.00.0
nissan3.02.012.01.0
peugeot6.00.00.05.0
plymouth0.03.04.00.0
porsche5.00.00.00.0
renault0.01.01.00.0
saab0.03.03.00.0
subaru2.03.07.00.0
toyota13.03.013.03.0
volkswagen0.00.06.04.0
volvo10.00.00.01.0
vw0.02.00.00.0

# 其竞品
competitons_2type = df_result.loc[df_result['km_result'] == 2]['CarName']
S_temp = ~competitons_2type.str.contains('volkswagen')
competitons_2type = competitons_2type[S_temp]
print('竞品种类数有:{}'.format(competitons_2type.shape[0]))
for competition in competitons_2type:
    print(competition)


"""
竞品种类数有:69
audi 100 ls
audi 100ls
audi fox
audi 100ls
audi 5000
audi 4000
chevrolet vega 2300
dodge monaco (sw)
dodge colt hardtop
dodge colt (sw)
dodge dart custom
honda accord lx
honda civic 1500 gl
honda prelude
honda accord
honda civic
honda civic (auto)
isuzu MU-X
isuzu D-Max 
isuzu D-Max V-Cross
mazda rx-4
mazda glc deluxe
mazda glc custom l
mazda rx-4
mazda 626
mitsubishi montero
mitsubishi pajero
mitsubishi outlander
mitsubishi mirage g4
nissan versa
nissan rogue
nissan latio
nissan titan
nissan leaf
nissan latio
nissan note
nissan rogue
nissan nv200
nissan dayz
nissan fuga
nissan otti
plymouth fury iii
plymouth satellite custom (sw)
plymouth fury gran sedan
plymouth valiant
renault 12tl
saab 99le
saab 99gle
saab 99e
subaru
subaru brz
subaru baja
subaru r1
subaru trezia
subaru tribeca
subaru dl
toyota corolla 1200
toyota corona hardtop
toyota corolla 1600 (sw)
toyota carina
toyota mark ii
toyota corolla 1200
toyota corona
toyota corolla
toyota mark ii
toyota corolla
toyota corona
toyota corolla
toyota mark ii
"""

总结

这篇文章写的有点长了,算是对一个流程的整体分析,下面总结一下自己做的不足的地方吧(也别问我知道有什么不足,为什么不改/doge)

1. 对于车这个具体的产品分析,根据搜查一下资料,很容易发现车大致可以分为可分为微型、普遍级、中级、中高级和高级轿车五种,所以分析的时候,如果把微型车和高级轿车进行比较其实是不合理的。(真正做数据分析,也需要查阅相关文献,我这里也偷懒没做了)

2.去除冗余数据的时候比较暴力,其实需要做更多的资料查询或者实验比较,到底去除哪些可以得到比较好的效果。

3.PCA降维时同上

4.做竞品分析的时候,没有去分析产品的定位(这其实就是第一点留下的问题),虽然聚类完了,但就像前面说的微型车和高级轿车,有可能有些特征都很相似,但两种车是没有比较的必要的。

最后,本文大部分思路只是我借鉴了很多人思路和自己的一些思考,并且自己相关的专业知识并不是很足够,所以会有错的地方,如果有请评论区指正!

  • 20
    点赞
  • 200
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
1. 项目背景 基于项目提供汽车相关数据,通过聚类分析的方法实现汽车产品聚类,以构建汽车产品画像、分析产品定位、完成汽车竞品分析等要求。 2. 项目数据 项目提供汽车数据包括26个字段共205条数据数据文件为“car_price.csv” 26个字段可以划分为类别型变量和数值型变量两种,包括汽车的长/宽/高、汽车净重、燃油系统、燃油类型、驱动类型、峰值转速、里程数、汽车价格等。 3. 项目要求 通过聚类的方法构建汽车产品画像、分析不同类别汽车产品定位,寻找Volkswagen大众汽车的竞品品牌。 4. 项目思路 第一步:数据字段理解 根据项目所提供数据,对数据中26个字段进行理解。结合汽车行业的相关知识,26个字段可以大致归为两类:第一类是车辆自身属性(如燃油系统、燃油类型、汽缸数、峰值转速、汽车长宽高等);第二类是车辆的市场属性(如车辆名称、车辆价格、风险评估等级)。 26个字段主要分为数值型变量和类别型变量两类。 第二步:原始数据描述性统计及变量分布可视化 对原始数据进行描述性统计并对数据中的字段分布进行可视化(详情见主文档)。通过对原始数据的观察,数据不存在缺失值、不存在重复值,“CarName”字段存在部分车辆品牌名称错误的情况。 第三步:确定聚类方法,明确聚类要求 通过对原始数据的变量观察,该数据变量主要为数值型变量和类别型变量两类,且类别型变量数量较多,常用的K-means聚类只能分析数值型变量,无法考虑类别型变量所包含的信息。二阶段聚类法适用于包含数值型和类别型变量的混合数据,因此考虑使用二阶段聚类分析数据。 二阶段聚类法的要求是:类别型变量符合多项式分布(即变量的值分属几个类别);数值型变量间要相互独立,且数值型变量近似服从正态分布。项目所给出的数据中,类别型变量符合多项式分布,因此仅需进一步观察并处理数值型变量。 第四步:特征工程 数据清洗与新变量生成。原始数据指给出了车辆的名称,没有给出车辆所属品牌,结合最终聚类分析的需要,根据“CarName”字段提取出车辆所属品牌信息,命名为“brand”。同时对品牌名称中的错误拼写进行清洗。 变量相关性分析与可视化。由于二阶段聚类要求数值型变量间相互独立,所以需要对数值型变量间的相关性进行查看与处理。相关性分析结果表示14个数值型变量之间存在高相关性情况,需要结合汽车知识背景与变量特征进行进一步处理。 高相关变量的处理——“highwaympg”和“citympg”呈高度正相关。其实不管是高速mpg还是城市mpg,其本质都是mpg指标,而且通过观察数据,二者之间的差异较小(极值、均值),因此考虑将二者合并为一个指标'mpg',计算方式为取二者均值:mpg=(highwaympg+citympg)/2; 高相关性变量的处理——“price”变量与其余变量产生高相关性的频数最多,可能是因为车辆自身属性和配置的变动会直接影响着车辆的市场价格。此外,与其他变量相比,price属性属于车辆的市场销售属性(而非车辆自身属性),在聚类中更适合作为类别型变量,对车辆的价位进行划分,因此,考虑将price变量转换为类别型变量,按照其价格分布划分为Low price(20000)三类; 高相关性变量的处理——对于其余数值型变量,变量数目较多且多个变量之间存在相关性,因此考虑使用因子分析对数值型变量进行降维,以减少数值型变量的数目并使变量间相互独立。 第五步:数值型变量因子分析结果(基于SPSS实现) 利用SPSS对数值型变量进行因子分析,KMO值>0.8,巴特利球形检验p值=0,说明参与因子分析的变量间存在相关性,可以进行因子分析。最终得到两个因子。 第一个因子包括:车长、车宽、车净重、引擎尺寸、车轴距、mpg、马力、车内径比。简单将该因子归纳为车辆截面与马力因子; 第二个因子包括:车高、峰值转速、车压缩比。简单将该因子归纳为车辆垂面与转速因子; 第六步:两阶段聚类及结果(基于SPSS实现) 对处理后的数据进行两阶段聚类,最终将205辆车聚为两类。 根据SPSS聚类结果,第一类中包含120条车辆数据,占总数据的58.5%;第二类中包含85条车辆数据,占总数据的41.5%。两类簇数据规模近似,没有过大或过小的类簇。 根据SPSS聚类结果,聚类质量属于“良好”范围,仍有进一步改进和优化的空间。 根据SPSS聚类结果,显著区分两类类簇的变量(重要性>0.6)按重要性大小排序依次是驱动类型、燃油系统、车辆截面与马力因子、价格范围。 汽车产品画像与产品定位 根据区分类簇的四个重要标签来对数据中的汽车产品进行产品画像与产品定位。 第一类画像:驱动类型多为fwd(前轮驱动),燃油系统多
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzzzzzzm

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值