机器学习:找到最接近查询向量的结果
Machine learning : find the closest results to a queried vector
我有数千个向量,每个向量大约有 20 个特征。
给定一个查询向量和一组潜在匹配项,我希望能够 select 最好的 N
匹配项。
我花了几天时间尝试回归(使用 SVM),用我自己创建的数据集训练我的模型:每个向量都是查询向量和结果向量的串联,我给出了分数(主观评估)在 0 和 1 之间,0 表示完美匹配,1 表示最差匹配。
我没有取得很好的成绩,我相信一个原因可能是很难主观地分配这些分数。另一方面,更容易的是对结果进行主观排名(score
是一个未知函数):
score(query, resultA) > score(query, resultB) > score(query, resultC)
所以我认为这更多是 Learning to rank 的问题,我找到了 Python 的各种链接:
- http://fa.bianp.net/blog/2012/learning-to-rank-with-scikit-learn-the-pairwise-transform/
- https://gist.github.com/agramfort/2071994
...
但我一直无法理解它是如何工作的。我真的对所有术语感到困惑,成对排名,等等……(请注意,我对机器学习一无所知,因此我感觉有点迷茫),等等……所以我不明白如何将其应用于我的问题。
有人可以帮我澄清一下,指出我要解决的问题的确切类别,甚至更好地说明我如何在 Python (scikit-learn) 中实现它吗?
在我看来,您要做的是简单地计算查询与其余数据之间的距离,然后 return 最接近您的查询的 N 个向量。这是一个搜索问题。
没有排序,您只需测量查询与 "thousands of vectors" 之间的距离。最后,您对距离进行排序并取最小的 N 个值。这些对应于与您的查询最相似的 N 个向量。
为了提高比较效率,您可以使用 KD 树或其他高效搜索结构:http://scikit-learn.org/stable/modules/neighbors.html#kd-tree
然后,看看 Lp space 上的维基百科页面。在选择合适的指标之前,您需要考虑数据及其表示形式:
- 您使用的是什么类型的数据?它来自哪里,代表什么? space 特征是仅由实数组成,还是包含二进制值、分类值或所有这些值? Wiki 的同类数据与异构数据。
对于真正有价值的特征 space,欧几里得距离 (L2) 通常是使用的选择度量,20 个特征应该没问题。从这个开始。否则,您可能需要考虑城市街区距离 (L1) 或其他指标,例如 Pearson 相关性、余弦距离等。
在执行其他任何操作之前,您可能必须对数据进行一些工程设计。
- 特征是否在同一尺度上?例如x1 = [0,1], x2 = [0, 100]
如果没有,请尝试缩放您的功能。这通常是一个反复试验的问题,因为某些特征可能有噪声,在这种情况下缩放可能无济于事。
为了解释这一点,请考虑一个具有两个特征的数据集:身高和体重。如果身高以厘米 (10^3) 为单位,体重以千克 (10^1) 为单位,那么您应该将厘米转换为米,以便两个特征的重量相等。对于具有广泛值的特征 space 来说,这通常是个好主意,这意味着您有两个特征的大量值样本。理想情况下,您希望所有特征都呈正态分布,只有一点点噪声 - 请参阅中心极限定理。
- 所有功能都相关吗?
如果您使用的是真正有价值的数据,您可以使用主成分分析 (PCA) 对特征进行排序并只保留相关的特征。
否则,您可以尝试特征选择 http://scikit-learn.org/stable/modules/classes.html#module-sklearn.feature_selection
减少 space 的维度可以提高性能,尽管这对您的情况并不重要。
如果您的数据由连续的、分类的和二进制值组成,则旨在缩放或标准化数据。使用您对数据的了解来提出适当的表示。这是大部分工作,或多或少是一种魔法。反复试验。
附带说明一下,基于度量的方法(例如 knn 和 kmeans)只是存储数据。学习从记忆结束的地方开始。
我有数千个向量,每个向量大约有 20 个特征。
给定一个查询向量和一组潜在匹配项,我希望能够 select 最好的 N
匹配项。
我花了几天时间尝试回归(使用 SVM),用我自己创建的数据集训练我的模型:每个向量都是查询向量和结果向量的串联,我给出了分数(主观评估)在 0 和 1 之间,0 表示完美匹配,1 表示最差匹配。
我没有取得很好的成绩,我相信一个原因可能是很难主观地分配这些分数。另一方面,更容易的是对结果进行主观排名(score
是一个未知函数):
score(query, resultA) > score(query, resultB) > score(query, resultC)
所以我认为这更多是 Learning to rank 的问题,我找到了 Python 的各种链接:
- http://fa.bianp.net/blog/2012/learning-to-rank-with-scikit-learn-the-pairwise-transform/
- https://gist.github.com/agramfort/2071994 ...
但我一直无法理解它是如何工作的。我真的对所有术语感到困惑,成对排名,等等……(请注意,我对机器学习一无所知,因此我感觉有点迷茫),等等……所以我不明白如何将其应用于我的问题。
有人可以帮我澄清一下,指出我要解决的问题的确切类别,甚至更好地说明我如何在 Python (scikit-learn) 中实现它吗?
在我看来,您要做的是简单地计算查询与其余数据之间的距离,然后 return 最接近您的查询的 N 个向量。这是一个搜索问题。 没有排序,您只需测量查询与 "thousands of vectors" 之间的距离。最后,您对距离进行排序并取最小的 N 个值。这些对应于与您的查询最相似的 N 个向量。
为了提高比较效率,您可以使用 KD 树或其他高效搜索结构:http://scikit-learn.org/stable/modules/neighbors.html#kd-tree
然后,看看 Lp space 上的维基百科页面。在选择合适的指标之前,您需要考虑数据及其表示形式:
- 您使用的是什么类型的数据?它来自哪里,代表什么? space 特征是仅由实数组成,还是包含二进制值、分类值或所有这些值? Wiki 的同类数据与异构数据。
对于真正有价值的特征 space,欧几里得距离 (L2) 通常是使用的选择度量,20 个特征应该没问题。从这个开始。否则,您可能需要考虑城市街区距离 (L1) 或其他指标,例如 Pearson 相关性、余弦距离等。 在执行其他任何操作之前,您可能必须对数据进行一些工程设计。
- 特征是否在同一尺度上?例如x1 = [0,1], x2 = [0, 100]
如果没有,请尝试缩放您的功能。这通常是一个反复试验的问题,因为某些特征可能有噪声,在这种情况下缩放可能无济于事。 为了解释这一点,请考虑一个具有两个特征的数据集:身高和体重。如果身高以厘米 (10^3) 为单位,体重以千克 (10^1) 为单位,那么您应该将厘米转换为米,以便两个特征的重量相等。对于具有广泛值的特征 space 来说,这通常是个好主意,这意味着您有两个特征的大量值样本。理想情况下,您希望所有特征都呈正态分布,只有一点点噪声 - 请参阅中心极限定理。
- 所有功能都相关吗?
如果您使用的是真正有价值的数据,您可以使用主成分分析 (PCA) 对特征进行排序并只保留相关的特征。 否则,您可以尝试特征选择 http://scikit-learn.org/stable/modules/classes.html#module-sklearn.feature_selection 减少 space 的维度可以提高性能,尽管这对您的情况并不重要。
如果您的数据由连续的、分类的和二进制值组成,则旨在缩放或标准化数据。使用您对数据的了解来提出适当的表示。这是大部分工作,或多或少是一种魔法。反复试验。
附带说明一下,基于度量的方法(例如 knn 和 kmeans)只是存储数据。学习从记忆结束的地方开始。