【问题标题】:How to optimize preprocess all text documents without using for loop to preprocess a single text document in each iteration?如何优化预处理所有文本文档而不使用 for 循环在每次迭代中预处理单个文本文档?
【发布时间】:2019-01-24 07:05:56
【问题描述】:

我想优化下面的代码,以便它可以有效地处理 3000 个文本数据,然后将这些数据馈送到 TFIDF Vectorizer 和 links() 进行聚类。

到目前为止,我已经使用 pandas 读取了 excel 并将数据框保存到列表变量中。然后我将列表中的每个文本元素迭代为标记,然后从元素中过滤掉停用词。过滤后的元素存储到另一个变量中,并且该变量存储在列表中。所以最后,我创建了一个已处理文本元素的列表(来自列表)。

我认为可以在创建列表、过滤掉停用词以及将数据保存到两个不同的变量时执行优化:documents_no_stopwords 和 processes_words。

如果有人可以帮助我或建议我遵循的方向,那就太好了。

temp=0
df=pandas.read_excel('File.xlsx')

for text in df['text'].tolist():
    temp=temp+1
    preprocessing(text)
    print temp


def preprocessing(word):

    tokens = tokenizer.tokenize(word)

    processed_words = []
    for w in tokens:
        if w in stop_words:
            continue
        else:
    ## a new list is created with only the nouns in them for each text document
            processed_words.append(w)
    ## This step creates a list of text documents with only the nouns in them
    documents_no_stopwords.append(' '.join(processed_words))
    processed_words=[]

【问题讨论】:

  • stop_words 是一组吗?如果没有,把它变成一个。除此之外,坦率地说,在我看来,在预处理下一切都很好。 .append 是常数时间运算,.join 是 O(n)。如果您愿意,您可以在 for w in tokens 步骤期间创建连接输出,但这对您没有太大帮助。

标签: python pandas nlp nltk


【解决方案1】:

您需要先将停用词设为set,然后使用列表推导来过滤标记。

def preprocessing(txt):
    tokens = word_tokenize(txt)
    # print(tokens)
    stop_words = set(stopwords.words("english"))
    tokens = [i for i in tokens if i not in stop_words]

    return " ".join(tokens)

string = "Hey this is Sam. How are you?"
print(preprocessing(string))

输出:

'Hey Sam . How ?'

与其使用for 循环,不如使用df.apply,如下所示:

df['text'] = df['text'].apply(preprocessing)

为什么集合比列表更受欢迎

stopwords.words() 中有重复条目 如果您检查len(stopwords.words())len(set(stopwords.words())) 集合的长度小了几百。这就是为什么这里首选set

以下是使用listset 的性能差异

x = stopwords.words('english')
y = set(stopwords.words('english'))

%timeit new = [i for i in tokens if i not in x]
# 10000 loops, best of 3: 120 µs per loop

%timeit old = [j for j in tokens if j not in y]
# 1000000 loops, best of 3: 1.16 µs per loop

而且list-comprehension 比普通for-loop 更快。

【讨论】:

  • 看起来不错。为什么我们更喜欢 set for stopwords.over 列表?性能会受到怎样的影响?在这种情况下,两者都包含独特的元素,那么为什么集合比列表更好?
  • 我检查了同样的,我发现对于英语,停用词列表的长度和停用词集的长度是相等的。两者都等于 179。不过,更快的列表理解肯定会是一场胜利。
  • @akshit 长度我错了。我已经使用listset 添加了性能基准,我希望现在很清楚为什么setlist 更受欢迎
猜你喜欢
  • 1970-01-01
  • 2011-07-12
  • 2015-01-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-01
  • 2011-03-22
  • 2023-04-05
相关资源
最近更新 更多