【问题标题】:Fastest way to classify surnames in python在python中分类姓氏的最快方法
【发布时间】:2016-11-27 14:32:38
【问题描述】:

我有一个来自人口普查的 12K 亚洲姓氏列表和一个包含 200K 名字的列表。我想根据他们的姓氏是否出现在我的 12K 名单上,将这 200K 人分类为亚洲人或非亚洲人。

有没有一种快速的方法来验证列表中的元素之一是否包含 12K 列表中的姓氏之一?

【问题讨论】:

  • 从您的姓氏列表中创建set,然后创建test for membership
  • 考虑名字是有社会偏见的->种族,甚至动机种族分类本身也相当令人不安:techcrunch.com/2015/08/02/…fatml.org/cfp.html
  • OP 也会有一些模棱两可的分类,比如 Lee 或 Long。非亚洲人也可以有这些名字。
  • 如果他们是姓Scotts这样的美籍华人怎么办?

标签: python nlp classification nltk


【解决方案1】:

取决于您所说的“快速”。

James 建议使用 Python 的内置 set 来测试成员资格。 Python 的set 实现使用哈希表。 平均时间复杂度为 O(1),但最坏的情况可能为 O(n),其中 n 是亚洲姓氏集的基数。因此,在最坏的情况场景中,您可能会以 O(mn) 而不是 O(m) 结束,其中 m 是要分类的名称集的基数。

参考见:https://wiki.python.org/moin/TimeComplexity

如果你想保证最坏的情况,你可以通过对集合n进行排序并进行二分搜索来实现。这最终会得到 O(m lg n) 的时间复杂度。

二分查找:https://docs.python.org/3.1/library/bisect.html

这实际上取决于散列函数对您的数据的效果。

【讨论】:

  • 请添加为什么您的解决方案是最快的。根据James 的回答,对于这个特定问题,您的方法可能会很慢。
  • @NanderSpeerstra 我已经编辑了答案。基本上这是最坏情况的保证。
  • 当您对字符串进行哈希处理时,遇到最坏情况的可能性微乎其微。 除非您正在编写自己的哈希函数,否则您不太可能遇到最坏的情况 - 内置的 has 函数肯定足以处理字符串。我删除了我的反对票,因为你的回答现在确实增加了一些东西,但值得一提的是,提问者遇到这种最坏的情况在天文上不太可能。
【解决方案2】:

执行此操作的最佳方法是将 12K 列表转换为集合数据结构。然后您可以遍历人口普查数据并检查每个数据是否都在集合中。

# O(n) where n is the length of the surname_list
surname_set = set(surname_list)

for name in census:
    # This is now O(1) operation
    if name in surname_set:
        do whatever...

这几乎肯定是用 Python 或任何语言完成所需任务的最快方法,并且在 200K 大小的列表中应该相当快。

Wai Leong Yeow 建议使用二分搜索,这比直接检查列表要快,但这仍然是对 200K 不同名称的 O(log n) 操作,其中 N 是 12,000,这意味着它可能会超过仅迭代部分慢 10 倍(这是一种简化 - 实际上有一些常量因素被大 O 表示法掩盖,但常量时间解决方案肯定更快)。排序需要 O(n log n) 时间,而将其转换为一个集合需要 O(n) 时间,这意味着该方法的预处理速度也更快。

【讨论】:

    【解决方案3】:

    我建议在训练任何机器学习模型之前的第一步中使用local sensitive hashing。这可能会有所帮助,因为您没有很多功能。如果你想要更强大的东西,你可以使用朴素贝叶斯和一些特征工程。

    【讨论】:

      【解决方案4】:

      这取决于您的实际问题。您是否希望机器学习(如您标记:分类)来预测亚洲/非亚洲名称?

      如果是:尝试一些半监督方法。为此,首先从 200k 数据中随机选择(接近 10%),然后在 12k 中搜索它,如果存在,将其标记为 1,否则将其标记为 0。然后使用一些分类算法,如随机森林、SVM或 KNN。你也可以为你的名字建模,比如 Bag Of word(在你的问题 Bag Of Letter 中!或类似的东西):https://en.wikipedia.org/wiki/Bag-of-words_model

      对于分类任务,看看 scikit-learn lib:http://scikit-learn.org/


      如果否(您不想使用机器学习解决方案): 存在一些快速字符串搜索算法,可以使用一些技术在其他字符串的语料库中搜索字符串。有很多算法,比如Boyer Moore:https://en.wikipedia.org/wiki/Boyer%E2%80%93Moore_string_search_algorithm

      更多细节,这很好:https://softwareengineering.stackexchange.com/questions/183725/which-string-search-algorithm-is-actually-the-fastest

      【讨论】:

      • 训练模型以模拟在您已有的列表中查找单词有什么意义?如果您想训练模型,请找到同样可能是假阴性的负数据。如果你想做直接的字符串匹配,有一个更简单的解决方案:set()
      • @alexis,正如我所提到的,这取决于一个问题,例如您想每秒分类 200k 名称并希望尽可能快地检索结果(因为用户问“最快的方法'),我提到了'it Depend'
      • 您是说统计分类器会比在集合中查找更快吗?那是不可能的。
      • @alexis 几乎没有,但有时你没有查找表
      • 问题说明有一个查找表,而您的答案需要一个。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-21
      • 2017-06-05
      • 2012-01-02
      • 2016-02-22
      • 1970-01-01
      相关资源
      最近更新 更多