不请自来:)
先回答你的问题,再顺道谈谈以K-means为原型的几种针对不同数据类型的聚类算法。
问题一:该算法要求训练数据中都是正向数据,如果训练数据中包含了异常数据,会导致阈值的值过大,从而异常测试数据进来时可能会漏报。 现实中我们很难保证训练数据中没有异常数据,那在训练过程中有没有什么方法可以减少异常数据对训练结果的干扰?(例如可视化后肉眼识别一些离群的数据点,并把它们从样本中去除?或者按比例缩小阈值?)
我的看法:聚类本身就是最常用的异常值检测方法,大部分非监督的异常值检测都依靠聚类。离群值(异常值)对非监督聚类的影响很明显,因为需要一边学习簇的特征,一边防止异常值的干扰。
并不是每一种聚类都擅长异常值检测:K-means和层次聚类(hierarchical clustering)对离群值非常敏感,因为其要求将每个点都划分到一个簇中(此处我们默认的K-means是hard assignment)。而且其相似度度量(Similarity Measure)默认是sum of euclidean squares,优化目标是将簇内差异最小化(minimize with-in clustering variation),因此即使单个噪音点也可以对整个簇造成很大的扰动。 常见的解决方法有:
- 改用密度聚类(Density based clustering)。这样可以同时优化簇内的紧密度(最小化inter-cluster density)和簇之间的离散度(最大化intra-cluster density)。此时的目标函数 ,超过一定阈值的点可以被标记为异常值。
- 使用混合模型(Finite Mixture Models)或者Soft K-means。人民群众喜闻乐见的算法包括高斯混合模型 (Gaussian Mixture Models),从本质上说Soft K-means是一种高斯混合模型的特例。
- 也可以通过对K-means的聚类结果做统计测试,设定p-value来决定聚类结果是否显著,同时通过这个方法来去除每个簇中的异常值。然而这个方法有局限性,因为它的假设前提是当前的聚类结果是正确的,而你去除的异常值可能别的簇中的正常值。
问题二:在特征提取过程中对于一些离散值,我们会采用独热编码将其转换为一个固定长度的向量,这个长度是根据数据集中该字段的所有值计算出来的(不同的值个数)。例如有个特征叫部门,样本数据里有研发、测试、HR三种值,独热编码后就会转换为一个3维的向量,[100][010][001],这是遍历了整个样本集后得出的向量长度。如果新来了一条测试数据,部门为研发,我怎么根据这一条数据将研发这个特征值转换为[100]向量,从而保证训练和测试的特征数据维度一致。如果测试数据的部门值为财务,财务这个值不在训练集中,这种情况又怎么处理呢?我的看法:聚类问题中的特征工程不单纯是将离散变量转化为连续变量这么简单,独热编码要慎用。特征转化中包含了多种假设需要考虑,至少要确保在转化过程中不丢失信息。本题中你直接转化为独热编码就不是一个很好的方法,原因就是...先不谈聚类中的距离(distance)在高维度中会丧失意义,只说任意两点在“部门”这个维度上的几何距离都是 ,因此相当于你人为的损失了信息。假设我有A,B,C三个点分别是[100],[010],[001],那么单纯看几何距离,我只能知道如果两点相同应该为0,如果不同距离应该为 。但你并不知道这两个点是A和B,还是B和C。
在未转换前我们有这个信息,但你转换为我们无法再区分,因此这就是信息损失。为什么独热编码在这里不再好用?因为我们使用了距离度量,也就是最终我们将一堆距离相加,而不是像决策树那样分开对待。----------------------------------------------------------------------一般我们在做聚类前做变量处理的方法如下:- 如果一个变量/特征是连续实数,那么大部分时候我们不做特别的处理。在特定的情况下,我们会做standardization或者normalization。
- 如果是离散变量,一般分两种:
- 有序变量。比如小学,初中,高中,大学。又比如非常满意,满意,不满意,极不满意。这类变量中的可取值之间都有一种顺序关系,因此不能单纯的用 One-hot Encoding,也就是题主提到的独热编码来转化,因为在转化过程中会失去一部分有用的信息。在这种情况下可以由来转换 N代表该变量可取的值得总数。此处也要注意,不是每种顺序都是有意义的。比如假设一个变量可以取三个值:“头等舱”,“商务舱”,“经济舱”,对于票价而言是有顺序的,但对于到达时间,这三者是无序的(请不要非说头等舱可以先下飞机....蟹蟹)
- 无序变量。如题主描述的研发,测试,HR,我们一般希望度量其差异性,比较常见的是像@呼广跃 提到的Value Difference Metrics (VDM)这一类。说白了就是直接看两个点的这个维度是否相同,若有N个无序变量,我们一般构建一个 的矩阵来描述差异度(Degree of Difference)。
- 对连续变量和离散变量都经过处理以后,就需要将各个变量合并来生成目标函数。在做这件事情前,有几点需要考虑:
- 是否每个变量的重要性都一样,即是否权重相同。假设有N个变量, 。虽然我们一般默认相等的 可以保证每个变量对聚类的影响相同,但这假设不严谨。举例,若聚类中有两个变量,其中变量1在所有数据点中取值都相同,即使你使得 ,其对于聚类的贡献值依然为0。不过在大部分时候,可以简单粗暴的使用等权重。别忘了,我们还有调参工程...
- 此时我们定义新的目标函数为 。C为连续变量的度量函数,如Euclidean Distance Square。而D为离散变量的度量函数,如Value Difference Metrics。还可以再在函数C和D中分别定义不同的变量权重,甚至在O中给C和D不同的权重。这些权重取决于我们对任务的了解,若一切未知可不赋值。
说了这么多,有没有简单一些,不需要整这么多花样的的方法...?答案是,还真有,在你了解问题的前提下可以愉快的掉包!我个人比较推荐的方法叫做 K-prototypes[1],该方法就是一个基于K-means比较完整的处理混合数据类型(连续 离散)的算法,基本的思路和我上面描述的是一样的:)
所以基于K-means这种思路的算法:- 处理连续变量的有K-means和K-means [2]
- 处理categorical变量的有K-modes[3]
- 处理混合变量的有K-prototypes
K-means和K-means 在python机器学习库sklearn中都有实现,K-modes和K-prototypes在GitHub和pipy上都有现成的库(https://pypi.python.org/pypi/kmodes/)不多说了,我去继续炼丹了(滑稽)...(?????)
#知乎的公式编辑器简直反人类#
---------------------------------------------------------------------------------------------------------
[1] Huang, Zhexue. "Extensions to the k-means algorithm for clustering large data sets with categorical values."
Data mining and knowledge discovery 2.3 (1998): 283-304.
[2] Arthur, David, and Sergei Vassilvitskii. "k-means : The advantages of careful seeding."
Proceedings of the eighteenth annual ACM-SIAM symposium on Discrete algorithms. Society for Industrial and Applied Mathematics, 2007.
[3] Huang, Zhexue, and Michael K. Ng. "A fuzzy k-modes algorithm for clustering categorical data."
IEEE Transactions on Fuzzy Systems 7.4 (1999): 446-452.