【问题标题】:Improve Data Preprocessing Speed - Regex in Python提高数据预处理速度 - Python 中的正则表达式
【发布时间】:2021-01-27 14:51:57
【问题描述】:

我在 Python 中使用以下类对字符串进行预处理,然后将其传递给机器学习分类模型以预测其情绪。

我将正则表达式与表情符号和推文预处理器等一些库一起用于大部分转换。该代码运行良好,但我认为它很慢。

你对如何提高它的速度有什么建议吗?

使用示例:

string  = "I am very happy with @easyjet #happy customer ????. Second sentence"
preprocessor = TextPreprocessing()
result = preprocessor.text_preprocessor(string)

结果将是:[“我很高兴拥有幸福的笑脸”、“第二句话”、“我很高兴拥有幸福的笑脸第二句话”]

import re
import preprocessor as p   # this is the tweet-preprocessor library
import emoji
import os
import numpy as np
import pandas as pd

class TextPreprocessing:
    def __init__(self):
        p.set_options(p.OPT.MENTION, p.OPT.URL)

    # remove punctuation
    def _punctuation(self, val):
        val = re.sub(r'[^\w\s]', ' ', val)
        val = re.sub('_', ' ', val)
        return val

    #remove white spaces
    def _whitespace(self, val):
        return " ".join(val.split())

    #remove numbers
    def _removenumbers(self, val):
        val = re.sub('[0-9]+', '', val)
        return val

    #remove unicode
    def _remove_unicode(self, val):
        val = unidecode(val).encode("ascii")
        val = str(val, "ascii")
        return val

    #split string into sentenses
    def _split_to_sentences(self, body_text):
        sentences = re.split(
            r"(?<!\w\.\w.)(?<![A-Z][a-z]\.)(?<=\.|\?)\s", body_text)
        return sentences

    # cleaning functions that combines all of the above functions
    def _clean_text(self, val):
        val = val.lower()
        val = self._removenumbers(val)
        val = p.clean(val)
        val = ' '.join(self._punctuation(emoji.demojize(val)).split())
        val = self._remove_unicode(val)
        val = self._whitespace(val)
        return val

    def text_preprocessor(self, body_text):
        body_text_df = pd.DataFrame({"body_text": body_text}, index=[1])
        sentence_split_df = body_text_df.copy()
        sentence_split_df["body_text"] = sentence_split_df["body_text"].apply(
            self._split_to_sentences)

        lst_col = "body_text"
        sentence_split_df = pd.DataFrame(
            {
                col: np.repeat(
                    sentence_split_df[col].values, sentence_split_df[lst_col].str.len(
                    )
                )
                for col in sentence_split_df.columns.drop(lst_col)
            }
        ).assign(**{lst_col: np.concatenate(sentence_split_df[lst_col].values)})[
            sentence_split_df.columns
        ]

        final_df = (
            pd.concat([sentence_split_df, body_text_df])
            .reset_index()
            .drop(columns=["index"])
        )

        final_df["body_text"] = final_df["body_text"].apply(self._clean_text)

        return final_df["body_text"]

这个问题可能与所有希望将 NLP 模型投入生产的数据科学家有关。

【问题讨论】:

    标签: python regex pandas emoji re


    【解决方案1】:

    由于我无法发表评论,我将尝试回答您的问题(在某种程度上):

    1. 您应该阐明如何衡量执行时间的改进。为此使用 timeit 及其重复功能:
    import timeit
    from functools import partial
    ...
    if __name__ == "__main__":
        # http://25.io/toau/audio/sample.txt
        with open("sample.txt") as f:
            text = f.read()
            tp = TextPreprocessing()
            print(min(timeit.Timer(partial(tp.text_preprocessor, text)).repeat(repeat=10, number=1)))
    
    

    您还可以在特定方法上使用 timeit 来检查瓶颈。

    1. 很遗憾,由于 L58 和 L64 中未定义的 np.,我无法运行您的代码示例 所以我无法检验我的假设。你也没有提供样本数据。

    2. 一些一般的想法:

    【讨论】:

    • 我已更新我的代码以包含 np 并包含一个示例。可以举个编译的例子吗?
    • 如果您添加更多详细信息,我很乐意接受您的回答,例如您指的是哪种代码气味?使用我的代码进行编译的示例会很好。
    • 好的,如果文档链接不够:pattern = re.compile(r"_") pattern.sub("", "asdf_asdf")
    • 我认为发布的链接所覆盖的代码有异味。
    猜你喜欢
    • 1970-01-01
    • 2021-12-18
    • 1970-01-01
    • 1970-01-01
    • 2013-06-15
    • 1970-01-01
    • 2021-10-03
    • 2019-05-13
    • 2011-12-03
    相关资源
    最近更新 更多