我嘗試將filtered_sentence追加到串列wiki_train_lst。我發現洗掉stop_words的步驟很快,但洗掉common_name的速度卻很慢(可能是common_name中的單詞太多)。如何才能快速過濾掉stop_words和common_name?此外,要追加到wiki_train_lst的總內容約為416,000項,這使得追加程序非常緩慢:我怎樣才能優化它?
from nltk.tokenize import RegexpTokenizer
wiki_train_lst = [] 。
for text in wiki_train_df.original_text。
tokenizer = RegexpTokenizer(r'w ')
tokenizer = tokenizer.tokenize(text)
#print(word_tokens)/span>
filtered_sentence = [w.lower() for w in tokenizer if not w.lower() in stop_words] #remove stop words[/span]。
#filtered_sentence = [w for w in filtered_sentence if not w in common_surname_lst or not w in common_name_lst]
filtered_sentence = [w for w in filtered_sentence if not w in common_name_lst] #remove common names[/span]。
filtered_sentence = [w for w in filtered_sentence if w.isalpha() ] #remove non alphabatics words[/span]。
wiki_train_lst.append(filtered_sentence)
#print(filtered_sentence)。
訓練
uj5u.com熱心網友回復:
讓它更快的一個方法是將所有的串列運算式卷成一個:
def my_filter(w)。
w_lower = w.lower()
if w_lower in stop_words:
return False
if w_lower in common_surname_lst
return False[/span
if w_lower in common_name_lst:
return False false
if not w.isalpha()
return False
return True
filtered_sentence = [w.lower() for w in tokenizer if my_filter(w) ]
wiki_train_lst.append(filtered_sentence)
注意,這增加了函式查找的開銷,你可以把函式重新寫成一堆and陳述句:
filtered_sentence = [w for w in tokenizer if w. lower() not in stop_words
and w.lower() not in common_surname_lst
and w.lower() not in common_name_lst
and w.isalpha() ]
現在我們有一堆w.lowers(),讓我們對此做些什么。 我們可以使用一個Generator Expression,它就像一個串列理解,但是很懶:
filtered_sentence = [w for w in (w. lower() for w in tokenizer) if w not in stop_words
and w not in commonly_surname_lst
and w not in common_name_lst
and w.isalpha() ]
更好的方法可能是使用filter:
filtered_sentence = filter(tokenizer, my_filter)
為了提高common_name搜索的速度,首先將串列轉換為set,采用上述方法之一:
common_name_lst = set(common_name_lst
其余的代碼可以保持不變,除非你想重命名變數以使型別更清晰。
最終,如果你需要性能,CPython通常是一個次優的選擇。 有一些方法可以讓它變得更快(參見PyPy或Cython),但您最好用一種更容易優化的語言重新撰寫代碼。
uj5u.com熱心網友回復:
我會做這樣的事情:
from nltk.tokenize import RegexpTokenizer
from itertools import chain
tokenizer = RegexpTokenizer(r'w ')
filter_words = set(chain(stop_words, common_name_lst, common_surname_lst)
def tokenize_text(txt)。 # 回傳一個生成器。
tokenized = tokenizer.tokenize(text)
return (w.lower() for w in tokenized if filters_word(w)
def filter_word(word。str) -> bool:
w = word.lower()
return (w not in filter_words and w.isalpha()
training_list = list(chain.fromiterable((tokenize_text(t) for t in wiki_train_df.original_text) )
這利用了幾項改進(盡管我沒有測驗過,所以可能有一兩個錯誤):
這利用了幾項改進。
- 將每個文本作為一個生成器而不是它自己的串列。這意味著,當它們被添加到最終的串列中時,數值就會被計算出來,從而節省了記憶體分配時間。使用
itertoolschain()函式來平整串列。 - 預先計算一組你想過濾掉的所有單詞。在一個集合中查詢一個值是O(1),而在一個串列中則是O(n)--一個串列的查詢會遍歷每個值,直到它找到該值或用盡該串列。不過,一個集合是由一個哈希表支持的,所以這種預計算可以節省每次迭代的時間。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/323169.html
標籤:
