哪种算法选择正确的点


9

下图显示了原点周围的7个点。其中一个已由人类根据规则和经验选择,并被涂成红色(左下象限中的一个)。

在此处输入图片说明

现在我们有1000多个这样的点集,并且每个人都选择了一个点。这些条件适用于所有集合:

  • 每套大约有3-10分
  • 没有异常值
  • 点可以具有正值和负值
  • 选择一个点没有犯错

我的问题是:是否存在一种机器学习算法可从这些集合和人工选择中学习,以便在给出新的一组点时可以自动决定要选择哪个点?当然,这个新集合可以满足前三个条件。

2最后的评论:

  • 我给出的示例只是我随机构建的示例,以支持有关原点周围平面中的点以及选定点的想法。在现实生活中,可能会有更多的结构,但是现在我很好奇,想知道这种情况下可能发生什么。
  • 会有变化吗?假设它是大约2个选定点,或者您有给定半径的圆而不是点。

2
只是大声思考,内核技巧可能会有所帮助吗?选定的点看起来看起来非常靠近其他点,同时可能在其他空间中是可分离的(例如,更高维度),然后就可以进行分类了!我会说这值得思考。
TwinPenguins

1
@MajidMortazavi听起来不错。老实说,机器学习对我来说是一个新领域。我唯一知道的是有很多可能,但我对如何以及如何一无所知。将尝试阅读有关您的内核建议的内容。
Elmex80s

2
如果您在每个点上添加特征(例如,到其他点的距离,其他点的数量等),则可以使用诸如“ K最近邻”之类的简单方法来确定您所训练的历史点最类似于您的新点,然后使用该分类。决策树或神经网络可能更适合这种非线性边界。
丹·卡特

1
piggy带@DanCarter的评论,询问要使用哪种ML算法是错误的问题。考虑一下您可以设计的功能,然后由它们确定要使用的方法(此处必不可少;除非您非常了解此问题,否则您永远不要尝试一种方法)。可以尝试其他一些可能的功能:距质心的距离(绝对值和相对于平均点质心的距离),距原点的距离,原点到矢量与轴的夹角。
保罗,

1
两个或两个以上的点可以任意靠近吗?
伊兰(Imran)'18年

Answers:


6

这是一个令人着迷的问题!有两点使它特别具有挑战性:

  • 我们应该如何比较两个点集?机器学习中的经典问题具有固定数量的属性,并且这些属性不可互换:例如,我可能拥有关于具有属性ageheight(以厘米为单位)的不同人员的数据。每个样本都有一个条目,当然(age, height) = (22, 180)与并不相同(age, height) = (180, 22)。您的问题也不是真的。一个点集包含3到10个点,比较两个点集时,我们输入点的顺序不应有任何区别。
  • 我们如何做出预测?假设我们找到了一种方法,可以从我们的训练集中选择与您上面的点集相似的点集。我们面临的问题是,我们的预测必须是您图片中的7点之一;但这些点都不能包含在相似的点集中。

让我概述一个解决这两个挑战的算法。预测精度不是很好。但也许您看到了一种可以对其进行改进的方法。至少它可以预测一些东西,对吗?

1.模拟样本

为了测试该算法,我编写了生成样本和标签的函数。

生成样本: 每个样本包含3到10个点。从均匀分布中得出的点数是随机的。每个点都是形式(x_coordinate, y_coordinate)。从正态分布中得出的坐标再次是随机的。

import numpy as np
from random import randint

def create_samples(number_samples, min_points, max_points):

    def create_single_sample(min_points, max_points):
        n = randint(min_points, max_points)
        return np.array([np.random.normal(size=2) for _ in range(n)]) 

    return np.array([create_single_sample(min_points, max_points) for _ in range(number_samples)])

生成标签:作为一个玩具示例,让我们假设选择一个点的规则是:始终选择最接近的点(0, 0),其中应根据欧几里得范式理解“最接近”。

def decision_function_minnorm(sample):
    norms = np.apply_along_axis(np.linalg.norm, axis=1, arr=sample)
    return sample[norms.argmin()]

def create_labels(samples, decision_function):
    return np.array([decision_function(sample) for sample in samples])

现在,我们可以创建训练和测试集:

n_train, n_test = 1000, 100
dec_fun = decision_function_minnorm

X_train = create_samples(number_samples=n_train, min_points=3, max_points=10)
X_test = create_samples(number_samples=n_test, min_points=3, max_points=10)
y_train = create_labels(X_train, dec_fun)
y_test = create_labels(X_test, dec_fun)

2.通过Hausdorff距离比较点集

让我们解决第一个问题:我们应该如何比较不同的点集?点集中的点数不同。还要记住,我们记下这些点的顺序应该无关紧要:与该点集[(0,0), (1,1), (2,2)]进行比较应产生与该点集进行比较相同的结果[(2,2), (0,0), (1,1)]。我的方法是通过它们的Hausdorff距离比较点集:

def hausdorff(A, B):

    def dist_point_to_set(x, A):
        return min(np.linalg.norm(x - a) for a in A)

    def dist_set_to_set(A, B):
        return max(dist_point_set(a, B) for a in A)

    return max(dist_set_to_set(A, B), dist_set_to_set(B, A))

3.通过k最近邻进行预测并求平均值

现在,我们有了点集之间的距离的概念。这样就可以使用k最近邻分类:给定一个测试点集,我们k在训练样本中找到相对于测试点集具有最小Hausdorff距离的点集,并获得它们的标签。现在出现了第二个问题:我们如何将这些k标签变成对测试点集的预测?我采用了最简单的方法:对标签取平均值,并预测测试点集中最接近平均值的点。

def predict(x, num_neighbors):
    # Find num_neighbors closest points in X_train.
    distances_to_train = np.array([hausdorff(x, x_train) for x_train in X_train])
    neighbors_idx = np.argpartition(distances_to_train, -num_neighbors)[-num_neighbors:]

    # Get labels of the neighbors and calculate the average.
    targets_neighbors = y_train[neighbors_idx]
    targets_mean = sum(targets_neighbors) / num_neighbors

    # Find point in x that is closest to targets_mean and use it as prediction.
    distances_to_mean = np.array([np.linalg.norm(p - targets_mean) for p in x])
    closest_point = x[distances_to_mean.argmin()]

    return closest_point

4.测试

一切就绪,可以测试我们算法的性能。

num_neighbors = 70
successes = 0
for i, x in enumerate(X_test):
    print('%d/%d' % (i+1, n_test))
    prediction = predict(x, num_neighbors)
    successes += np.array_equal(prediction, y_test[i])

对于给定的决策函数和num_neighbors = 70,我们的预测精度为84%。这并不是非常好,它当然是特定于我们的决策功能的,这似乎相当容易预测。

要看到这一点,请定义一个不同的决策函数:

decision_function_maxaverage(sample):
    avgs = (sample[:, 0] + sample[:, 1]) / 2
    return sample[norms.argmin()]

通过使用此功能dec_fun = decision_function_maxaverage会将预测精度降低到45%。这表明考虑生成标签的决策规则的重要性。如果您知道为什么人们会选择某些点,这将帮助您找到最佳算法。

改进此算法的一些方法:(1)使用不同的距离函数代替Hausdorff距离,(2)使用比k最近邻更复杂的东西,(3)改进如何将所选训练标签转化为预测。


3

您可以使用以下几种方法使用神经网络来解决此问题:

使用简单的前馈神经网络:

  • 缩放数据以适合原点周围从(-1,-1)到(1,1)的正方形
  • k
  • 为每个点添加第三个指标输入,以指示该点是否存在
  • 选择隐藏层的数量和大小
  • 在输出端使用大小为10的softmax层

kk

使用卷积神经网络:

  • nnnnkki,j010
  • nn

由于您的数据本质上是空间的,因此CNN的效果可能更好。但是,如果两个或多个点重叠,则必须决定该怎么办。最简单的解决方案是随机选择一个,具体取决于您的特定任务。

使用递归神经网络:

  • 输入缩放的(x,y)点的可变长度序列,并输出大小为10的softmax估算值

是的,就像使用RNN一样简单!它们可以很好地处理可变长度的输入,但是仍然缺少CNN的优势,可以处理空间数据。

注意事项:

如果使用FNN或RNN,则还存在如何订购输入数据的问题。如果您的真实数据中没有固有顺序,那么我们不希望我们的网络对以不同顺序编码的同一数据做出不同的预测。解决此问题的一种方法是使用数据扩充:以不同的输入顺序将每个训练示例重复几次,因此希望您的网络可以学习适当的对称性。

如果您只有时间尝试一种方法,则可以选择CNN。CNN的设计可以很好地处理空间数据,并且输入顺序没有问题。


1
这样做的问题是预测是依赖于顺序的。向算法提供一个点集(0,0), (1,1), (2,2)与向它提供一个点集会有不同的效果(1,1), (2,2), (0,0)
Elias Strehle,

很好,伊莱亚斯(Elias)-我将提出一个缓解建议。
伊兰(Imran)'18

@EliasStrehle提到这一点很好,顺序与该问题无关。我们有一组点(全部唯一,无顺序)。
Elmex80s
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.