在集群之前是否有必要对数据进行标准化?在从例如scikit learn
约DBSCAN,在这里他们这样做的线:
X = StandardScaler().fit_transform(X)
但我不明白为什么有必要。归根结底,聚类不假定任何特定的数据分布-它是一种无监督的学习方法,因此其目的是探索数据。
为什么需要转换数据?
在集群之前是否有必要对数据进行标准化?在从例如scikit learn
约DBSCAN,在这里他们这样做的线:
X = StandardScaler().fit_transform(X)
但我不明白为什么有必要。归根结底,聚类不假定任何特定的数据分布-它是一种无监督的学习方法,因此其目的是探索数据。
为什么需要转换数据?
Answers:
并非总是需要规范化,但很少有伤害。
一些例子:
K-均值:
K-均值聚类在空间的所有方向上都是“各向同性的”,因此倾向于产生或多或少的圆形(而不是拉长的)簇。在这种情况下,使方差不相等就等于对方差较小的变量赋予更大的权重。
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将会更加平坦。)
为了避免这种对测量单位选择的依赖,可以选择标准化数据。这会将原始测量值转换为无单位变量。
Kaufman等。继续进行一些有趣的考虑(第11页):
从哲学的角度来看,标准化并不能真正解决问题。实际上,选择测量单位会引起变量的相对权重。以较小的单位表达变量将导致该变量的范围更大,这将对所得结构产生较大影响。另一方面,通过标准化一次尝试赋予所有变量相等的权重,以期达到客观性。这样,它可以由不具备先验知识的从业人员使用。然而,很可能某些变量在特定应用中本质上比其他变量更重要,然后权重的分配应基于主题知识(例如,参见Abrahamowicz,1985)。另一方面,曾有人尝试设计与变量规模无关的聚类技术(Friedman和Rubin,1967)。Hardy and Rasson(1982)的建议是寻找一个分区,以最大程度地减少群集凸包的总体积。原则上,这种方法相对于数据的线性变换是不变的,但是不幸的是,不存在用于其实现的算法(除了限于二维的近似值之外)。因此,标准化的困境目前看来是不可避免的,本书中描述的程序由用户自行选择。Hardy and Rasson(1982)的建议是寻找一个分区,以最大程度地减少群集凸包的总体积。原则上,这种方法相对于数据的线性变换是不变的,但是不幸的是,不存在用于其实现的算法(除了限于二维的近似值之外)。因此,标准化的困境目前看来是不可避免的,本书中描述的程序由用户自行选择。Hardy and Rasson(1982)的建议是寻找一个分区,以最大程度地减少群集凸包的总体积。原则上,这种方法相对于数据的线性变换是不变的,但是不幸的是,不存在用于其实现的算法(除了限于二维的近似值之外)。因此,标准化的困境目前看来是不可避免的,本书中描述的程序由用户自行选择。
建议标准化数据,因为否则,在确定如何对数据进行聚类时,每个要素中的值范围将作为权重,这通常是不希望的。
例如,考虑大多数聚类算法(包括sci-kit learning中的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. ]]
从中您应该看到,非标准化版本之间的欧几里得距离由第三列支配,因为它的值范围比其他两列大得多。但是,当数据标准化后,这将不再成为问题,并且在计算每个数据点之间的距离时,将每个特征加权为相等。
不一定要进行标准化,是否需要标准化可能取决于您选择的距离度量。
例如,如果您选择马氏距离,则分离将基于分离点的标准偏差的数量,而不是它们之间的绝对距离,因此,这是比例不变度量。
与机器学习中的许多事情一样,没有硬性的和快速的答案,唯一可以肯定地知道的方法是应用各种技术,看看能为您的数据提供最合适的结果。
我发现在某些情况下定义“业务评估”功能,定义用于聚类的维度的“重要性”很有用。例如,将蔬菜水果商聚集到顾客那里,如果苹果的价格是橘子的两倍,那么苹果的数量将增加一倍。