【算法竞赛学习】数据分析达人赛3:汽车产品聚类分析
賽題背景
賽題以競品分析為背景,通過數據的聚類,為汽車提供聚類分類。對于指定的車型,可以通過聚類分析找到其競品車型。通過這道賽題,鼓勵學習者利用車型數據,進行車型畫像的分析,為產品的定位,競品分析提供數據決策。
賽題數據
數據源:car_price.csv,數據包括了205款車的26個字段
https://tianchi.aliyun.com/competition/entrance/531892/information
賽題任務
選手需要對該汽車數據進行聚類分析,并找到vokswagen汽車的相應競品。要求選手在天池實驗室中用notebook完成以上任務,并分享到比賽論壇。(聚類分析是常用的數據分析方法之一,不僅可以幫助我們對用戶進行分組,還可以幫我們對產品進行分組(比如競品分析) 這里的聚類個數選手可以根據數據集的特點自己指定,并說明聚類的依據)
一、數據探索
-
了解數據類型及基本情況
-
數據質量檢查:主要包括檢查數據中是否有錯誤,如拼寫有誤等
-
對空值、重復值、異常值等檢測
數據集中共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']=car_price.cylindernumber.replace({'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()
從上面數據看,數據集不存在違背常理的異常值
由各特征的箱線圖可知,部分特征存在離群點,但不存在特別明顯的離群點,可接受。
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中的錯誤,只在導出的品牌名中修改)
#修改品牌名稱的不規則命名 carBrand=carBrand.replace({'porcshce':'porsche','vokswagen':'volkswagen','Nissan':'nissan','maxda':'mazda','vw':'volkswagen','toyouta':'toyota'}) print(set(carBrand))#將carBrand放入原數據集中 car_price['carBrand']=carBrand1.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=car_df.corr() df_corr #繪制相關性熱力圖 mask=np.zeros_like(df_corr) mask[np.triu_indices_from(mask)]=True plt.figure(figsize=(10,10)) with sns.axes_style("white"):ax=sns.heatmap(df_corr,mask=mask,square=True,annot=True,cmap='bwr') ax.set_title("df_corr Variables Relation") plt.show()
相關系數分類: 0.8-1.0 極強相關;0.6-0.8 強相關;0.4-0.6 中等程度相關;0.2-0.4 弱相關;0.0-0.2 極弱相關或無相關
由上面熱力圖可看出: 車長、寬、軸距三者都極強相關,整備質量和車長、寬、發動機尺寸極強相關,價格與車整備質量、發動機尺寸、馬力具有極強相關性,等等。部分數據之間存在高度相似,數據存在冗余。
二、數據預處理
2.1 篩選合適的變量特征
carSize可代表車型大小,剔除carlength
#剔除carlength features=car_df.drop(['carlength'],axis=1)2.2 對類別型變量進行數值映射和one-hot編碼
# 將取值具有大小意義的類別型變量數據轉變為數值型映射 features1=features.copy()#使用LabelEncoder對不具實體數值數據編碼 from sklearn.preprocessing import LabelEncoder carSize1=LabelEncoder().fit_transform(features1['carSize']) features1['carSize']=carSize1 #對于類別離散型特征,取值間沒有大小意義的,可采用one-hot編碼 cate=features1.select_dtypes(include='object').columns print(cate)features1=features1.join(pd.get_dummies(features1[cate])).drop(cate,axis=1) features1.head()
對數值型數據進行one-hot編碼后,數據變量由原來24列變為47列,維度變大。
2.3 對數值型變量標準化
數據變量之間存在量級的差異,需要進行數據標準化
#對數值型數據進行歸一化 from sklearn import preprocessingfeatures1=preprocessing.MinMaxScaler().fit_transform(features1) features1=pd.DataFrame(features1) features1.head()2.4 利用PCA對高維數據進行降維
目的:在‘信息’損失較小的前提下,將高維數據轉換到低維,從而減少計算量。把可能具有線性相關的高維變量合成線性無關的低維變量,成為主成分。保留最大的方差方向,使從變換特征回到原始特征的誤差最小。
#對數據集進行PCA降維(信息保留為99.99%) from sklearn.decomposition import PCA pca=PCA(n_components=0.9999) #保證降維后的數據保持90%的信息,則填0.9 features2=pca.fit_transform(features1)#降維后,每個主要成分的解釋方差占比(解釋PC攜帶的信息多少) ratio=pca.explained_variance_ratio_ print('各主成分的解釋方差占比:',ratio)#降維后有幾個成分 print('降維后有幾個成分:',len(ratio))#累計解釋方差占比 cum_ratio=np.cumsum(ratio) print('累計解釋方差占比:',cum_ratio) #繪制PCA降維后各成分方差占比的直方圖和累計方差占比折線圖 plt.figure(figsize=(8,6)) X=range(1,len(ratio)+1) Y=ratio plt.bar(X,Y,edgecolor='black') plt.plot(X,Y,'r.-') plt.plot(X,cum_ratio,'b.-') plt.ylabel('explained_variance_ratio') plt.xlabel('PCA') plt.show()
藍色折線為累計方差占比。 降維后,選擇幾個維度表示原數據集的特征更合適: 一般會根據帕累托的二八原則,選擇累計解釋方差大于80%的前幾個成分。根據藍色折線圖各成分的累計方差占比看出,當選取保留8個主要成分時,累計解釋方差大于80%。
降維后,解釋PC有效信息保留約81%。
三、K-Means聚類模型應用
3.1 利用肘方法確定簇的最佳數量
K-Means沒有確定k值,可以通過肘部法來估計聚類數量
手肘法的核心指標是SSE(sum of the squared errors,誤差平方和)
隨著聚類數k的增大,樣本劃分會更加精細,每個簇的聚合程度會逐漸提高,那么誤差平方和SSE自然會逐漸變小。并且,當k小于真實聚類數時,由于k的增大會大幅增加每個簇的聚合程度,故SSE的下降幅度會很大,而當k到達真實聚類數時,再增加k所得到的聚合程度回報會迅速變小,所以SSE的下降幅度會驟減,然后隨著k值的繼續增大而趨于平緩,也就是說SSE和k的關系圖是一個手肘的形狀。(下降率突然變緩時即認為是最佳的k值)
##肘方法看k值,簇內離差平方和 #對每一個k值進行聚類并且記下對于的SSE,然后畫出k和SSE的關系圖 from sklearn.cluster import KMeanssse=[] for i in range(1,15):km=KMeans(n_clusters=i,init='k-means++',n_init=10,max_iter=300,random_state=0)km.fit(features3)sse.append(km.inertia_)plt.plot(range(1,15),sse,marker='*') plt.xlabel('n_clusters') plt.ylabel('distortions') plt.title("The Elbow Method") plt.show()
由上面肘方圖可以看到,拐點在k=5處,所以k的取值為5.
3.2 應用K-Means聚類模型
#進行K-Means聚類分析 kmeans=KMeans(n_clusters=5,init='k-means++',n_init=10,max_iter=300,random_state=0) kmeans.fit(features3) lab=kmeans.predict(features3) print(lab)3.3 對聚類效果評估
3.3.1 查看聚類后的效果
通過繪制聚類后結果的散點圖,查看每簇間距離效果
#繪制聚類結果2維的散點圖 plt.figure(figsize=(8,8)) plt.scatter(features3[:,0],features3[:,1],c=lab) for ii in np.arange(205):plt.text(features3[ii,0],features3[ii,1],s=car_price.car_ID[ii]) plt.xlabel('PC1') plt.ylabel('PC2') plt.title('K-Means PCA') plt.show()
上面以占比最大的前2個主成分畫出的二維散點圖,發現右下藍色這簇部分聚類點距離很遠,效果似乎不是很好;而其他四簇效果還好。 考慮到保留的主成分為8個,且前兩個主成分累計可解釋方差占比僅約為44%,損失信息較多,所以嘗試利用前3個主成分畫3d效果圖再查看。
3d散點圖看,聚類各簇的效果還好
3.3.2 利用輪廓系數評估聚類效果
肘圖選擇k值是比較直觀但較為粗糙的方法。使用輪廓分數,即所有實例的平均輪廓系數來選擇k值更為精確。該方法的核心指標是輪廓系數(Silhouette Coefficient),求出所有樣本的輪廓系數后再求平均值就得到了平均輪廓系數。
平均輪廓系數的取值范圍為[-1,1]:接近+1點系數表示該實例很好地位于自身的集群中,并且遠離其他集群;而接近0點系數表示該實例接近一個集群的邊界;接近-1點系數,意味著該實例已分配給錯誤的集群。
簇內樣本的距離越近,簇間樣本距離越遠,平均輪廓系數越大,聚類效果越好。
#繪制輪廓圖和3d散點圖 from sklearn.datasets import make_blobs from sklearn.metrics import silhouette_samples, silhouette_score import matplotlib.cm as cm from mpl_toolkits.mplot3d import Axes3Dfor n_clusters in range(2,9):fig=plt.figure(figsize=(12,6))ax1=fig.add_subplot(121)ax2=fig.add_subplot(122,projection='3d')ax1.set_xlim([-0.1,1])ax1.set_ylim([0,len(features3)+(n_clusters+1)*10])km=KMeans(n_clusters=n_clusters,init='k-means++',n_init=10,max_iter=300,random_state=0)y_km=km.fit_predict(features3)silhouette_avg=silhouette_score(features3,y_km)print('n_cluster=',n_clusters,'The average silhouette_score is :',silhouette_avg)cluster_labels=np.unique(y_km) silhouette_vals=silhouette_samples(features3,y_km,metric='euclidean')y_ax_lower=10for i in range(n_clusters):c_silhouette_vals=silhouette_vals[y_km==i]c_silhouette_vals.sort()cluster_i=c_silhouette_vals.shape[0]y_ax_upper=y_ax_lower+cluster_icolor=cm.nipy_spectral(float(i)/n_clusters)ax1.fill_betweenx(range(y_ax_lower,y_ax_upper),0,c_silhouette_vals,edgecolor='none',color=color)ax1.text(-0.05,y_ax_lower+0.5*cluster_i,str(i))y_ax_lower=y_ax_upper+10ax1.set_title('The silhouette plot for the various clusters')ax1.set_xlabel('The silhouette coefficient values')ax1.set_ylabel('Cluster label')ax1.axvline(x=silhouette_avg,color='red',linestyle='--')ax1.set_yticks([])ax1.set_xticks([-0.1,0,0.2,0.4,0.6,0.8,1.0])colors=cm.nipy_spectral(y_km.astype(float)/n_clusters)ax2.scatter(features3[:,0],features3[:,1],features3[:,2],marker='.',s=30,lw=0,alpha=0.7,c=colors,edgecolor='k')centers=km.cluster_centers_ax2.scatter(centers[:,0],centers[:,1],centers[:,2],marker='o',c='white',alpha=1,s=200,edgecolor='k')for i,c in enumerate(centers):ax2.scatter(c[0],c[1],c[2],marker='$%d$' % i,alpha=1,s=50,edgecolor='k')ax2.set_title("The visualization of the clustered data.")ax2.set_xlabel("Feature space for the 1st feature")ax2.set_ylabel("Feature space for the 2nd feature")ax2.view_init(30,45)plt.suptitle(("Silhouette analysis for KMeans clustering on sample data ""with n_clusters = %d" % n_clusters),fontsize=14, fontweight='bold') plt.show()
結合輪廓圖和3d散點圖: 當k太小時,單獨的集群會合并;而當k太大時,某些集群會被分成多個。
當k=2,每個集群很大且很大部分實例系數接近0,表明集群內很大部分實例接近邊界,一些單獨的集群被合并了,模型效果不好;
當k=3時,集群‘0’大部分實例輪廓系數低于集群的輪廓分數,且有小部分實例系數小于0趨向-1,說明該部分實例可能已分配給錯誤的集群;
k=4時,集群‘0’大部分實例輪廓系數低于集群的輪廓分數且接近0,說明這些實例接近邊界,該集群可能分為2個單獨集群更合適;
k=7或8時,某些集群被分成多個,中心非常接近,導致非常糟糕的模型;
當k為5或6時,大多數實例都超出虛線,集群看起來很好,聚類效果都很好。按得分排k更佳是6>5,當k=5時,集群‘3’很大,k=6時,各個集群分布更均衡一些;
綜上所述,k值選取5或6都可以,聚類模型效果都可以,但考慮各集群均衡些,所以選取k=6。
#調整選擇k=6進行聚類 kmeans=KMeans(n_clusters=6,init='k-means++',n_init=10,max_iter=300,random_state=0) y_pred=kmeans.fit_predict(features3) print(y_pred)#將聚類后的類目放入原特征數據中 car_df_km=car_price.copy() car_df_km['km_result']=y_pred四、聚類結果展示
4.1 聚類結果統計
#統計聚類后每個集群的車型數 car_df_km.groupby('km_result')['car_ID'].count() #統計每個集群各個品牌的車型數 car_df_km.groupby(by=['km_result','carBrand'])['car_ID'].count() #統計每個品牌所屬各個集群的車型數 car_df_km.groupby(by=['carBrand','km_result'])['km_result'].count()4.2 提取Volkswagen的競品
Volkswagen對應同一個集群內的其他車型,均為其競品
1、找出特指’vokswagen’的車型同一集群的車型
2、若’vokswagen’不為特指,而是拼寫錯誤;那需要找出大眾volkswagen品牌同一集群的其他車型(由上面的統計可知,volkswagen大眾品牌所屬的分類有0、1、2類,然后各分類中同一類型的車型為競品)
#查看特指車名‘vokswagen’車型的聚類集群 df=car_df_km.loc[:,['car_ID','CarName','carBrand','km_result']] print(df.loc[df['CarName'].str.contains("vokswagen")])’vokswagen’的車名為‘vokswagen rabbit’,car_ID 為183,集群分類為0.
#查看特指車名為‘vokswagen’車型的競品車型(分類0的所有車型) df.loc[df['km_result']==0] #查看大眾volkswagen品牌各集群內的競品車型 df_volk=df.loc[df['km_result']<3].sort_values(by=['km_result','carBrand']) df_volk4.3 對’vokswagen’車型的競品分析
這里主要針對特指‘vokswagen’車型的競品分析,若要分析‘Volkswagen’大眾品牌的也可同理按每個集群進行分析
#提取分類為0的所有車型特征數據 df0=car_df_km.loc[car_df_km['km_result']==0] df0.head() df0_1=df0.drop(['car_ID','CarName','km_result'],axis=1)#查看集群0的車型所有特征分布 fig=plt.figure(figsize=(20,20)) i=1 for c in df0_1.columns:ax=fig.add_subplot(7,4,i)if df0_1[c].dtypes=='int' or df0_1[c].dtypes=='float':sns.histplot(df0_1[c],ax=ax)else:sns.barplot(df0_1[c].value_counts().index,df0_1[c].value_counts(),ax=ax)i=i+1plt.xlabel('')plt.title(c) plt.subplots_adjust(top=1.2) plt.show()
由集群0的變量特征分布圖可知,類別型變量取值只有一種的有:fueltype : {‘diesel’};enginelocation : {‘front’};fuelsystem : {‘idi’};這些共性的特征在競品分析時可不考慮。
根據乘用車的汽車用戶需求特點,一般首先會考慮車型大小級別;而乘用車的對比也是基于同等級別的車型大小進行(如,不可能拿一個D級豪華型車與A級緊湊型車來對比的)。
#對不同車型級別、品牌、車身等類型特征進行數據透視 df2=df0.pivot_table(index=['carSize','carbody','carBrand','CarName']) df2
數據透視可知,集群0中所有的車型大小級別為:A0小型車、A緊湊型車、B中型車、C中大型車、D豪華型車; 而car_ID為183的‘vokswagen rabbit’屬于A級緊湊型車,所以它最直接的細分競品為集群0中的A級車中的其他6輛。
集群0中A級車型這7款車中,所屬品牌分別為:大眾(3輛)、馬自達(2輛)、豐田(1輛),其中所有車型車身均為‘sedan’,燃料類型均為柴油,發動機均為前置,發動機型號均為‘ohc’,燃油系統均為‘idi’;只有‘mazda rx-7 gs’車型發動機為前置后驅動,其他6款均為前置前驅;另外,只有目標車型‘vokswagen rabbit’為雙開門的三廂車,其他車型的為四開門的三廂車。
包含‘vokswagen rabbit’在內的7輛A級車中均有4個氣缸,沖程范圍在3.4-3.64,最大功率轉速范圍在4500-4800,壓縮比范圍在22.5-23.0,車身寬范圍66.1-66.9,車高范圍在54.4-55.7,氣缸橫截面面積與沖程比范圍在3.01-3.43;以上這些數據都是比較相似的。
一般汽車關注點在:車型級別(carSize)、品牌(carBrand)、動力性能(馬力horsepower)、質量安全(Symboling )、油耗(citympg、highwaympg)、空間體驗(軸距wheelbase)、車身(carbody、curbweight) 等等。
下面提取其他一些不同關鍵特征進行考量‘vokswagen rabbit’與其他競品之間的差異化:
基本信息:‘carBrand’,‘doornumber’, ‘curbweight’
油耗:‘highwaympg’、‘citympg’
安全性:‘symboling’
底盤制動:‘drivewheel’
動力性能:‘aspiration’, ‘enginesize’, ‘horsepower’
空間體驗:‘wheelbase’
價格: ‘price’
#對油耗的分析('citympg','highwaympg') lab=df0_A['CarName']fig,ax=plt.subplots(figsize=(10,8)) ax.barh(range(len(lab)),df0_A['highwaympg'],tick_label=lab,color='red') ax.barh(range(len(lab)),df0_A['citympg'],tick_label=lab,color='blue') for i,(highway,city) in enumerate(zip(df0_A['highwaympg'],df0_A['citympg'])):ax.text(highway,i,highway,ha='right')ax.text(city,i,city,ha='right')plt.legend(('highwaympg','citympg'), loc='upper right') plt.title('miles per gallon') plt.show()
’vokswagen rabbit‘車的油耗與‘Volkswagen model 111’一樣,在7款車中并列最低,其在高速公路上每加侖油可跑46英里,而在城市這種交通比較繁忙糟糕的環境每加侖油可跑37英里,比最低的‘toyota celica gt’多了7英里;可見其油耗較其他款車型低。
由上面條形圖,‘vokswagen rabbit’與其他競品相比:
質量安全方面:其保險風險評級為2,比馬自達品牌和豐田品牌車型相對更具有風險;
車身空間方面:軸距是最小的;
動力方面:發動機尺寸和馬力都是最小的;
車重方面:整備質量最小的;
價格方面:價格是最小的;
4.4 總結和建議
綜上所述,‘'vokswagen rabbit‘’與集群0中同是A級的競品相比:
劣勢:質量安全性偏低、車身空間偏小、動力馬力偏小
優勢:車身輕、油耗低、價格低(在類似的配置中性價比非常高)
設計特點:雙車門三廂車
產品定位:“經濟適用、城市代步緊湊型A級轎車”
建議: 在銷售推廣時,可偏重于:①同類配置車型中超高的性價比;②油耗低,城市代步非常省油省錢;③車身小巧,停車方便;④雙車門設計,個性獨特
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎總結
以上是生活随笔為你收集整理的【算法竞赛学习】数据分析达人赛3:汽车产品聚类分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 不能换电的子品牌,可以帮蔚来卖更多的车吗
- 下一篇: 天猫宝和余额宝有什么区别?天猫宝和余额宝