我目前正在参加IBM提供的机器学习基础课程。在老师完成模型构建后,我注意到他没有使用归一化数据来拟合模型,而是使用了常规数据,最终得到了一个好的聚类和不重叠的聚类。但是当我尝试使用归一化数据来训练模型时,我得到了一个灾难性的结果,并且得到了嵌套的聚类,正如代码和图片所示。为什么归一化过程会导致这种情况?虽然据我所知,在数学基础算法中使用归一化总是好的。
代码不使用归一化数据
import numpy as npimport matplotlib.pyplot as plt%matplotlib inlinefrom sklearn.cluster import KMeanscust_df = pd.read_csv('D:\machine learning\Cust_Segmentation.csv')cust_df.head()df = cust_df.drop('Address', axis = 1)X = df.values[:, 1:]X = np.nan_to_num(X)from sklearn.preprocessing import StandardScalernorm_featur = StandardScaler().fit_transform(X)clusterNum = 3kmeans = KMeans(init = 'k-means++', n_clusters = clusterNum, n_init = 12)kmeans.fit(X)k_means_labels = kmeans.labels_df['cluster'] = kmeans.labels_k_means_cluster_centers = kmeans.cluster_centers_area = np.pi * ( X[:, 1])**2 plt.scatter(X[:, 0], X[:, 3], s=area, c=kmeans.labels_.astype(np.float), alpha=0.5)plt.xlabel('Age', fontsize=18)plt.ylabel('Income', fontsize=16)plt.show()
使用归一化数据的代码
import numpy as npimport matplotlib.pyplot as plt%matplotlib inlinefrom sklearn.cluster import KMeanscust_df = pd.read_csv('D:\machine learning\Cust_Segmentation.csv')cust_df.head()df = cust_df.drop('Address', axis = 1)X = df.values[:, 1:]X = np.nan_to_num(X)from sklearn.preprocessing import StandardScalernorm_feature = StandardScaler().fit_transform(X)clusterNum = 3kmeans = KMeans(init = 'k-means++', n_clusters = clusterNum, n_init = 12)kmeans.fit(norm_feature)k_means_labels = kmeans.labels_df['cluster'] = kmeans.labels_k_means_cluster_centers = kmeans.cluster_centers_area = np.pi * ( norm_feature[:, 1])**2 plt.scatter(norm_feature[:, 0], norm_feature[:, 3], s=area, c=kmeans.labels_.astype(np.float), alpha=0.5)plt.xlabel('Age', fontsize=18)plt.ylabel('Income', fontsize=16)plt.show()
回答:
在这里,收入和年龄的尺度相当不同。在你的第一个图表中,收入的差异大约为100时,与年龄的差异大约为10时是相同的。但在k-means中,收入的差异被认为是10倍大。垂直轴很容易主导聚类过程。
这可能是“错误的”,除非你碰巧认为收入的1单位变化“与”年龄的10单位变化“相同”,为了确定什么是相似的。这就是你进行标准化的原因,这做出了一个不同的假设:它们同样重要。
你的第二个图表不太合理;k-means不能产生“重叠”的聚类。问题是你只绘制了你聚类用的4个(?)维度中的2个。你无法绘制4D数据,但我怀疑如果你先对结果应用PCA以降低到2维然后绘制,你会看到分离的聚类。