如何按比例检查短语是否为英语

时间:2019-04-12 16:50:56

标签: pyspark azure-databricks

我需要使用language属性丰富PySpark-Sql中的数据框,该属性基本上告诉每一行纸质标题的语言。我只需要过滤掉英文论文。我有几千万篇论文,所以我需要并行进行。

在集群上安装了库之后,我已经使用名为langdetecthttps://pypi.org/project/langdetect/)的Python库注册了UDF。我正在使用以下代码:

from langdetect import detect

def lang_detector(_s):
  try:
    lan = detect(_s)
  except:
    lan = 'null'
  return lan

detect2 = udf(lang_detector, StringType())

papers_abs_fos_en = papers_abs \
.join(papersFos_L1, "PaperId") \
.withColumn("Lang", detect2(col("PaperTitle"))) \
.filter("Lang =='en'") \
.select("PaperId", "Rank", "PaperTitle", "RefCount", "CitCount", "FoSList")

它可以工作,但即使是大约一千万个标题,它也要花很长时间。我不确定这是归因于langdetect,UDF还是我做错了什么,但我会对任何建议表示感谢!

非常感谢! 保罗

1 个答案:

答案 0 :(得分:0)

谢谢cronoik确认这一点。我最终得到了一个不同的解决方案,它花费了6分钟以上的时间才能处理950万个文档。基本上,我在NLTK的Brown数据集中建立了所有单词的集合,并将其作为广播变量分发到节点。然后,我为数据框中的每个文档计算了该集中出现的单词所占的比例。如果> 75%,那么我试探性地得出结论,它必须是英语。这是嵌入到UDF中的代码。

from nltk.corpus import brown
import re

bwn = set([x.lower() for x in brown.words()])
bc_brown = sc.broadcast(bwn)

def is_en(_s):
  tok = set(re.findall(r"\w+", _s.lower()))
  return len(tok & bc_brown.value) / len(tok)

isEn = udf(is_en)

papers_abs_fos_en = papers_abs \
.join(papersFos_L1, "PaperId") \
.filter(isEn(col("PaperTitle")) > 0.75) \
.select("PaperId", "Rank", "PaperTitle", "RefCount", "CitCount", "FoSList")