Python 使用PySpark高效的文本预处理(清理、标记化、停止字、词干分析、过滤器)

Python 使用PySpark高效的文本预处理(清理、标记化、停止字、词干分析、过滤器),python,apache-spark,pyspark,apache-spark-sql,text-processing,Python,Apache Spark,Pyspark,Apache Spark Sql,Text Processing,最近,我开始在《学习火花》一书上学习火花。理论上,一切都很清楚,在实践中,我首先需要对文本进行预处理,但在这个主题上没有实际的提示 我考虑的第一件事是现在最好使用Dataframe而不是RDD,所以我的预处理尝试是在Dataframe上进行的 所需操作: 清除标点符号regexp\u replace中的文本 标记化标记器 删除停止字停止字删除器 Stematization雪球炮 过滤短词udf 我的代码是: from pyspark.sql import SparkSession from py

最近,我开始在《学习火花》一书上学习火花。理论上,一切都很清楚,在实践中,我首先需要对文本进行预处理,但在这个主题上没有实际的提示

我考虑的第一件事是现在最好使用Dataframe而不是RDD,所以我的预处理尝试是在Dataframe上进行的

所需操作:

清除标点符号regexp\u replace中的文本 标记化标记器 删除停止字停止字删除器 Stematization雪球炮 过滤短词udf 我的代码是:

from pyspark.sql import SparkSession
from pyspark.sql.functions import udf, col, lower, regexp_replace
from pyspark.ml.feature import Tokenizer, StopWordsRemover
from nltk.stem.snowball import SnowballStemmer

spark = SparkSession.builder \
    .config("spark.executor.memory", "3g") \
    .config("spark.driver.cores", "4") \
    .getOrCreate()
df = spark.read.json('datasets/entitiesFull/full').select('id', 'text')

# Clean text
df_clean = df.select('id', (lower(regexp_replace('text', "[^a-zA-Z\\s]", "")).alias('text')))

# Tokenize text
tokenizer = Tokenizer(inputCol='text', outputCol='words_token')
df_words_token = tokenizer.transform(df_clean).select('id', 'words_token')

# Remove stop words
remover = StopWordsRemover(inputCol='words_token', outputCol='words_clean')
df_words_no_stopw = remover.transform(df_words_token).select('id', 'words_clean')

# Stem text
stemmer = SnowballStemmer(language='english')
stemmer_udf = udf(lambda tokens: [stemmer.stem(token) for token in tokens], ArrayType(StringType()))
df_stemmed = df_words_no_stopw.withColumn("words_stemmed", stemmer_udf("words_clean")).select('id', 'words_stemmed')

# Filter length word > 3
filter_length_udf = udf(lambda row: [x for x in row if len(x) >= 3], ArrayType(StringType()))
df_final_words = df_stemmed.withColumn('words', filter_length_udf(col('words_stemmed')))
处理需要很长时间,整个文档的大小为60 GB。使用RDD有意义吗?缓存会有帮助吗?如何优化预处理


首先,我在本地计算机上测试了实现,然后我将在集群上进行尝试。本地计算机-Ubuntu RAM 6Gb,4 CPU。也欢迎任何替代解决方案。谢谢

JSON通常是Spark分析中最差的文件格式,尤其是如果它是一个60GB的JSON文件。Spark适用于1GB拼花文件。稍加预处理会有很大帮助:

temp_df=spark.read.json'datasets/entitiesFull/full'。选择'id','text'。重新分区60 临时拼花地板'some/other/path' df=spark.read.parquet'some/other/path' ... 继续其余的分析 从性能的角度来看,将SnowballStemmer包装在UDF中不是最好的,但最现实的方法是,除非您习惯于用低级Java字节码编写算法。我还使用UDF创建了一个Porter词干算法


给你。实现是可能的,但并不容易。

60Gb仍然是一个非常大的文件,在今天,您所做的处理类型不适合进行数值优化。可能有一些方法可以加快速度,但对我来说,期待几秒钟内的结果听起来过于乐观了。SQL Dataframe over RDDIs There spark版本的SnowballStemmer在任何地方都可用吗?如果有,你可以用这个来提高速度。而且我会尝试使用pyspark的本机函数,而不是使用udf,因为它们比本机函数慢。在这里,您应该能够使用诸如长度和何时得出相同结果之类的函数。对于60gb文件,spark无法并行读取对象,因此这里有一个瓶颈。在阅读之前,您可以重新划分数据帧以获得更好的性能。