scikit learn - 如何对由多个独立值组成的单个特征进行建模
scikitlearn - how to model a single features composed of multiple independant values
我的数据集由数百万行和几个(10 个)特征组成。
一个特征是由 1000 个不同值组成的标签(想象每一行都是一个用户,这个特征是用户的名字:
Firstname,Feature1,Feature2,....
Quentin,1,2
Marc,0,2
Gaby,1,0
Quentin,1,0
什么是此功能的最佳表示(以执行聚类):
我可以使用 LabelEncoder
将数据转换为整数,但这在这里没有意义,因为两个不同的标签 [=26] 之间没有逻辑 "order" =]
Firstname,F1,F2,....
0,1,2
1,0,2
2,1,0
0,1,0
我可以将特征拆分为 1000 个特征(每个标签一个),当标签匹配时为 1,否则为 0。然而,这会导致一个非常大的矩阵(如果我不能在我的分类器中使用稀疏矩阵,那就太大了)
Quentin,Marc,Gaby,F1,F2,....
1,0,0,1,2
0,1,0,0,2
0,0,1,1,0
1,0,0,1,0
我可以将 LabelEncoder
值表示为 N 列中的二进制,与之前的想法相比,这会减少最终矩阵的维数,但我不确定结果:
LabelEncoder(Quentin) = 0 = 0,0
LabelEncoder(Marc) = 1 = 0,1
LabelEncoder(Gaby) = 2 = 1,0
A,B,F1,F2,....
0,0,1,2
0,1,0,2
1,0,1,0
0,0,1,0
...还有其他想法吗?
您如何看待解决方案 3?
编辑一些额外的解释
我应该在我的第一个 post 中提到,但在真实数据集中,该特征更像是分类树的最后一片叶子(Aa1
、Aa2
等. 在示例中 - 它不是二叉树)。
A B C
Aa Ab Ba Bb Ca Cb
Aa1 Aa2 Ab1 Ab2 Ab3 Ba1 Ba2 Bb1 Bb2 Ca1 Ca2 Cb1 Cb2
所以同一水平下的2个词之间有相似性(Aa1
Aa2
和Aa3
非常相似,而Aa1
与Ba1
比 Cb2
).
最终目标是从较小的数据集中找到相似的实体:我们在较小的数据集上训练OneClassSVM
,然后得到整个数据集的每个术语的距离
方案三:
我会说它具有与使用 1..N
编码(解决方案 1)相同的缺点,但不太明显。您的名称在某些列中都给出 1,除了编码顺序外没有其他原因...
所以我不建议这样做。
解决方案 1:
1..N
解决方案是解决格式问题的 "easy way",正如您所指出的,它可能不是最好的。
解决方案 2:
这看起来是最好的方法,但它有点麻烦,而且根据我的经验,分类器在处理大量类别时并不总是表现很好。
解4+:
我认为编码取决于你想要什么:如果你认为相似的名字(比如 John 和 Johnny)应该很接近,你可以使用 characters-grams 来表示它们。不过,我怀疑您的应用程序是否属于这种情况。
另一种方法是使用名称在(训练)数据集中的频率对名称进行编码。这样你说的是:"Mainstream people should be close, whether they're Sophia or Jackson does not matter".
希望这些建议能有所帮助,对此没有明确的答案,所以我很期待看到其他人的做法。
此问题主要是单热编码问题之一。我们如何以可以使用聚类算法的方式表示多个分类值,并且 而不是 搞砸你的算法需要做的距离计算(你可以使用某种概率有限混合模型,但我离题了)?和user3914041的回答一样,确实没有确定的答案,但是我会把你提出的每一个解决方案都看一遍,并给出我的印象:
解决方案 1
如果您像您提到的那样将分类列转换为数字列,那么您将面临您提到的那个相当大的问题:您基本上失去了该列的意义。如果 Quentin 在 0、Marc 1 和 Gaby 2 中,这到底意味着什么?到那时,为什么还要将该列包括在集群中?与 user3914041 的回答一样,这是将分类值更改为数值的最简单方法,但它们 没有用 ,并且可能对聚类结果有害。
解决方案 2
在我看来,这将是您最好的选择,这取决于您如何通过集群实现所有这些以及您的目标。因为我假设您计划使用 sklearn 和 k-Means 之类的东西,所以您应该能够很好地使用稀疏矩阵。但是,就像 imaluengo 所建议的那样,您应该考虑使用不同的距离度量。您可以考虑做的是将所有数字特征缩放到与分类特征相同的范围,然后使用余弦距离之类的东西。或者混合使用距离指标,就像我在下面提到的那样。但总而言之,这可能是您的聚类算法最有用的分类数据表示。
解决方案 3
我同意 user3914041 的观点,因为这没有用,并且引入了一些与 #1 中提到的相同的问题——当两个(可能)完全 不同时,你就失去了意义名称共享一个列值。
解决方案 4
另一个解决方案是遵循答案 here. You can consider rolling your own version of a k-means-like algorithm that takes a mix of distance metrics (hamming distance for the one-hot encoded categorical data, and euclidean for the rest). There seems to be some work in developing k-means like algorithms for mixed categorical and numerical data, like here 的建议。
我想考虑您是否需要对这个分类数据进行聚类也很重要。你希望看到什么?
我的数据集由数百万行和几个(10 个)特征组成。
一个特征是由 1000 个不同值组成的标签(想象每一行都是一个用户,这个特征是用户的名字:
Firstname,Feature1,Feature2,....
Quentin,1,2
Marc,0,2
Gaby,1,0
Quentin,1,0
什么是此功能的最佳表示(以执行聚类):
我可以使用
LabelEncoder
将数据转换为整数,但这在这里没有意义,因为两个不同的标签 [=26] 之间没有逻辑 "order" =]Firstname,F1,F2,.... 0,1,2 1,0,2 2,1,0 0,1,0
我可以将特征拆分为 1000 个特征(每个标签一个),当标签匹配时为 1,否则为 0。然而,这会导致一个非常大的矩阵(如果我不能在我的分类器中使用稀疏矩阵,那就太大了)
Quentin,Marc,Gaby,F1,F2,.... 1,0,0,1,2 0,1,0,0,2 0,0,1,1,0 1,0,0,1,0
我可以将
LabelEncoder
值表示为 N 列中的二进制,与之前的想法相比,这会减少最终矩阵的维数,但我不确定结果:LabelEncoder(Quentin) = 0 = 0,0 LabelEncoder(Marc) = 1 = 0,1 LabelEncoder(Gaby) = 2 = 1,0 A,B,F1,F2,.... 0,0,1,2 0,1,0,2 1,0,1,0 0,0,1,0
...还有其他想法吗?
您如何看待解决方案 3?
编辑一些额外的解释
我应该在我的第一个 post 中提到,但在真实数据集中,该特征更像是分类树的最后一片叶子(Aa1
、Aa2
等. 在示例中 - 它不是二叉树)。
A B C
Aa Ab Ba Bb Ca Cb
Aa1 Aa2 Ab1 Ab2 Ab3 Ba1 Ba2 Bb1 Bb2 Ca1 Ca2 Cb1 Cb2
所以同一水平下的2个词之间有相似性(Aa1
Aa2
和Aa3
非常相似,而Aa1
与Ba1
比 Cb2
).
最终目标是从较小的数据集中找到相似的实体:我们在较小的数据集上训练OneClassSVM
,然后得到整个数据集的每个术语的距离
方案三:
我会说它具有与使用 1..N
编码(解决方案 1)相同的缺点,但不太明显。您的名称在某些列中都给出 1,除了编码顺序外没有其他原因...
所以我不建议这样做。
解决方案 1:
1..N
解决方案是解决格式问题的 "easy way",正如您所指出的,它可能不是最好的。
解决方案 2:
这看起来是最好的方法,但它有点麻烦,而且根据我的经验,分类器在处理大量类别时并不总是表现很好。
解4+:
我认为编码取决于你想要什么:如果你认为相似的名字(比如 John 和 Johnny)应该很接近,你可以使用 characters-grams 来表示它们。不过,我怀疑您的应用程序是否属于这种情况。
另一种方法是使用名称在(训练)数据集中的频率对名称进行编码。这样你说的是:"Mainstream people should be close, whether they're Sophia or Jackson does not matter".
希望这些建议能有所帮助,对此没有明确的答案,所以我很期待看到其他人的做法。
此问题主要是单热编码问题之一。我们如何以可以使用聚类算法的方式表示多个分类值,并且 而不是 搞砸你的算法需要做的距离计算(你可以使用某种概率有限混合模型,但我离题了)?和user3914041的回答一样,确实没有确定的答案,但是我会把你提出的每一个解决方案都看一遍,并给出我的印象:
解决方案 1
如果您像您提到的那样将分类列转换为数字列,那么您将面临您提到的那个相当大的问题:您基本上失去了该列的意义。如果 Quentin 在 0、Marc 1 和 Gaby 2 中,这到底意味着什么?到那时,为什么还要将该列包括在集群中?与 user3914041 的回答一样,这是将分类值更改为数值的最简单方法,但它们 没有用 ,并且可能对聚类结果有害。
解决方案 2
在我看来,这将是您最好的选择,这取决于您如何通过集群实现所有这些以及您的目标。因为我假设您计划使用 sklearn 和 k-Means 之类的东西,所以您应该能够很好地使用稀疏矩阵。但是,就像 imaluengo 所建议的那样,您应该考虑使用不同的距离度量。您可以考虑做的是将所有数字特征缩放到与分类特征相同的范围,然后使用余弦距离之类的东西。或者混合使用距离指标,就像我在下面提到的那样。但总而言之,这可能是您的聚类算法最有用的分类数据表示。
解决方案 3
我同意 user3914041 的观点,因为这没有用,并且引入了一些与 #1 中提到的相同的问题——当两个(可能)完全 不同时,你就失去了意义名称共享一个列值。
解决方案 4
另一个解决方案是遵循答案 here. You can consider rolling your own version of a k-means-like algorithm that takes a mix of distance metrics (hamming distance for the one-hot encoded categorical data, and euclidean for the rest). There seems to be some work in developing k-means like algorithms for mixed categorical and numerical data, like here 的建议。
我想考虑您是否需要对这个分类数据进行聚类也很重要。你希望看到什么?