【问题标题】:What algorithms are suitable for this simple machine learning problem?什么算法适合这个简单的机器学习问题?
【发布时间】:2011-01-31 23:28:20
【问题描述】:

我有一个我认为是简单的机器学习问题。

这是一个基本问题:我反复得到一个新对象和关于该对象的描述列表。例如:new_object:'bob'new_object_descriptions:['tall','old','funny']。然后,我必须使用某种机器学习来查找先前处理过的具有 10 个或更少的最相似描述的对象,例如,past_similar_objects:['frank','steve','joe']。接下来,我有一个算法,可以直接衡量这些对象是否确实与bob相似,例如,correct_objects:['steve','joe']。然后为分类器提供成功匹配的反馈训练。然后这个循环重复一个新对象。 一种 伪代码如下:

Classifier=new_classifier()

while True:
    new_object,new_object_descriptions = get_new_object_and_descriptions()
    past_similar_objects = Classifier.classify(new_object,new_object_descriptions)
    correct_objects = calc_successful_matches(new_object,past_similar_objects)
    Classifier.train_successful_matches(object,correct_objects)

但是,有一些规定可能会限制可以使用的分类器:

  • 将有数百万个对象放入此分类器中,因此分类和训练需要很好地扩展到数百万个对象类型,并且仍然很快。我相信这会取消诸如垃圾邮件分类器之类的东西,该分类器仅适用于两种类型:垃圾邮件或非垃圾邮件。 (更新:如果这是一个问题,我可能会将其缩小到数千个对象而不是数百万个。)

  • 再次强调,在对数百万个对象进行分类时,我更喜欢速度,而不是准确度。

  • 更新:分类器应根据过去训练的反馈返回 10 个(或更少)最相似的对象。如果没有这个限制,一个明显的欺骗是分类器可以只返回所有过去的对象:)

为此目的,什么是体面、快速的机器学习算法?

注意:calc_successful_matches 距离度量的计算成本非常高,这就是为什么我使用快速机器学习算法来尝试在我实际进行昂贵的计算之前猜测哪些物体会靠近。

【问题讨论】:

  • 请注意:当您描述您的算法时,您未能就被省略的项目提供反馈。即,在您提供的示例中,correct_objects 可能等于 ['steve', 'joe', 'dan']。由于计算限制,这可能是必要的,但请确保它是故意的。
  • 我特别将 calc_successful_matches 限制为检查是否有任何 past_similar_objects 与 new_object 足够相似。如果它们都不存在,则返回的列表将为空。

标签: python artificial-intelligence machine-learning classification neural-network


【解决方案1】:

您可以使用向量空间模型 (http://en.wikipedia.org/wiki/Vector_space_model)。我认为您要学习的是如何在考虑两个对象描述向量彼此之间的接近程度时对术语进行加权,例如就简化的互信息而言。这可能非常有效,因为您可以从术语散列到向量,这意味着您不必比较没有共享特征的对象。然后,幼稚模型将具有每个术语的可调整权重(这可以是每个向量的每个术语、每个术语整体,或两者兼而有之),以及一个阈值。向量空间模型是一种广泛使用的技术(例如,在 Apache Lucene 中,您可能可以使用它来解决这个问题),因此您可以通过进一步搜索找到很多关于它的信息。

让我根据你的例子给出一个非常简单的表述。给定 bob:['tall','old','funny'],我检索

坦率:['年轻','矮小,'有趣'] 史蒂夫:['高','老','脾气暴躁'] 乔:['高','老']

因为我正在维护来自 fun->{frank,...}、tall->{steve, joe,...} 和 old->{steve, joe,...} 的哈希值

我计算了类似整体互信息的东西:共享标签的权重/鲍勃标签的权重。如果该权重超过阈值,我会将它们包含在列表中。

训练时,如果我犯了错误,我会修改共享标签。如果我的错误包括 frank,我会因为搞笑而减轻体重,而如果我因为不包括 Steve 或 Joe 而犯了错误,我会增加身高和老年人的体重。

您可以根据需要将其设置为复杂的,例如通过为术语连词添加权重。

【讨论】:

    【解决方案2】:

    SVM 非常快。对于 Python,LIBSVM 尤其提供了非常体面的分类支持向量机实现。

    【讨论】:

    • SVM 的问题在于它最基本的形式是一个二元分类器。使其成为多类并非易事。一对多的方法需要每个类一个 SVM,这对于大量类是不可行的。一种可能的解决方案是使用纠错输出编码 (ECOC),但这仍然需要大约 log(类数)SVM 分类器。
    • SVM 不合适。他概述的程序似乎需要在线/增量培训。据我所知,所有的 SVM 实现都只支持离线/批量模式训练。
    【解决方案3】:

    你真的需要机器学习算法吗?你的相似度指标是什么?你提到了对象数量的维度,那么每个人的特征集的大小呢?是否有最大数量的特征类型?我可能会尝试这样的事情:

    1) 具有字典映射特征到名为 map 的名称列表

    每个人 p

    对于 p 中的每个特征 t

    地图[t].add(p);

    2) 然后当我想找到最近的人时,我会拿起我的字典并创建一个新的临时字典:

    要计数的字典映射名称叫cnt

    对于我感兴趣的人的每个特征 t

    对于地图中的每个人 p[t]

    cnt[p]++;

    然后计数最高的条目最接近


    这里的好处是地图只创建一次。如果每个人的特质少,可用特质的类型多,那么算法应该很快。

    【讨论】:

    • 这基本上是向量空间方法的最简单实现。恭喜,您现在了解机器学习了。
    • 有趣,不知道这算不算。 :)
    • 实际距离度量计算起来非常昂贵,这就是为什么我使用机器学习算法在直接计算之前先尝试猜测哪些物体可能靠近。
    • 这不是也叫逆索引吗?第二步是一个基本的标量积(计算向量的常见二进制维度),如果可以对其进行归一化,则可以将其称为余弦相似度
    【解决方案4】:

    该项目在两个显着方面偏离了典型的分类应用程序:

    • “分类器”不是输出新对象被认为属于的类别(或可能输出这些类别的数组,每个类别都有概率/置信水平),而是提供“接近”的“邻居”列表足够”到新对象。
    • 对于每个新分类,一个独立于分类器的目标函数提供正确的“邻居”列表;然后使用更正后的列表(分类器提供的列表的子集?)来训练分类器

    第二点背后的想法可能是,由于正在进行的训练,提交给分类器并且与当前对象相似的未来对象应该得到更好的“分类”(与一组更正确的先前看到的对象相关联)加强与正(正确)匹配的连接,同时削弱与分类器最初出错的对象的连接。

    这两个特征带来了不同的问题。
    - 输出是对象列表而不是“原型”(或类别标识符)这一事实使得随着迄今为止看到的对象数量向问题中建议的数百万个实例增长而难以扩展。 - 训练是基于分类器找到的匹配的 子集 进行的这一事实,可能会引入过度拟合,从而分类器可能对它所识别的特征(维度)“视而不见” ,意外地,在训练的早期部分没有那么重要/相关。 (关于负责生成“正确”对象列表的目标函数,我可能假设太多了)

    可能,缩放问题可以通过两步过程来处理,使用第一个分类器,基于 K-Means 算法或类似的东西,这将产生整个对象集合的一个子集(之前看到的对象)作为当前对象的合理匹配(有效地过滤掉 70% 或更多的集合)。然后将根据向量空间模型(如果特征维度基于因素而不是值)或其他一些模型来评估这些可能的匹配。这个两步过程的基本假设是对象集合将有效地暴露集群(它可能只是相对均匀地分布在各个维度上)。

    随着先前看到的对象大小的增长,进一步限制要评估的候选对象数量的另一种方法是删除附近的重复项并仅与其中一个进行比较(但要在结果中提供完整的重复列表,假设如果新对象接近这个近似重复类的“代表”,则该类的所有成员也会匹配)

    过拟合问题更难处理。一种可能的方法是[有时]将对象随机添加到分类器通常不包括的匹配列表中。可以根据与新对象的距离相对距离添加额外的对象(即,增加添加相对较近的对象的可能性)

    【讨论】:

    • 这重申了我试图很好解释的问题的一些部分。谢谢。是的,我知道快速分类容易过度拟合,并且可能会得出次优的解决方案。这是我愿意接受的权衡。
    • @user213060:过度拟合并不是因为选择了快速分类器,而是因为正在进行的训练可能有偏差的“训练数据”(如果我认为,calc_successful_matches 函数生成分类器返回的匹配子集)。
    【解决方案5】:

    似乎满足您要求的算法(并且可能类似于统计学家约翰的建议)是Semantic Hashing。基本思想是它训练一个深度信念网络(一种神经网络,有些人称之为“神经网络 2.0”,目前是一个非常活跃的研究领域)来创建一个对象描述列表的散列到二进制数,使得数字之间的汉明距离对应于相似的对象。由于这只需要按位运算,它可以非常快,并且由于您可以使用它来创建最近邻风格的算法,因此它自然可以推广到非常多的类。这是非常好的最先进的东西。缺点:理解和实现并不容易,需要一些参数调整。作者提供了一些matlab代码here。一种更容易实现且与该算法密切相关的算法是局部敏感哈希。

    既然你说你想要快速逼近一个昂贵的距离函数,我想起了另一个非常有趣的算法,Boostmap。这个使用提升来创建一个快速度量,该度量近似于一个昂贵的计算度量。在某种意义上它与上面的想法相似,但使用的算法不同。这篇论文的作者有几篇关于相关技术的论文,质量都很好(发表在顶级会议上),您可能想看看。

    【讨论】:

    • 语义散列的好处是它还可以学习属性是否相似。因此,如果“高”和“重”相关联,网络实际上会注意到。它也非常快,因为它基本上只有矩阵乘法和元素智能函数应用。
    • 我确实也考虑过推荐语义哈希,或者类似的也涉及受限玻尔兹曼机器的东西。问题是,我不确定何时不再需要为相似的人添加节点,而向量空间模型可以让我以可扩展的方式添加人员,而无需明确表示他们。尽管如此,我还是要告诉你一点,尽管我仍然会按照自己的方式去做。
    • 实际上,如果您阅读语义哈希论文,他们会有点偷偷摸摸地做一些预处理,以将他们哈希的标签数量限制在大约 1000 个最重要的单词。如果您必须继续“即时”学习,您可能会遇到意想不到的问题。
    • 是的,像往常一样在学术论文中一些细节(这可能对现实世界的应用很重要)被掩盖了。但这是一个有趣的起点。
    • 是的,当然不要让它阻碍使用语义散列等 RBM 技术。同时,如果您有足够的预处理能力,那就去做吧。
    【解决方案6】:

    您所描述的有点类似于Locally Weighted Learning 算法,它给定一个查询实例,它会在相邻实例周围本地训练一个模型,该模型由它们到查询实例的距离加权。

    Weka (Java) 在weka.classifiers.lazy.LWL 中有一个实现

    【讨论】:

    • 这种方法的问题是它会非常慢,因为需要所有的模型构建。局部模型提高了准确性,但 OP 倾向于更快的分类器,即使准确度较低。
    猜你喜欢
    • 2020-06-06
    • 1970-01-01
    • 2012-03-04
    • 2012-06-08
    • 1970-01-01
    • 2014-03-05
    • 2011-01-30
    • 2013-02-06
    • 1970-01-01
    相关资源
    最近更新 更多