簡體   English   中英

有沒有更快的方法來預處理 Python 中的大量文本數據?

[英]Is there a faster way to preprocess huge amount of text data in Python?

我正在構建情緒分析算法來預測 IMDb 評論的分數。 我想從頭開始,所以我收集了 50 萬條評論並創建了自己的數據集。

我正在將小型評論包(包含 50 條評論)發送到帶有池的 review_cleaner。 它幫助我將 1000 條評論的運行時間從 40 分鍾減少到 11 分鍾。 但是,我有 50 萬條評論,我需要更快的方法來處理它們。 我在想是否可以在我的 GPU (GTX1060 6GB) 上運行它? 我安裝了 CUDA,但我找不到如何在 GPU 內核上運行特定功能(review_cleaner)。

基本上,我需要的是更快地運行預處理的解決方案。 我搜索並嘗試了許多不同的東西,但無法做到。 有什么方法可以更快地運行它嗎?

def filling_the_database(review_data): 
    try:
        c.executemany("""INSERT INTO preprocessed_reviews(review, review_score) VALUES (?, ?)""", review_data)
        conn.commit()
    except Error as e:
        print(e)


def get_wordnet_pos(word):
    """Map POS tag to first character lemmatize() accepts"""
    tag = nltk.pos_tag([word])[0][1][0].upper()
    tag_dict = {"J": wordnet.ADJ,
                "N": wordnet.NOUN,
                "V": wordnet.VERB,
                "R": wordnet.ADV}

    return tag_dict.get(tag, wordnet.NOUN)


def review_cleaner(review):
    lemmatizer = WordNetLemmatizer()
    new_review_data = ()
    bulk_data = []
    for each in review:
        review_temp = ''.join([i for i in each[0] if not i.isdigit()])
        review_temp = REPLACE_NO_SPACE.sub(" ", review_temp.lower())
        review_temp = nltk.word_tokenize(review_temp)
        review_temp = (lemmatizer.lemmatize(word, get_wordnet_pos(word)) for word in review_temp)
        review_temp = ' '.join([word for word in review_temp if word not in stopwords.words('english')])
        new_review_data = (review_temp, each[1])
        bulk_data.append(new_review_data)
    filling_the_database(bulk_data)


if __name__ == "__main__":
    review_data = ()
    bulk_data = []
    amount_of_reviews = 0
    previous_amount = 0
    conn = create_connection('2020-04-11')
    c = conn.cursor()
    c.execute("""CREATE TABLE IF NOT EXISTS preprocessed_reviews(review TEXT, review_score INTEGER, ID PRIMARY KEY)""")
    conn.commit()
    total_number_of_reviews = c.execute("""SELECT COUNT(*) FROM movie_reviews""")
    for each in total_number_of_reviews:
        total_number_of_reviews = each[0]
    while amount_of_reviews < total_number_of_reviews:
        review_package = []
        amount_of_reviews += 50
        data = c.execute("""SELECT * FROM movie_reviews WHERE ID BETWEEN (?) AND (?)""", (previous_amount, amount_of_reviews-1))
        conn.commit()
        previous_amount = amount_of_reviews
        for each in data:
            review_data = (each[0], each[1])
            review_package.append(review_data)
            del review_data
        bulk_data.append(review_package)
        del review_package
        print(amount_of_reviews)
    p = Pool(4)
    p.map(review_cleaner, bulk_data)
    p.close()
    print('---- %s seconds ----' % (time.time() - start_time))

我在 SQLite 數據庫中存儲了大約一百萬(400k)條評論。 一欄為評論,一欄為評論的分數。 在另一個表中,我以相同的方式插入預處理的評論,一列用於評論,一列用於評分。 我有 16 GB 的 RAM、Intel i7 6700HQ、SSD 和 GTX1060 6GB。

一些想法掠過我的腦海。

  1. 從 SQLite 讀取和寫入可能會有相當多的開銷,而實際上您可以在 16GB 內存中容納 500k 條評論。 為此,您可以將數據轉儲到表格 csv 文件中,然后使用 pandas 將其讀入以進行預處理。 您還可以使用 pandarallel 來並行化工作,而不是使用 pool 來讓您的生活更輕松。

  2. 如果 SQLite 不是瓶頸,那么它可能是計算瓶頸,在這種情況下,我會考慮在一夜之間運行該過程,或者租用具有良好 cpu 資源的雲計算實例。 一台 16 核的機器在 AWS 上租用很短的時間不會太貴,這會給你理論上的 4 倍加速。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM