我有数千个每个大约包含20个特征的向量。
给定一个查询向量和一组潜在的匹配项,我希望能够选择最佳的N
个匹配项。
我花了几天时间尝试使用回归(使用SVM),用我自己创建的数据集训练我的模型:每个向量是查询向量和结果向量的拼接,我给出了一个在0到1之间的分数(主观评估),0表示完美匹配,1表示最差匹配。
我的结果并不理想,我认为一个原因可能是主观分配这些分数非常困难。另一方面,更容易做的是主观地对结果进行排序(score
是一个未知函数):
score(query, resultA) > score(query, resultB) > score(query, resultC)
所以我认为这更是一个学习排序的问题,我找到了各种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)中实现这一点?
回答:
在我看来,你试图做的是简单地计算查询与你其余数据之间的距离,然后返回与查询最接近的N个向量。这是一个搜索问题。没有排序,你只是测量查询与“数千个向量”之间的距离。最后,你对距离进行排序并取最小的N个值。这些对应于与你的查询最相似的N个向量。
为了提高比较的效率,你可以使用KD-Tree或其他高效的搜索结构:http://scikit-learn.org/stable/modules/neighbors.html#kd-tree
然后,看看关于Lp空间的维基百科页面。在选择合适的度量标准之前,你需要考虑数据及其表示:
- 你在处理什么类型的数据?它来自哪里,代表什么?特征空间仅包含实数,还是包含二进制值、分类值或所有这些?查看同质与异质数据的维基百科页面。
对于实值特征空间,通常选择的度量标准是欧几里得距离(L2),对于20个特征来说应该没问题。从这个开始。否则,你可能需要考虑城市街区距离(L1)或其他度量标准,如皮尔逊相关系数、余弦距离等。你可能需要在进行其他操作之前对数据进行一些工程处理。
- 特征是否在同一尺度上?例如,x1 = [0,1],x2 = [0, 100]
如果不是,那么尝试缩放你的特征。这通常是试错的问题,因为有些特征可能是噪声,在这种情况下,缩放可能无济于事。为了解释这一点,想想一个包含两个特征的数据集:身高和体重。如果身高以厘米(10^3)计,体重以千克(10^1)计,那么你应该设法将厘米转换为米,以便两个特征的权重相等。这对于特征空间值范围广泛的情况通常是一个好主意,意味着你对两个特征都有大量的样本值。你理想情况下希望所有特征都呈正态分布,只有少量噪声 – 参见中心极限定理。
- 所有特征都相关吗?
如果你处理的是实值数据,你可以使用主成分分析(PCA)对特征进行排序,并只保留相关的特征。否则,你可以尝试特征选择http://scikit-learn.org/stable/modules/classes.html#module-sklearn.feature_selection降低空间维度会提高性能,尽管在你的情况下这不是关键的。
如果你的数据包含连续值、分类值和二进制值,那么目标是缩放或标准化数据。利用你对数据的了解来提出合适的表示。这是工作的重点,基本上是一门黑艺术。试错法。
作为旁注,基于度量的方法如knn和kmeans只是存储数据。学习从记忆结束的地方开始。