Scikit-learn: 实现高尔相似系数

创建于 2015-11-19  ·  51评论  ·  资料来源: scikit-learn/scikit-learn

正如@lesshaste 所建议的

论文 - http://cbio.ensmp.fr/~jvert/svn/bibli/local/Gower1971general.pdf

如果有足够的兴趣,我可以实施这个吗?

@jnothman @amueller @agramfort

New Feature

最有用的评论

你好,

为了以某种方式做出贡献,我根据原始论文实现了 Gower 函数,以及 pdist 模块中所需的相应调整,因为在内部 pdist 进行了几个数值转换,如果您使用具有混合数据的矩阵,这些转换将失败。

到目前为止,我从 R 的菊花函数中获得的结果是相同的。

源代码可在此 jupyter 笔记本中找到: https ://sourceforge.net/projects/gower-distance-4python/files/

随意使用它

所有51条评论

谢谢。

这个来自 R 的daisy文档可能也很相关https://stat.ethz.ch/R-manual/R-devel/library/cluster/html/daisy.html因为它是一个流行的用例高尔系数。

建议在哪里? 在什么情况下?

@agramfort我在 gitter 上推荐了它。 这个系数的主要兴趣是当变量具有混合类型(即分类、数值、有序)时。 一个流行的用例是在前面提到的 R 包daisy()中对混合类型的数据进行聚类时(参见 https://cran.r-project.org/web/packages/cluster/cluster.pdf 的第 27 页) . 更一般地说, http ://www.clustan.talktalk.net/gower_similarity.html 声称“Gower 的一般相似系数是混合数据类型最流行的邻近度度量之一。” 这似乎是一个合理的主张。

是否有一个基准或令人信服的例子来激励这一点?

@agramfort我认为更多的是我们目前没有其他方法可以计算混合数据类型的相异系数,这似乎是标准方法。 我可以在网上找到很多示例和问题/答案,人们可​​以在其中解释高尔系数是什么或建议将其用于混合数据类型,但我还没有什么可以称为基准的。 据谷歌学者统计,原论文已被引用 2298 次。

好的,我相信:)

@agramfort太棒了! 这一变化将很好地补充https://github.com/scikit-learn/scikit-learn/pull/4899 ,它引入了对树的原生分类变量支持。

话虽如此,我现在意识到 scikit-learn 目前根本没有对序数的本地支持,所以我的这部分建议会稍微超前。 我想人们可以积极地将其视为支持序数特征的第一步。

@amueller被标记为[New Feature] ...

你好,

为了以某种方式做出贡献,我根据原始论文实现了 Gower 函数,以及 pdist 模块中所需的相应调整,因为在内部 pdist 进行了几个数值转换,如果您使用具有混合数据的矩阵,这些转换将失败。

到目前为止,我从 R 的菊花函数中获得的结果是相同的。

源代码可在此 jupyter 笔记本中找到: https ://sourceforge.net/projects/gower-distance-4python/files/

随意使用它

我只是想知道是否有任何更新? 另外, @marcelobeckmann指出的问题

@ashimb9看来我们需要有人来整合@marcelobeckmann的代码

@agramfort嗯,在这种情况下,我会在空闲时间去尝试一下。 顺便说一句,您是否碰巧知道上述问题的当前状态:“在 pdist 模块中,因为在内部 pdist 进行了几个数值转换,如果您使用具有混合数据的矩阵,这些转换将失败”

嗨,在 pdist 中有一些私有函数(例如,_convert_to_double、_copy_array_if_base_present)假设底层数据是完全数字的,当你有一个包含分类数据的 Dataframe 时,这是不正确的。

我自愿集成此代码并使其在分叉中可用,您可以将此票分配给我。

github分配功能仅适用于团队成员

2017 年 7 月 17 日下午 7:32,“marcelobeckmann”通知@github.com 写道:

嗨,有一些私有函数(例如,_convert_to_double,
_copy_array_if_base_present) 在 pdist 中,假设基础数据是
完全数字,当你有一个数据框时,这是不正确的
分类数据。

我自愿集成此代码并使其在 fork 中可用,您
可以把这张票分配给我。


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/scikit-learn/scikit-learn/issues/5884#issuecomment-315707830
或静音线程
https://github.com/notifications/unsubscribe-auth/AAEz62L3HHzGsSerW5G3n-Z8rrNoV6mwks5sOyoTgaJpZM4Glm0p
.

不用担心,我会fork它,稍后您可以获取get代码。 对我来说,重要的是做出贡献。 完成后我会通知你。

感谢@marcelobeckmann接受这个问题。 当您使用它时(如果它对您可行),我想知道您是否会考虑添加对具有 NaN 值的数据的高尔计算的支持,如在 R 中的 daisy 包中实现的(您也在上面引用过) ?

我完成了 Gower 到 sklearn.metrics.pairwise 的集成(也观察了 NaN 值的处理)。 在提交我的分叉代码之前,我将准备一些单元测试。

@marcelobeckmann太棒了! 非常感谢,尤其是对 NaN 的支持! :)

PS:如果我可以建议,您可能需要考虑发起拉取请求,以便审阅者可以在您进行单元测试等时开始查看您的代码。

几天前我提出了一个拉取请求,b5884。

是的,它在等待审核的队列中。

2017 年 8 月 17 日 23:40,Marcelo Beckmann通知@github.com
写道:

几天前我提出了一个拉取请求,b5884。


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/scikit-learn/scikit-learn/issues/5884#issuecomment-323076581
或静音线程
https://github.com/notifications/unsubscribe-auth/AAEz69uMu0XsoAUfvwWikkadjGCk5yvKks5sZELKgaJpZM4Glm0p
.

我做了CI要求的修改,所有的检查都通过了。

@marcelobeckmann伟大的工作! 您可能希望将第 659 行更改为:
ranges_of_numeric[col] = (1 - min / max, 0)[max == 0] if (max!=0) else 0.0

否则,我会在您的第二个测试用例中除以零警告。

嗨,我更改了代码以避免 Pierre Wessman 提出的警告,并且 CI 是绿色的。 我需要有人来审查我的代码。

@marcelobeckmann和可能的其他人。

嗨,马塞洛(或其他人),关于您在此处放置的高尔系数的实现有几个快速问题: https :

  1. 我是否需要一个熊猫数据帧来将原始数据输入到函数中,或者我也可以使用一个 numpy 数组?

  2. 我正在将我的数据导入一个 numpy 数组。 除了作为唯一 ID 的第一列之外,所有列都是数字实数。 我有两个问题,

  • 首先,当我运行该函数时,它返回数据转换警告,说 dtype U7 已转换为对象!!。 我认为这是因为数组条目出于某种原因出现在引号中,因此是字符串。 因此,例如,我将数组条目的类型转换为 int32,但它仍然给出转换错误,指出 int32 已转换为对象

  • 其次,可能与上面有关,每次我运行函数并绘制结果时,我都会收到不同的可视化(点的不同分布)。

你能就上述问题给我建议吗?

非常感谢

嗨,阿里,

感谢您对高尔距离的这种实现感兴趣。

虽然我提出 pull request 的代码没有得到 scikit learn 提交者的批准(CI 是绿色的,只是在等待审查),但我将这个最新且稳定的实现推送到: https :

让我们来回答你的问题:

  1. 我是否需要 Panda DataFrame 来将原始数据输入到函数中,还是我也可以使用 numpy 数组?

答:您可以在新版本 3 中使用 DataFrame 或 Numpy。还支持稀疏矩阵。

  1. . 我正在将我的数据导入一个 numpy 数组。 除了作为唯一 ID 的第一列之外,所有列都是数字实数。 我有两个问题,
  • 首先,当我运行该函数时,它返回数据转换警告,说 dtype U7 已转换为对象!!。 我认为这是因为数组条目出于某种原因出现在引号中,因此是字符串。 因此,例如,我将数组条目的类型转换为 int32,但它仍然给出转换错误,指出 int32 已转换为对象

答:这个新版本支持数字分类属性,有一个额外的参数categorical_features,你可以设置一个数组,false(数值属性)或true(分类属性)

  • 其次,可能与上面有关,每次我运行函数并绘制结果时,我都会收到不同的可视化(点的不同分布)。

答:我推送的新版本解决了这个问题。

请注意,我确实打算审查此 PR,但它不是很高
优先自动取款机

嗨,阿里,

  1. 最新的是 gower_function-v3.ipynb,是的,它处理 nan
    传播

  2. 如果您的分类属性不是,您只能使用 gower_distance(X)
    数字,或 gower_distance(X, categorical_features=[False, True,
    错误,...]),如果您的猫属性表示为数字。

如果您有任何问题,请私下告诉我,因为此实现
我推到网上应该不是scikit learn的关注点,他们有
有很多事情要做,这里不是讨论这个的最佳场所。

2017 年 11 月 30 日 11:51,“阿里”通知@github.com 写道:

@marcelobeckmann https://github.com/marcelobeckmann

嗨,马塞洛(或其他人),有一个关于您的快速问题
您在此处放置的高尔系数的实现:
https://sourceforge.net/projects/gower-distance-4python/files/

1.

gower_single_function-v2.ipynb 是最终版本并处理
NaN也是?
2.

更重要的是,此实现是否允许您获得
单个样本数据中的相似性? 因为在大多数情况下你
需要的是获得每对观察之间的高尔距离
一个单一的样本数据,而不是比较两个不同的样本数据。

非常感谢


你收到这个是因为你被提到了。
直接回复本邮件,在GitHub上查看
https://github.com/scikit-learn/scikit-learn/issues/5884#issuecomment-348166596
或静音线程
https://github.com/notifications/unsubscribe-auth/AA3G79jWVbpBNdAFOAim7wJS92-QGl0dks5s7pa8gaJpZM4Glm0p
.

嗨,阿里,

  1. 最新的是 gower_function-v3.ipynb,它是我推到 scikit learn 的一个副本,是的,它处理 nan 传播

  2. 如果您的分类属性不是数字,您只能使用 gower_distance(X),或者如果您的分类属性表示为数字,则可以使用 gower_distance(X, categorical_features=[False, True, False,...])。

如果您有任何问题,请私下告诉我,因为我推送到互联网的这个实现不应该是 scikit learn 的关注点,他们有很多事情要做,这里不是讨论 scikit 之外的东西的最佳场所学习项目。

@marcelobeckmann你好,马塞洛,
如果我们将分类变量编码为数字格式,那么 categorical_features 参数的值应该是 True 还是 False?

我也收到以下错误:
ValueError: 找到具有 0 个样本的数组 (shape=(0, 0)) 而 check_pairwise_arrays 需要最少 1。

它以前在相同的数据中成功运行,但现在却出现了这样的错误。 为什么会这样?

@bendiste

如果您将 True 和 False 表示为 1 和 0,您将得到相同的结果。

你用的是最新的笔记本 gower_function-v6.4.ipynb 吗?
https://sourceforge.net/projects/gower-distance-4python/files/
?

我正在写一篇文章,希望这个月我会做出要求的更改,以使我的实现在 scikit-learn 大师中被接受。

@marcelobeckmann ,感谢您的回复。 是的,我正在使用您指出的最新版本。 当我重新下载它时,它成功运行。 因为我是机器学习的新手,所以我想问几件事:
1- 我可以使用 KPCA 来降低维度作为层次聚类算法的输入吗?
2- 还是我必须使用整个高维数据集作为层次聚类的输入?

@marcelobeckmann
感谢您的实施!

我试过 gower_function-v6.4 版本。
我可以看到您的单元测试中的距离是相同的,无论您是否指定分类列。 我也尝试过使用我自己的数据,它也不影响结果。

这样对吗?

谢谢!

@annelaura

很抱歉延迟回复。 是的,这是正确的,该测试只是为了检查 categorical_features=[0, 1] 参数是否不会影响结果,如果非数字列也可以识别为对象。 输入的数据是一样的,所以结果一定是一样的。

完成一些论文后,我又回去工作了,最终向 scikit master 分支提出了我的实现! :)

@marcelobeckmann有关于这方面的消息吗? :)

嗨亚历克斯,我已经完成了审查者在拉取请求中提出的所有修改,并且 CI 是绿色的。 我还 ping 评论者以检查他们是否满意,然后我们可以关闭此拉取请求并将其推送到发布。

任何更新? @马塞洛贝克曼

审核后进行中。

PR 批准了吗? @马塞洛贝克曼

还没有,在最近的一些代码审查之后工作正在进行中。

太糟糕了我需要它。

只是该功能在某处可用吗? 所以我可以自己使用它(用于研究目的)

谢谢

您可以在此 PR 中获取此函数的最新提交:
https://github.com/scikit-learn/scikit-learn/pull/9555

我设法让它在本地工作。 谢谢!

只需快速 +1 这张票! 感谢您为此所做的所有工作。

撞。 这将是一个很好的补充。 我不敢相信一个相对简单的计算花了 4 年的时间才将它变成了 sklearn!

或者你可以说:感谢你四年来的执着
无私的努力!

或者您可以说:感谢您四年来的无私奉献!

你说得对,对不起。 我不是故意让别人觉得粗鲁的。 我非常感谢您的努力。 我已经在本地使用它一段时间了,很高兴看到它被添加。 这是我所知道的混合数据类型的唯一距离度量。

除了志愿者的努力,核心开发人员还没有考虑
如此紧迫,如何处理混合类型确实存在挑战,
以及如何在训练测试设置中执行缩放。

期待在 sklearn 中。

声称从该线程“借用想法”的人在github上发布了一个包来计算高尔距离(技术上的相似性)。 说到距离和相似性,这个例子与@marcelobeckmann 的例子相同。 到目前为止,我只看了一眼代码,但这里有一个一瞥:

来自@marcelobeckmann的笔记本:

    # This is to normalize the numeric values between 0 and 1.
    X_num = np.divide(X_num ,max_of_numeric,out=np.zeros_like(X_num), where=max_of_numeric!=0)

来自“迈克尔·严”:

    # This is to normalize the numeric values between 0 and 1.
    Z_num = np.divide(Z_num ,num_max,out=np.zeros_like(Z_num), where=num_max!=0)

大家好,感谢关注。

我很高兴人们正在接受代码并试图改进它,这就是开源的目的,尽管受到了一些赞扬。

希望此代码将成为 scikit-learn 的一部分,如果此 PR #9555被接受。

此致,

马塞洛·贝克曼

祝过程顺利!!

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

yandrieiev picture yandrieiev  ·  3评论

divyaprabha123 picture divyaprabha123  ·  3评论

shauli-ravfogel picture shauli-ravfogel  ·  3评论

rth picture rth  ·  3评论

trchan picture trchan  ·  3评论