是否有必要在集群之前标准化您的数据?在scikit learn
关于 DBSCAN 的示例中,他们在以下行中执行此操作:
X = StandardScaler().fit_transform(X)
但我不明白为什么有必要。毕竟,聚类不假设任何特定的数据分布——它是一种无监督学习方法,因此它的目标是探索数据。
为什么需要转换数据?
是否有必要在集群之前标准化您的数据?在scikit learn
关于 DBSCAN 的示例中,他们在以下行中执行此操作:
X = StandardScaler().fit_transform(X)
但我不明白为什么有必要。毕竟,聚类不假设任何特定的数据分布——它是一种无监督学习方法,因此它的目标是探索数据。
为什么需要转换数据?
标准化并不总是需要,但它很少会造成伤害。
一些例子:
K-均值:
K-means 聚类在空间的所有方向上都是“各向同性的”,因此往往会产生或多或少的圆形(而不是细长的)聚类。在这种情况下,使方差不相等等同于对方差较小的变量赋予更多的权重。
Matlab 中的示例:
X = [randn(100,2)+ones(100,2);...
randn(100,2)-ones(100,2)];
% Introduce denormalization
% X(:, 2) = X(:, 2) * 1000 + 500;
opts = statset('Display','final');
[idx,ctrs] = kmeans(X,2,...
'Distance','city',...
'Replicates',5,...
'Options',opts);
plot(X(idx==1,1),X(idx==1,2),'r.','MarkerSize',12)
hold on
plot(X(idx==2,1),X(idx==2,2),'b.','MarkerSize',12)
plot(ctrs(:,1),ctrs(:,2),'kx',...
'MarkerSize',12,'LineWidth',2)
plot(ctrs(:,1),ctrs(:,2),'ko',...
'MarkerSize',12,'LineWidth',2)
legend('Cluster 1','Cluster 2','Centroids',...
'Location','NW')
title('K-means with normalization')
(仅供参考:我如何检测我的数据集是集群的还是非集群的(即形成一个集群)
比较分析表明,分布式聚类结果取决于归一化过程的类型。
如果输入变量是线性组合的,就像在 MLP 中一样,那么很少有必要对输入进行标准化,至少在理论上是这样。原因是输入向量的任何重新缩放都可以通过更改相应的权重和偏差来有效地撤消,从而使您获得与以前完全相同的输出。然而,标准化输入可以加快训练速度并减少陷入局部最优的机会有多种实际原因。此外,使用标准化输入可以更方便地完成权重衰减和贝叶斯估计。
你应该对你的数据做这些事情吗?答案是,这取决于。
通过改进优化问题的数值条件(参见 ftp://ftp.sas.com/pub/neural/illcond/illcond.html)并确保各种默认初始化和终止中涉及的值是适当的。标准化目标也会影响目标函数。
案例标准化应该谨慎对待,因为它会丢弃信息。如果这些信息无关紧要,那么标准化案例可能会很有帮助。如果这些信息很重要,那么标准化案例可能是灾难性的。
有趣的是,改变测量单位甚至可能导致人们看到一种非常不同的聚类结构:Kaufman、Leonard 和 Peter J. Rousseeuw。“在数据中寻找组:聚类分析简介。” (2005 年)。
在某些应用程序中,更改测量单位甚至可能导致人们看到非常不同的聚类结构。例如,表 3 中给出了四个假想人的年龄(以年为单位)和身高(以厘米为单位)并绘制在图 3 中。看起来 {A, B ) 和 { C, 0) 是两个分离良好的集群. 另一方面,当高度以英尺表示时,可以得到表 4 和图 4,其中明显的簇现在是 {A, C} 和 {B, D}。这个分区与第一个分区完全不同,因为每个主题都收到了另一个同伴。(如果以天为单位来衡量年龄,图 4 会更加扁平。)
为了避免这种对测量单位选择的依赖,可以选择对数据进行标准化。这会将原始测量值转换为无单位变量。
考夫曼等人。继续一些有趣的考虑(第 11 页):
从哲学的角度来看,标准化并不能真正解决问题。实际上,测量单位的选择会产生变量的相对权重。以较小的单位表示变量将导致该变量的范围更大,这将对最终的结构产生很大的影响。另一方面,通过标准化尝试赋予所有变量同等权重,以期实现客观性。因此,它可以由没有先验知识的从业者使用。然而,很可能某些变量在特定应用中本质上比其他变量更重要,然后权重的分配应该基于主题知识(例如,参见 Abrahamowicz,1985)。另一方面,已经尝试设计独立于变量规模的聚类技术(弗里德曼和鲁宾,1967)。Hardy 和 Rasson (1982) 的建议是寻找一个最小化集群凸包总体积的分区。原则上,这种方法对于数据的线性变换是不变的,但不幸的是,不存在用于其实现的算法(除了限于二维的近似值)。因此,标准化的困境在目前看来是不可避免的,本书中描述的程序将选择权留给了用户。Hardy 和 Rasson (1982) 的建议是寻找一个最小化集群凸包总体积的分区。原则上,这种方法对于数据的线性变换是不变的,但不幸的是,不存在用于其实现的算法(除了限于二维的近似值)。因此,标准化的困境在目前看来是不可避免的,本书中描述的程序将选择权留给了用户。Hardy 和 Rasson (1982) 的建议是寻找一个最小化集群凸包总体积的分区。原则上,这种方法对于数据的线性变换是不变的,但不幸的是,不存在用于其实现的算法(除了限于二维的近似值)。因此,标准化的困境在目前看来是不可避免的,本书中描述的程序将选择权留给了用户。
建议对数据进行标准化,因为否则在确定如何对数据进行聚类时,每个特征中的值范围将充当权重,这通常是不希望的。
例如,考虑大多数聚类算法(包括 sci-kit learn 中的 DBSCAN)的标准度量euclidean
,也称为 L2 规范。如果您的一个特征具有比其他特征大得多的值范围,则聚类将完全由该特征主导。为了说明这一点,请看下面的简单示例:
>>> import numpy as np
>>> from sklearn.preprocessing import StandardScaler
>>> from sklearn.metrics.pairwise import euclidean_distances
>>>
>>> X = np.array([[1,2,100],[4,3,50],[1,1,75]])
>>>
>>> print X
[[ 1 2 100]
[ 4 3 50]
[ 1 1 75]]
>>>
>>> print euclidean_distances(X)
[[ 0. 50.0999002 25.01999201]
[ 50.0999002 0. 25.25866188]
[ 25.01999201 25.25866188 0. ]]
>>> print euclidean_distances(StandardScaler().fit_transform(X))
[[ 0. 3.46410162 1.73205081]
[ 3.46410162 0. 3.46410162]
[ 1.73205081 3.46410162 0. ]]
从这里你应该看到非标准化版本之间的欧几里得距离由第三列控制,因为它的值范围比其他两列大得多。但是,当数据标准化后,这不再成为问题,并且在计算每个数据点之间的距离时将每个特征加权为相等。
标准化并不是绝对必要的,是否需要标准化可能取决于您选择的距离度量。
例如,如果您选择马氏距离,那么分离将基于标准偏差分离点的数量,而不是它们之间的绝对距离,因此它是一个尺度不变的度量。
与机器学习中的许多事情一样,没有硬性和快速的答案,唯一确定的方法是应用各种技术,看看哪种技术可以为您的数据提供最合适的结果。
我发现在某些情况下定义“业务评估”功能很有用,定义了用于聚类的维度的“重要性”。例如,对于蔬菜水果商将顾客聚集在一起,如果苹果的价格是橙子的两倍,那么苹果的数量将翻倍。