From 97e3bb0a179aa3a8ce28081728accdb95bd8de85 Mon Sep 17 00:00:00 2001 From: Rehan Fazal Date: Sat, 17 Aug 2024 18:24:51 +0200 Subject: [PATCH 1/2] Develop (#32) * Intial commit of squeaky clean text * updated the sct.py script with modular code * updated the sct.py script with pipeline method, which would ideally would help to make changes in the processing easier * removed unnecessary direction code * adding to do list * adding to do list * added requiremnt.txt file * added setup.py file * added test cases * updated config file * merging back * Develop (#2) (#3) * Intial commit of squeaky clean text * updated the sct.py script with modular code * updated the sct.py script with pipeline method, which would ideally would help to make changes in the processing easier * removed unnecessary direction code * adding to do list * adding to do list * added requiremnt.txt file * added setup.py file * added test cases * updated config file * merging back * rebase * update the license * added German and Spanish support * Updated file for pypi * Updated readme file * Add GitHub Actions workflow for publishing to PyPI * Updated readme file * Updated readme file * added the username to the publish.yml * update the API vriable name * update the API user name * Bump version to 0.1.1 * updated the readme file * updated the version * Update NER Process and added tag removal * Updated congig file * updated the code to have the option to not output language * fixed the bug for NER which was refrencing to the wrong model variable names, add the gpu support * fixed the Anonomyser Engine * fixed the Anonomyser Engine * added the test.yml file * added the test.yml file * added the test.yml file * added the German and Spanish language support in lingua * added the ability in the config to change the model name * added the ability in the config to change the model name * added the ability in the config to change the model name and fixed spanish model name * squased some bugs * added the language passing support * Refactored the code * fixed typing issue * reverted the refactor --- sct/config.py | 91 +++++----------- sct/sct.py | 238 +++-------------------------------------- sct/utils/constants.py | 11 +- sct/utils/contact.py | 88 +++++---------- sct/utils/datetime.py | 19 +--- sct/utils/ner.py | 225 ++++++++------------------------------ sct/utils/normtext.py | 117 +++++--------------- sct/utils/special.py | 99 ++++------------- sct/utils/stopwords.py | 49 ++------- setup.py | 2 +- 10 files changed, 174 insertions(+), 765 deletions(-) diff --git a/sct/config.py b/sct/config.py index b95d6a4..323d872 100644 --- a/sct/config.py +++ b/sct/config.py @@ -1,100 +1,57 @@ """ -Module containing the configuration parameters for the SCT package. + detect_language : to detect the language automatically, but would consume more time if done on a batch + fix_bad_unicode : if True, fix "broken" unicode such as mojibake and garbled HTML entities + to_ascii_unicode : if True, convert non-to_ascii characters into their closest to_ascii equivalents + replace_with_url : special URL token, default "", + replace_with_email : special EMAIL token, default "", + replace_years : replace year, default "", + replace_with_phone_number : special PHONE token, default "", + replace_with_number : special NUMBER token, default "", + no_currency_symbols : if True, replace all currency symbols with the respective alphabetical ones, + ner_process : To execute NER Process to remove the positpositional tags, PER, LOC, ORG, MISC + remove_isolated_letters : remove any isolated letters which doesn't add any value to the text + remove_isolated_symbols : remove any isolated symbols which shouldn't be present in the text, usually which isn't + immediatly prefixed and suffixed by letter or number + normalize_whitespace : remove any unnecessary whitespace + statistical_model_processing : to get the statistical model text, like for fastText, SVM, LR etc + casefold : to lower the text + remove_stopwords : remove stopwords based on the language, usues NLTK stopwords + remove_punctuation : removes all the special symbols """ -# Flag to detect the language automatically. If True, the language will be detected for each text. CHECK_DETECT_LANGUAGE = True - -# Flag to fix "broken" unicode such as mojibake and garbled HTML entities. CHECK_FIX_BAD_UNICODE = True - -# Flag to convert non-ASCII characters into their closest ASCII equivalents. CHECK_TO_ASCII_UNICODE = True - -# Flag to replace HTML tags with a special token. CHECK_REPLACE_HTML = True - -# Flag to replace URLs with a special token. CHECK_REPLACE_URLS = True - -# Flag to replace email addresses with a special token. CHECK_REPLACE_EMAILS = True - -# Flag to replace years with a special token. CHECK_REPLACE_YEARS = True - -# Flag to replace phone numbers with a special token. CHECK_REPLACE_PHONE_NUMBERS = True - -# Flag to replace numbers with a special token. CHECK_REPLACE_NUMBERS = True - -# Flag to replace currency symbols with their respective alphabetical equivalents. CHECK_REPLACE_CURRENCY_SYMBOLS = True - -# Flag to execute Named Entity Recognition (NER) to remove positional tags such as PER, LOC, ORG, MISC. CHECK_NER_PROCESS = True - -# Flag to remove any isolated letters which do not add any value to the text. CHECK_REMOVE_ISOLATED_LETTERS = True - -# Flag to remove any isolated symbols which should not be present in the text. CHECK_REMOVE_ISOLATED_SPECIAL_SYMBOLS = True - -# Flag to remove any unnecessary whitespace. CHECK_NORMALIZE_WHITESPACE = True - -# Flag to get the statistical model text, such as for fastText, SVM, LR. CHECK_STATISTICAL_MODEL_PROCESSING = True - -# Flag to convert all characters to lowercase. CHECK_CASEFOLD = True - -# Flag to remove stopwords based on the language. Uses NLTK stopwords. CHECK_REMOVE_STOPWORDS = True - -# Flag to remove all special symbols. CHECK_REMOVE_PUNCTUATION = True - -# Flag to remove custom stopwords specific to the SCT package. CHECK_REMOVE_STEXT_CUSTOM_STOP_WORDS = True - -# Special token to replace URLs. REPLACE_WITH_URL = "" - -# Special token to replace HTML tags. REPLACE_WITH_HTML = "" - -# Special token to replace email addresses. REPLACE_WITH_EMAIL = "" - -# Special token to replace years. REPLACE_WITH_YEARS = "" - -# Special token to replace phone numbers. REPLACE_WITH_PHONE_NUMBERS = "" - -# Special token to replace numbers. REPLACE_WITH_NUMBERS = "" - -# Special token to replace currency symbols. If None, symbols will be replaced with their 3-letter abbreviations. REPLACE_WITH_CURRENCY_SYMBOLS = None - -# List of positional tags to be removed by NER. POSITIONAL_TAGS = ['PER', 'LOC', 'ORG'] - -# Confidence threshold for NER. NER_CONFIDENCE_THRESHOLD = 0.85 - -# Language to be used for NER. If None, the language will be detected automatically. LANGUAGE = None -# List of pre-trained NER models in order of importance. -NER_MODELS_LIST = [ - "FacebookAI/xlm-roberta-large-finetuned-conll03-english", # English Model - "FacebookAI/xlm-roberta-large-finetuned-conll02-dutch", # Dutch Model - "FacebookAI/xlm-roberta-large-finetuned-conll03-german", # German Model - "FacebookAI/xlm-roberta-large-finetuned-conll02-spanish", # Spanish Model - "Babelscape/wikineural-multilingual-ner" # Multilingual Model -] - +# Order of the model is Important : English Model, Dutch Model, German Model, Spanish Model, MULTILINGUAL Model +NER_MODELS_LIST = ["FacebookAI/xlm-roberta-large-finetuned-conll03-english", + "FacebookAI/xlm-roberta-large-finetuned-conll02-dutch", + "FacebookAI/xlm-roberta-large-finetuned-conll03-german", + "FacebookAI/xlm-roberta-large-finetuned-conll02-spanish", + "Babelscape/wikineural-multilingual-ner"] diff --git a/sct/sct.py b/sct/sct.py index 5ccdcc6..8e1b08d 100644 --- a/sct/sct.py +++ b/sct/sct.py @@ -9,46 +9,30 @@ class TextCleaner: def __init__(self): - """ - Initialize the TextCleaner object and setup the pipeline. - """ - - # Initialize all the pipeline steps - self.ProcessContacts = contact.ProcessContacts() # Handles contact processing - self.ProcessDateTime = datetime.ProcessDateTime() # Handles datetime processing - self.ProcessSpecialSymbols = special.ProcessSpecialSymbols() # Handles special symbols processing - self.NormaliseText = normtext.NormaliseText() # Handles text normalization - self.ProcessStopwords = stopwords.ProcessStopwords() # Handles stopwords processing - self.GeneralNER = ner.GeneralNER() # Handles named entity recognition - - # Initialize the pipeline and language - self.pipeline = [] # Stores the pipeline steps - self.language = None # Stores the language of the text - - # Initialize the pipeline + self.ProcessContacts = contact.ProcessContacts() + self.ProcessDateTime = datetime.ProcessDateTime() + self.ProcessSpecialSymbols = special.ProcessSpecialSymbols() + self.NormaliseText = normtext.NormaliseText() + self.ProcessStopwords = stopwords.ProcessStopwords() + self.GeneralNER = ner.GeneralNER() + self.pipeline = [] + self.language = None self.init_pipeline() def init_pipeline(self): - """ - Initialize pipeline steps based on config - """ - - # If the language is specified in the config, set it + # Initialize pipeline steps based on config language_config = config.LANGUAGE.lower() if config.LANGUAGE else None + if language_config and language_config in resources.LANGUAGE_NAME: self.language = language_config.upper() - - # Add the detect language step if any of the following are True - if any([config.CHECK_DETECT_LANGUAGE, config.CHECK_NER_PROCESS, config.CHECK_REMOVE_STOPWORDS]): + elif any([config.CHECK_DETECT_LANGUAGE, config.CHECK_NER_PROCESS, config.CHECK_REMOVE_STOPWORDS]): self.pipeline.append(self.detect_language) - # Add the Unicode fix steps if any of the following are True if config.CHECK_FIX_BAD_UNICODE: self.pipeline.append(self.fix_bad_unicode) if config.CHECK_TO_ASCII_UNICODE: self.pipeline.append(self.to_ascii_unicode) - # Add the replace steps if any of the following are True if config.CHECK_REPLACE_HTML: self.pipeline.append(self.replace_html) if config.CHECK_REPLACE_URLS: @@ -64,11 +48,9 @@ def init_pipeline(self): if config.CHECK_REPLACE_CURRENCY_SYMBOLS: self.pipeline.append(self.replace_currency_symbols) - # Add the NER step if any of the following are True if config.CHECK_NER_PROCESS: self.pipeline.append(self.ner_process) - # Add the remove isolated steps if any of the following are True if config.CHECK_REMOVE_ISOLATED_LETTERS: self.pipeline.append(self.remove_isolated_letters) if config.CHECK_REMOVE_ISOLATED_SPECIAL_SYMBOLS: @@ -91,251 +73,57 @@ def process(self, text): return text def detect_language(self, text): - """ - Detects the language of the input text and sets the language attribute. - - Args: - text (str): The input text to detect the language of. - - Returns: - str: The input text. - """ - # Detect the language of the text - detected_language = str(resources.DETECTOR.detect_language_of(text)).split(".")[-1] - - # Set the language attribute to the detected language - self.language = detected_language - - # Return the input text + self.language = str(resources.DETECTOR.detect_language_of(text)).split(".")[-1] return text def fix_bad_unicode(self, text): - """ - Fixes broken unicode text using the `ftfy` library. - - This function fixes various issues with unicode text, including mojibake, HTML entities, and other code cruft. - It also normalizes the text to a specified format, which can improve the readability and consistency of the text. - - Args: - text (str): The raw text to be fixed. - - Returns: - str: The fixed and normalized text. - """ - # Call the fix_bad_unicode method of NormaliseText class to fix the text return self.NormaliseText.fix_bad_unicode(text) def to_ascii_unicode(self, text): - """ - Transliterate unicode text into ascii characters. - - This function uses the `to_ascii_unicode` method of the `NormaliseText` class to transliterate the text. - - Args: - text (str): The input text to transliterate. - - Returns: - str: The transliterated text. - """ - # Call the to_ascii_unicode method of the NormaliseText class to transliterate the text return self.NormaliseText.to_ascii_unicode(text) def replace_html(self, text): - """ - Replace all HTML tags in the given text with the specified replacement string. - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text with all HTML tags replaced. - """ - # Call the replace_html method of the ProcessContacts class to replace HTML tags in the text return self.ProcessContacts.replace_html(text, replace_with=config.REPLACE_WITH_HTML) def replace_urls(self, text): - """ - Replace all URLs in the given text with the specified replacement string. - - This function uses the `replace_urls` method of the `ProcessContacts` class to replace URLs in the text. - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text with all URLs replaced. - """ - # Call the replace_urls method of the ProcessContacts class to replace URLs in the text return self.ProcessContacts.replace_urls(text, replace_with=config.REPLACE_WITH_URL) def replace_emails(self, text): - """ - Replace all email addresses in the given text with the specified replacement string. - - This function uses the `replace_emails` method of the `ProcessContacts` class to replace email addresses in the text. - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text with all email addresses replaced. - """ - # Call the replace_emails method of the ProcessContacts class to replace email addresses in the text return self.ProcessContacts.replace_emails(text, replace_with=config.REPLACE_WITH_EMAIL) def replace_years(self, text): - """ - Replace all years in the given text with the specified replacement string. - - This function uses the `replace_years` method of the `ProcessDateTime` class to replace years in the text. - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text with all years replaced. - """ - # Call the replace_years method of the ProcessDateTime class to replace years in the text return self.ProcessDateTime.replace_years(text, replace_with=config.REPLACE_WITH_YEARS) def replace_phone_numbers(self, text): - """ - Replace all phone numbers in the given text with the specified replacement string. - - This function uses the `replace_phone_numbers` method of the `ProcessContacts` class to replace phone numbers in the text. - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text with all phone numbers replaced. - """ - # Call the replace_phone_numbers method of the ProcessContacts class to replace phone numbers in the text return self.ProcessContacts.replace_phone_numbers(text, replace_with=config.REPLACE_WITH_PHONE_NUMBERS) def replace_numbers(self, text): - """ - Replace all numbers in the given text with the specified replacement string. - - This function uses the `replace_numbers` method of the `ProcessContacts` class to replace numbers in the text. - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text with all numbers replaced. - """ - # Call the replace_numbers method of the ProcessContacts class to replace numbers in the text return self.ProcessContacts.replace_numbers(text, replace_with=config.REPLACE_WITH_NUMBERS) def replace_currency_symbols(self, text): - """ - Replace all currency symbols in the given text with the specified replacement string. - - This function uses the `replace_currency_symbols` method of the `ProcessSpecialSymbols` class to replace currency symbols in the text. - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text with all currency symbols replaced. - """ - # Call the replace_currency_symbols method of the ProcessSpecialSymbols class to replace currency symbols in the text return self.ProcessSpecialSymbols.replace_currency_symbols(text, replace_with=config.REPLACE_WITH_CURRENCY_SYMBOLS) def ner_process(self, text): - """ - Execute named entity recognition (NER) to remove the positional tags from the text. - - Args: - text (str): The input text to be processed. - config.POSITIONAL_TAGS (list): The positional tags to be removed from the text. - config.NER_CONFIDENCE_THRESHOLD (float): The confidence threshold for the NER model. - self.language (str): The language of the text. - - Returns: - str: The processed text with the positional tags removed. - """ return self.GeneralNER.ner_process(text, config.POSITIONAL_TAGS, config.NER_CONFIDENCE_THRESHOLD, self.language) def remove_isolated_letters(self, text): - """ - Removes any isolated letters which doesn't add any value to the text. - - This method uses the `remove_isolated_letters` method of the `ProcessSpecialSymbols` class to remove isolated letters from the input text. - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text with isolated letters removed. - """ - # Call the remove_isolated_letters method of the ProcessSpecialSymbols class to remove isolated letters from the text return self.ProcessSpecialSymbols.remove_isolated_letters(text) def remove_isolated_special_symbols(self, text): - """ - Removes any isolated special symbols which doesn't add any value to the text. - - This method uses the `remove_isolated_special_symbols` method of the `ProcessSpecialSymbols` class to remove isolated special symbols from the input text. - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text with isolated special symbols removed. - """ - # Call the remove_isolated_special_symbols method of the ProcessSpecialSymbols class to remove isolated special symbols from the text return self.ProcessSpecialSymbols.remove_isolated_special_symbols(text) def normalize_whitespace(self, text): - """ - Normalize whitespace in the given text. - - This function replaces one or more spacings with a single space, and one - or more line breaks with a single newline. Also, it strips leading/trailing whitespace. - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text with normalized whitespace. - """ - # Call the normalize_whitespace method of the NormaliseText class to normalize whitespace in the text - # Set no_line_breaks flag to True to remove all line breaks return self.NormaliseText.normalize_whitespace(text, no_line_breaks=True) def statistical_model_processing(self, text): - """ - Process the given text for classical/statistical machine learning models. - - This function applies the following processing steps to the input text: - 1. Case folding (lowercase) - 2. Stopword removal - 3. Punctuation removal - 4. Removing isolated letters - 5. Normalizing whitespace - - Args: - text (str): The input text to be processed. - - Returns: - str: The processed text. - """ - stext = text if config.CHECK_CASEFOLD: - # Convert the text to lowercase - stext = text.casefold() + stext = text.casefold() # lowercase if config.CHECK_REMOVE_STOPWORDS: - # Remove stopwords from the text stext = self.ProcessStopwords.remove_stopwords(stext, self.language) if config.CHECK_REMOVE_PUNCTUATION: - # Remove punctuation from the text stext = self.ProcessSpecialSymbols.remove_punctuation(stext) if config.CHECK_REMOVE_ISOLATED_LETTERS: - # Remove isolated letters from the text stext = self.ProcessSpecialSymbols.remove_isolated_letters(stext) if config.CHECK_NORMALIZE_WHITESPACE: - # Normalize whitespace in the text stext = self.NormaliseText.normalize_whitespace(stext) return stext \ No newline at end of file diff --git a/sct/utils/constants.py b/sct/utils/constants.py index d57b950..1087256 100644 --- a/sct/utils/constants.py +++ b/sct/utils/constants.py @@ -36,6 +36,14 @@ flags=re.IGNORECASE | re.UNICODE, ) +# for more information: https://github.com/jfilter/clean-text/issues/10 +# PHONE_REGEX = re.compile( +# r"((?:^|(?<=[^\w)]))(((\+?[01])|(\+\d{2}))[ .-]?)?(\(?\d{3,4}\)?/?[ .-]?)?(\d{3}[ .-]?\d{4})(\s?(?:ext\.?|[#x-])\s?\d{2,6})?(?:$|(?=\W)))|\+?\d{4,5}[ .-/]\d{6,9}" +# ) +# PHONE_REGEX = re.compile( +# r"((?:^|(?<=[^\w)]))((\+?[01]|0{1,2}\d{0,1}|\+\d{2})[ .-]?)?(\(?\d{3,4}\)?/?[ .-]?)?(\d{3}[ .-]?\d{4})(\s?(?:ext\.?|[#x-])\s?\d{2,6})?(?:$|(?=\W)))|\+?\d{4,5}[ .-/]\d{6,9}" +# ) + PHONE_REGEX = re.compile( r"((?:^|(?<=[^\w)]))((\+?\d+|0{1,2}\d*?)[ .-]?)?(\(?\d{3,4}\)?/?[ .-]?)?(\d{3}[ .-]?\d{4})(\s?(?:ext\.?|[#x-])\s?\d{2,6})?(?:$|(?=\W)))|\+?\d{4,5}[ .-/]\d{6,9}" ) @@ -108,7 +116,6 @@ "〟", """, ] - strange_single_quotes = ["‘", "‛", "’", "❛", "❜", "`", "´", "‘", "’"] DOUBLE_QUOTE_REGEX = re.compile("|".join(strange_double_quotes)) @@ -120,4 +127,4 @@ ISOLATED_SPECIAL_SYMBOLS_REGEX = re.compile(r"(?<;·}@~!?+#)({,/\\\\^]+(?![a-zA-Z0-9])", flags=re.UNICODE | re.IGNORECASE) -SENTENCE_BOUNDARY_PATTERN = re.compile('(?<=[.!?])\s+(?=[^\d])') +SENTENCE_BOUNDARY_PATTERN = re.compile('(?<=[.!?])\s+(?=[^\d])') \ No newline at end of file diff --git a/sct/utils/contact.py b/sct/utils/contact.py index 3d189f5..8ea4df4 100644 --- a/sct/utils/contact.py +++ b/sct/utils/contact.py @@ -6,83 +6,45 @@ class ProcessContacts: def __init__(self): pass - def replace_urls(self, input_text: str, replacement: str = "") -> str: + def replace_urls(self, text, replace_with=""): """ - Replace all URLs in the given input text with the specified replacement string. - - Args: - input_text (str): The input text to be processed. - replacement (str, optional): The string to replace URLs with. Defaults to "". - - Returns: - str: The processed text with all URLs replaced. + Replace all URLs in ``text`` str with ``replace_with`` str. """ - return constants.URL_REGEX.sub(replacement, input_text) + # matches = constants.URL_REGEX.finditer(text) + # result = text + # # Iterate through matches in reverse order (to avoid index issues) + # for match in reversed(list(matches)): + # # Check if the matched substring contains non-ASCII characters + # if not any(ord(char) > 127 for char in match.group()): + # result = text[:match.start()] + replace_with + text[match.end():] + return constants.URL_REGEX.sub(replace_with, text) - def replace_html(self, text: str, replacement: str = "") -> str: + def replace_html(self, text, replace_with=""): """ - Replaces all HTML tags in the given text with the specified replacement string. - - Args: - text (str): The input text to be processed. - replacement (str, optional): The string to replace HTML tags with. Defaults to "". - - Returns: - str: The processed text with all HTML tags replaced. + Replace all html tags in ``text`` str with ``replace_with`` str. """ try: - # Use BeautifulSoup to parse the HTML and extract the text - cleaned_text = BeautifulSoup(text, 'html.parser').get_text() + soup = BeautifulSoup(text, 'html.parser') + text = soup.get_text() except: - # If BeautifulSoup fails, use the HTML_REGEX to remove HTML tags - cleaned_text = constants.HTML_REGEX.sub(replacement, text) + text = constants.HTML_REGEX.sub(replace_with, text) - return cleaned_text + return text - def replace_emails(self, input_text: str, replacement: str = "") -> str: + def replace_emails(self, text, replace_with=""): """ - Replace all email addresses in the input text with the specified replacement string. - - Args: - input_text (str): The text to be processed. - replacement (str, optional): The string to replace email addresses with. Defaults to "". - - Returns: - str: The processed text with all email addresses replaced. + Replace all emails in ``text`` str with ``replace_with`` str. """ - # Use the pre-compiled regular expression to find all email patterns in the text - # and replace them with the specified replacement string - return constants.EMAIL_REGEX.sub(replacement, input_text) + return constants.EMAIL_REGEX.sub(replace_with, text) - def replace_phone_numbers(self, input_text: str, replacement: str = "") -> str: + def replace_phone_numbers(self, text, replace_with=""): """ - Replaces all occurrences of phone numbers in the input text with a - specified replacement string. - - Args: - input_text (str): The text to be processed. - replacement (str, optional): The string to replace the phone numbers with. - Defaults to "". - - Returns: - str: The modified text with phone numbers replaced. + Replace all phone numbers in ``text`` str with ``replace_with`` str. """ - # Use the pre-compiled regular expression to find all phone number patterns - # in the text and replace them with the specified replacement string - return constants.PHONE_REGEX.sub(replacement, input_text) + return constants.PHONE_REGEX.sub(replace_with, text) - def replace_numbers(self, input_text: str, replacement: str = "") -> str: + def replace_numbers(self, text, replace_with=""): """ - Replace all numbers in the input text with a specified replacement string. - - Args: - input_text (str): The input text. - replacement (str, optional): The string to replace the numbers with. - Defaults to "". - - Returns: - str: The modified text with numbers replaced. + Replace all numbers in ``text`` str with ``replace_with`` str. """ - # Use the pre-compiled regular expression to find all number patterns - # in the text and replace them with the specified replacement string - return constants.NUMBERS_REGEX.sub(replacement, input_text) + return constants.NUMBERS_REGEX.sub(replace_with, text) \ No newline at end of file diff --git a/sct/utils/datetime.py b/sct/utils/datetime.py index ddfa14b..78b330a 100644 --- a/sct/utils/datetime.py +++ b/sct/utils/datetime.py @@ -1,26 +1,15 @@ from sct.utils import constants + class ProcessDateTime: def __init__(self): pass - def replace_years(self, text: str, replacement: str = "") -> str: + def replace_years(self, text, replace_with =""): """ Replaces years between 1900 to 2099 in the text with a special token. - - Args: - text (str): The input text. - replacement (str, optional): The string to replace the years with. - Defaults to "". - - Returns: - str: The modified text with years replaced. """ - # Use the pre-compiled regular expression to find all year patterns - # in the text and replace them with the specified replacement string - - # Substitute all year patterns with special token - cleaned_string = constants.YEAR_REGEX.sub(replacement, text) + cleaned_string = constants.YEAR_REGEX.sub(replace_with, text) - return cleaned_string + return cleaned_string \ No newline at end of file diff --git a/sct/utils/ner.py b/sct/utils/ner.py index 5c9c229..116daaf 100644 --- a/sct/utils/ner.py +++ b/sct/utils/ner.py @@ -21,129 +21,60 @@ class GeneralNER: """ def __init__(self): - """ - Initializes the GeneralNER object. - - This function initializes the GeneralNER object by loading the necessary models and tokenizers. - It sets the device to "cuda" if it is available, otherwise it sets it to "cpu". - It initializes the AnonymizerEngine object. - It loads the NER models and tokenizers based on the configuration. - It sets the minimum token length based on the maximum length of the tokenizers. - It sets the tokenizer based on the maximum length of the tokenizers. - """ - - # Set the device to "cuda" if it is available, otherwise set it to "cpu" + self.device = "cuda" if torch.cuda.is_available() else "cpu" - # Initialize the AnonymizerEngine object self.engine = AnonymizerEngine() - - # Load the NER models and tokenizers based on the configuration + if len(config.NER_MODELS_LIST) == 5: - # Load models from the configuration english_model_name = config.NER_MODELS_LIST[0] dutch_model_name = config.NER_MODELS_LIST[1] german_model_name = config.NER_MODELS_LIST[2] spanish_model_name = config.NER_MODELS_LIST[3] multilingual_model_name = config.NER_MODELS_LIST[4] else: - # Load default models - model_name = [ - "FacebookAI/xlm-roberta-large-finetuned-conll03-english", - "FacebookAI/xlm-roberta-large-finetuned-conll02-dutch", - "FacebookAI/xlm-roberta-large-finetuned-conll03-german", - "FacebookAI/xlm-roberta-large-finetuned-conll02-spanish", - "Babelscape/wikineural-multilingual-ner" - ] + # Load models + model_name = ["FacebookAI/xlm-roberta-large-finetuned-conll03-english", + "FacebookAI/xlm-roberta-large-finetuned-conll02-dutch", + "FacebookAI/xlm-roberta-large-finetuned-conll03-german", + "FacebookAI/xlm-roberta-large-finetuned-conll02-spanish", + "Babelscape/wikineural-multilingual-ner"] + english_model_name = model_name[0] dutch_model_name = model_name[1] german_model_name = model_name[2] spanish_model_name = model_name[3] multilingual_model_name = model_name[4] - - # Load English model and tokenizer + self.en_tokenizer = AutoTokenizer.from_pretrained(english_model_name) self.en_model = AutoModelForTokenClassification.from_pretrained(english_model_name).to(self.device) - self.en_ner_pipeline = pipeline( - "ner", - model=self.en_model, - tokenizer=self.en_tokenizer, - aggregation_strategy="simple" - ) + self.en_ner_pipeline = pipeline("ner", model=self.en_model, tokenizer=self.en_tokenizer, aggregation_strategy="simple") - # Load Dutch model and tokenizer self.nl_tokenizer = AutoTokenizer.from_pretrained(dutch_model_name) self.nl_model = AutoModelForTokenClassification.from_pretrained(dutch_model_name).to(self.device) - self.nl_ner_pipeline = pipeline( - "ner", - model=self.nl_model, - tokenizer=self.nl_tokenizer, - aggregation_strategy="simple" - ) + self.nl_ner_pipeline = pipeline("ner", model=self.nl_model, tokenizer=self.nl_tokenizer, aggregation_strategy="simple") - # Load German model and tokenizer self.de_tokenizer = AutoTokenizer.from_pretrained(german_model_name) self.de_model = AutoModelForTokenClassification.from_pretrained(german_model_name).to(self.device) - self.de_ner_pipeline = pipeline( - "ner", - model=self.de_model, - tokenizer=self.de_tokenizer, - aggregation_strategy="simple" - ) + self.de_ner_pipeline = pipeline("ner", model=self.de_model, tokenizer=self.de_tokenizer, aggregation_strategy="simple") - # Load Spanish model and tokenizer self.es_tokenizer = AutoTokenizer.from_pretrained(spanish_model_name) self.es_model = AutoModelForTokenClassification.from_pretrained(spanish_model_name).to(self.device) - self.es_ner_pipeline = pipeline( - "ner", - model=self.es_model, - tokenizer=self.es_tokenizer, - aggregation_strategy="simple" - ) + self.es_ner_pipeline = pipeline("ner", model=self.es_model, tokenizer=self.es_tokenizer, aggregation_strategy="simple") - # Load Multilingual model and tokenizer self.multi_tokenizer = AutoTokenizer.from_pretrained(multilingual_model_name) self.multi_model = AutoModelForTokenClassification.from_pretrained(multilingual_model_name).to(self.device) - self.multi_ner_pipeline = pipeline( - "ner", - model=self.multi_model, - tokenizer=self.multi_tokenizer, - aggregation_strategy="simple" - ) + self.multi_ner_pipeline = pipeline("ner", model=self.multi_model, tokenizer=self.multi_tokenizer, aggregation_strategy="simple") - # Set the minimum token length based on the maximum length of the tokenizers - self.min_token_length = math.ceil(min( - self.en_tokenizer.max_len_single_sentence, - self.multi_tokenizer.max_len_single_sentence - ) * 0.9) + self.min_token_length = math.ceil(min(self.en_tokenizer.max_len_single_sentence, self.multi_tokenizer.max_len_single_sentence) * 0.9) - # Set the tokenizer based on the maximum length of the tokenizers self.tokenizer = self.en_tokenizer if self.en_tokenizer.max_len_single_sentence <= self.multi_tokenizer.max_len_single_sentence else self.multi_tokenizer def ner_data(self, data, pos): """ - Formats the Named Entity Recognition (NER) data. - - Args: - data (List[Dict[str, Any]]): A list of dictionaries containing entity information. - pos (List[str]): A list of valid entity groups. - - Returns: - List[Dict[str, Any]]: A list of dictionaries with the formatted entity data. + Formats NER (Named Entity Recognition) files. """ - # Filter the data based on the entity group and return the desired keys - return [ - { - 'entity_group': ix['entity_group'], # The entity group - 'score': ix['score'], # The score of the entity - 'word': ix['word'], # The word of the entity - 'key': f"{ix['start']}{ix['end']}", # The unique key for the entity - 'start': ix['start'], # The start position of the entity - 'end': ix['end'] # The end position of the entity - } - for ix in data # Iterate over each entity in the data - if ix['entity_group'] in pos # Check if the entity group is in the valid entity groups - ] + return [{'entity_group': ix['entity_group'], 'score': ix['score'], 'word': ix['word'], 'key': str(ix['start']) + str(ix['end']), 'start': ix['start'], 'end': ix['end']} for ix in data if ix['entity_group'] in pos] def filter_ner_data(self, data, keys): """ @@ -156,19 +87,12 @@ def filter_ner_data(self, data, keys): Returns: list: A list of unique entity data dictionaries with the highest score for each key. """ - # Dictionary to store the unique data with the highest score for each key unique_data = {} - - # Iterate over each item in the data for item in data: - # Check if the key of the item is in the keys if item['key'] in keys: - # Check if the key is already in unique_data - # If it is, compare the scores and update the value if the new score is higher if item['key'] not in unique_data or item['score'] > unique_data[item['key']]['score']: unique_data[item['key']] = item - # Return the values of the unique_data dictionary return list(unique_data.values()) def anonymize_text(self, text, filtered_data): @@ -182,41 +106,21 @@ def anonymize_text(self, text, filtered_data): Returns: str: The anonymized text with entity type tags. """ - # Initialize an empty list to store the RecognizerResult objects - analyzer_result = [] - - # Iterate over each item in the filtered_data - for item in filtered_data: - # Check the entity_group of the item - if item['entity_group'] == 'PER': - # Create a RecognizerResult object with the corresponding entity_type and other attributes - analyzer_result.append(RecognizerResult(entity_type="PERSON", - start=item['start'], - end=item['end'], - score=item['score'])) - elif item['entity_group'] == 'LOC': - # Create a RecognizerResult object with the corresponding entity_type and other attributes - analyzer_result.append(RecognizerResult(entity_type="LOCATION", - start=item['start'], - end=item['end'], - score=item['score'])) - elif item['entity_group'] == 'ORG': - # Create a RecognizerResult object with the corresponding entity_type and other attributes - analyzer_result.append(RecognizerResult(entity_type="ORGANISATION", - start=item['start'], - end=item['end'], - score=item['score'])) - - # Get the length of the text + analyzer_result = list() + for items in filtered_data: + if items['entity_group'] == 'PER': + analyzer_result.append(RecognizerResult(entity_type="PERSON", start=items['start'], end=items['end'], score=items['score'])) + elif items['entity_group'] == 'LOC': + analyzer_result.append(RecognizerResult(entity_type="LOCATION", start=items['start'], end=items['end'], score=items['score'])) + elif items['entity_group'] == 'ORG': + analyzer_result.append(RecognizerResult(entity_type="ORGANISATION", start=items['start'], end=items['end'], score=items['score'])) + text_length = len(text) - - # Filter out the analyzer_result entries that have invalid start or end positions analyzer_result = [entry for entry in analyzer_result if 0 <= entry.start < text_length and 0 < entry.end <= text_length] - - # Replace words in the text with their entity_type tags using the anonymize function of the engine + # Replace words in the text with their entity_type tags return self.engine.anonymize(text=text, analyzer_results=analyzer_result) - def ner_ensemble(self, ner_results: List[Dict[str, Any]], t: float) -> List[Dict[str, Any]]: + def ner_ensemble(self, ner_results, t): """ Applies an ensemble method for NER. @@ -227,95 +131,63 @@ def ner_ensemble(self, ner_results: List[Dict[str, Any]], t: float) -> List[Dict Returns: List[Dict[str, Any]]: A sorted list of dictionaries containing the filtered NER results. """ - # Initialize a dictionary to store the count and sum of scores for each key ner_keys = defaultdict(lambda: [0, 0]) - - # Iterate over each item in the ner_results for entity in ner_results: - # For each item, increment the count and add the score to the sum ner_keys[entity['key']][0] += 1 ner_keys[entity['key']][1] += entity['score'] - # Filter out the keys that have a score below the threshold ner_keys = [key for key, val in ner_keys.items() if val[1] / val[0] >= t] - # Filter out the NER results that have a key not in the ner_keys filter_ner_results = self.filter_ner_data(ner_results, ner_keys) - # Sort the filtered NER results by start position filter_ner_results.sort(key=lambda x: x['start']) - # Return the filtered NER results return filter_ner_results - def ner_process(self, text: str, positional_tags: List[str], ner_confidence_threshold: float, language: str) -> str: - """ - Executes NER Process to remove the positional tags, PER, LOC, ORG, MISC. - + def ner_process(self, text, positional_tags, ner_confidence_threshold, language): + """_summary_ + Executes NER Process to remove the positional tags, PER, LOC, ORG, MISC. Args: - text (str): text from which postional tags need to be recognised + text (string): text from which postional tags need to be recognised positional_tags (list): pass tags as ['PER', 'LOC'] (default), also supports 'ORG', 'MISC' - ner_confidence_threshold (float): NER Confidence - language (str): language model which need to be used, currently supports ENGLISH, DUTCH + ner_confidence_threshold (int): NER Confidence + language (string): language model which need to be used, currently supports ENGLISH, DUTCH Returns: - str: a string of words sorted based on length for the provided positional tags which meets the threshold + list: a list of words sorted based on length for the provided positional tags which meets the threshold """ - # Initialize a list to store the cleaned text - ner_clean_text = [] - - # Get the length of the input text + ner_clean_text = list() + # text length text_token_length = len(self.tokenizer.tokenize(text)) - # Calculate the number of parts the text needs to be split into - num_parts = math.ceil(text_token_length / self.min_token_length) + # parts it need to get split + num_parts = math.ceil(text_token_length/self.min_token_length) - # If the text doesn't need to be split, just add it to the list if num_parts == 0: texts = [text] else: - # Split the text into chunks texts = self.split_text(text, self.min_token_length, self.tokenizer) - # Iterate over each chunk of text for text in texts: - # Initialize a list to store the NER results ner_results = [] - - # Get the NER results for the multi-lingual model ner_results.append(self.ner_data(self.multi_ner_pipeline(text), positional_tags)) - - # Get the NER results for the English model ner_results.append(self.ner_data(self.en_ner_pipeline(text), positional_tags)) - - # If the language is Dutch, get the NER results for the Dutch model if language == 'DUTCH': ner_results.append(self.ner_data(self.nl_ner_pipeline(text), positional_tags)) - - # If the language is German, get the NER results for the German model elif language == 'GERMAN': ner_results.append(self.ner_data(self.de_ner_pipeline(text), positional_tags)) - - # If the language is Spanish, get the NER results for the Spanish model elif language == 'SPANISH': ner_results.append(self.ner_data(self.es_ner_pipeline(text), positional_tags)) - # Flatten the list of NER results + # flat out the list ner_results = list(itertools.chain.from_iterable(ner_results)) - - # Apply the ensemble method to the NER results ner_results = self.ner_ensemble(ner_results, ner_confidence_threshold) - - # Anonymize the text using the filtered NER results ner_text = self.anonymize_text(text, ner_results).text - - # Add the anonymized text to the list ner_clean_text.append(ner_text) - - # Join the cleaned text into a single string and return it + return ' '.join(ner_clean_text) - def split_text(self, text: str, max_tokens: int, tokenizer) -> List[str]: + def split_text(self, text, max_tokens, tokenizer): """ Splits a given text into chunks based on a maximum token limit. @@ -327,32 +199,22 @@ def split_text(self, text: str, max_tokens: int, tokenizer) -> List[str]: Returns: list: A list of text chunks, each containing a maximum of max_tokens tokens. """ - # Find the sentence boundaries in the text sentence_boundaries = [(m.start(), m.end()) for m in constants.SENTENCE_BOUNDARY_PATTERN.finditer(text)] - # Initialize a list to store the text chunks chunks = [] - - # Initialize variables to keep track of the current chunk current_chunk = [] current_token_count = 0 current_position = 0 - # Iterate over the sentence boundaries for boundary_start, boundary_end in sentence_boundaries: - # Get the sentence sentence = text[current_position:boundary_start+1] - # Update the current position current_position = boundary_end - # Get the number of tokens in the sentence token_count = len(tokenizer(sentence)["input_ids"]) - # If the sentence can fit in the current chunk, add it if current_token_count + token_count <= max_tokens: current_chunk.append(sentence) current_token_count += token_count - # Otherwise, create a new chunk else: chunks.append(''.join(current_chunk)) current_chunk = [sentence] @@ -363,5 +225,4 @@ def split_text(self, text: str, max_tokens: int, tokenizer) -> List[str]: current_chunk.append(last_sentence) chunks.append(''.join(current_chunk)) - # Return the list of chunks return chunks \ No newline at end of file diff --git a/sct/utils/normtext.py b/sct/utils/normtext.py index 1003c0d..17f9274 100644 --- a/sct/utils/normtext.py +++ b/sct/utils/normtext.py @@ -11,127 +11,63 @@ def __init__(self): pass - def fix_bad_unicode( - self, - text: str, - normalization: str = "NFC", - ) -> str: + def fix_bad_unicode(self, text, normalization="NFC"): """ - Fixes broken unicode text using the `ftfy` library. - - This function fixes various issues with unicode text, including mojibake, HTML entities, and other code cruft. - It also normalizes the text to a specified format, which can improve the readability and consistency of the text. - + Fix unicode text that's "broken" using `ftfy `_; + this includes mojibake, HTML entities and other code cruft, + and non-standard forms for display purposes. Args: - text (str): The raw text to be fixed. - normalization (str, optional): The normalization form to use. - Defaults to "NFC". - Possible values are: - - "NFC" (Canonical Decomposition, followed by Canonical Composition): - Combines characters and diacritics written using separate code points, - e.g. converting "e" plus an acute accent modifier into "é". - Unicode can be converted to NFC form without any change in its meaning. - - "NFKC" (Compatibility Decomposition, followed by Canonical Composition): - Applies additional normalizations that can change the meanings of characters, - e.g. replacing ellipsis characters with three periods. - - "NFD" (Canonical Decomposition): - Decomposes characters and diacritics written using separate code points. - - "NFKD" (Compatibility Decomposition): - Decomposes characters and diacritics written using separate code points, - and applies additional normalizations. - - Returns: - str: The fixed and normalized text. + text (str): raw text + normalization ({'NFC', 'NFKC', 'NFD', 'NFKD'}): if 'NFC', + combines characters and diacritics written using separate code points, + e.g. converting "e" plus an acute accent modifier into "é"; unicode + can be converted to NFC form without any change in its meaning! + if 'NFKC', additional normalizations are applied that can change + the meanings of characters, e.g. ellipsis characters will be replaced + with three periods """ - # Trying to fix backslash-replaced strings (via https://stackoverflow.com/a/57192592/4028896) + # trying to fix backslash-replaced strings (via https://stackoverflow.com/a/57192592/4028896) try: - # Decode text using the "latin" encoding and "backslashreplace" error handler text = text.encode("latin", "backslashreplace").decode("unicode-escape") except: pass - # Use the fix_text function from the ftfy library to fix the text return fix_text(text, normalization=normalization) - def fix_strange_quotes(self, text: str) -> str: + def fix_strange_quotes(self, text): """ - Replace strange quotes, i.e., with a single quote ' or a double quote " if it fits better. - - Args: - text (str): The text to be processed. - - Returns: - str: The processed text with strange quotes replaced. + Replace strange quotes, i.e., 〞with a single quote ' or a double quote " if it fits better. """ - # Replace single quotes text = constants.SINGLE_QUOTE_REGEX.sub("'", text) - # Replace double quotes text = constants.DOUBLE_QUOTE_REGEX.sub('"', text) return text - def to_ascii_unicode( - self, - text: str, - no_emoji: bool = True, - ) -> str: + def to_ascii_unicode(self, text, no_emoji=True): """ - Transliterate unicode text into ascii characters. - - This function tries to represent unicode data in ascii characters similar to - what a human with a US keyboard would choose. It works great for languages of - Western origin, and gets worse the farther the language gets from Latin-based - alphabets. It's based on hand-tuned character mappings that also contain ascii - approximations for symbols and non-Latin alphabets. - - Args: - text (str): The text to be transliterated. - no_emoji (bool, optional): Flag to indicate whether to remove emojis or not. Defaults to True. - - Returns: - str: The transliterated text. - + Try to represent unicode data in ascii characters similar to what a human + with a US keyboard would choose. + Works great for languages of Western origin, worse the farther the language + gets from Latin-based alphabets. It's based on hand-tuned character mappings + that also contain ascii approximations for symbols and non-Latin alphabets. """ - # Normalize quotes before since this improves transliteration quality. + # normalize quotes before since this improves transliteration quality text = self.fix_strange_quotes(text) - # If no_emoji flag is set to False, remove emojis from the text. if not no_emoji: text = demojize(text, use_aliases=True) - # Convert unicode characters to their ascii approximations. text = unidecode(text) return text - def normalize_whitespace( - self, - text: str, - strip_lines: bool = True, - no_line_breaks: bool = False, - keep_two_line_breaks: bool = False, - ) -> str: + def normalize_whitespace(self, text, strip_lines=True, no_line_breaks=False, keep_two_line_breaks=False): """ - Normalize whitespace in the given text. - - This function replaces one or more spacings with a single space, and one - or more line breaks with a single newline. Also, it strips leading/trailing whitespace. - - Args: - text (str): The input text to be processed. - strip_lines (bool, optional): Flag to indicate whether to strip leading/trailing whitespace from each line. Defaults to True. - no_line_breaks (bool, optional): Flag to indicate whether to remove all line breaks or not. Defaults to False. - keep_two_line_breaks (bool, optional): Flag to indicate whether to keep two consecutive line breaks or not. Defaults to False. - - Returns: - str: The processed text with normalized whitespace. + Given ``text`` str, replace one or more spacings with a single space, and one + or more line breaks with a single newline. Also strip leading/trailing whitespace. """ - - # Strip leading/trailing whitespace from each line if strip_lines flag is set to True. if strip_lines: text = "\n".join([x.strip() for x in text.splitlines()]) - # If no_line_breaks flag is set to True, remove all line breaks. - # Otherwise, replace consecutive line breaks with one newline. if no_line_breaks: text = constants.MULTI_WHITESPACE_TO_ONE_REGEX.sub(" ", text) else: @@ -144,5 +80,4 @@ def normalize_whitespace( " ", constants.LINEBREAK_REGEX.sub(r"\n", text) ) - # Strip leading/trailing whitespace from the final processed text. - return text.strip() + return text.strip() \ No newline at end of file diff --git a/sct/utils/special.py b/sct/utils/special.py index f70a8d3..8259f47 100644 --- a/sct/utils/special.py +++ b/sct/utils/special.py @@ -8,106 +8,43 @@ class ProcessSpecialSymbols: def __init__(self): pass - def replace_currency_symbols( - self, - text: str, - replace_with: str = "" - ) -> str: + def replace_currency_symbols(self, text, replace_with=""): """ - Replaces currency symbols in the given text with the specified replacement string. - + Replace currency symbols in ``text`` str with string specified by ``replace_with`` str. Args: - text (str): The raw text. - replace_with (str, optional): If None (default), replaces symbols with their - standard 3-letter abbreviations (e.g. '$' with 'USD', '£' with 'GBP'). - Otherwise, passes in a string with which to replace all symbols - (e.g. "*CURRENCY*"). - - Returns: - str: The modified text with currency symbols replaced. + text (str): raw text + replace_with (str): if None (default), replace symbols with + their standard 3-letter abbreviations (e.g. '$' with 'USD', '£' with 'GBP'); + otherwise, pass in a string with which to replace all symbols + (e.g. "*CURRENCY*") """ - # If `replace_with` is None, replace symbols with their standard 3-letter abbreviations if replace_with is None: - # Iterate over the keys and values in CURRENCIES - for symbol, abbreviation in constants.CURRENCIES.items(): - # Replace the symbol in the text with its standard abbreviation - text = text.replace(symbol, abbreviation) + for k, v in constants.CURRENCIES.items(): + text = text.replace(k, v) return text - # If `replace_with` is not None, use regular expressions to replace all currency symbols else: - # Use the pre-compiled regular expression CURRENCY_REGEX to find all currency symbols - # in the text and replace them with the specified replacement string return constants.CURRENCY_REGEX.sub(replace_with, text) - def remove_isolated_letters( - self, - text: str - ) -> str: + def remove_isolated_letters(self, text): """ Removes any isolated letters which doesn't add any value to the text. - - Args: - text (str): The raw text to be processed. - - Returns: - str: The modified text with isolated letters removed. """ - # Use the pre-compiled regular expression ISOLATED_LETTERS_REGEX to find all isolated - # letters in the text and replace them with an empty string - cleaned_text: str = constants.ISOLATED_LETTERS_REGEX.sub('', text) + cleaned_text = constants.ISOLATED_LETTERS_REGEX.sub('', text) return cleaned_text - def remove_isolated_special_symbols( - self, - text: str - ) -> str: + def remove_isolated_special_symbols(self, text): """ Removes any isolated symbols which shouldn't be present in the text. - - This includes: - - [] content, usually images or file locations - - {} content, usually HTML links - - Any isolated special symbols which don't add any value to the text - - Args: - text (str): The raw text. - - Returns: - str: The modified text with isolated special symbols removed. """ - # Remove [] content, usually images or file locations - cleaned_text: str = re.sub(r'\[[^\]]+\]', '', text) - # Remove {} content, usually HTML links - cleaned_text: str = re.sub(r'\{[^}]+\}', '', cleaned_text) - # Remove any isolated special symbols which don't add any value to the text - cleaned_text: str = constants.ISOLATED_SPECIAL_SYMBOLS_REGEX.sub('', cleaned_text) - # Remove any remaining isolated special symbols which may have been missed - cleaned_text: str = re.sub(r"(? str: - """ - Removes all punctuation characters from the given text. - - Args: - text (str): The input text. - - Returns: - str: The modified text with punctuation characters removed. - """ - # Create a regular expression pattern of all punctuation characters - # using the string.punctuation string. + def remove_punctuation(self, text): chars = re.escape(string.punctuation) - - # Use re.sub() to replace all occurrences of punctuation characters with an empty string. - # The pattern is created by escaping all punctuation characters using re.escape(). - # The '[' and ']' are added to the pattern to match any character in the set. - # The '+' after the '[' and before the ']' is a quantifier that matches one or more occurrences. - # The '' (empty string) is the replacement string, which replaces all matches with an empty string. - return re.sub('['+chars+']', '', text) + return re.sub('['+chars+']', '',text) \ No newline at end of file diff --git a/sct/utils/stopwords.py b/sct/utils/stopwords.py index 47cc616..089f9d2 100644 --- a/sct/utils/stopwords.py +++ b/sct/utils/stopwords.py @@ -10,53 +10,26 @@ def __init__(self): self.STOP_WORDS_DE = sw.words('german') self.STOP_WORDS_ES = sw.words('spanish') - def remove_stopwords(self, text: str, lan: str) -> str: + def remove_stopwords(self, text, lan): """ Removes stopwords based on the language. - - Parameters: - text (str): The input text to have stopwords removed from. - lan (str): The language of the text. - - Returns: - str: The text with all stopwords removed. """ + if lan == 'DUTCH': + stop_words = self.STOP_WORDS_NL + elif lan == 'ENGLISH': + stop_words = self.STOP_WORDS_EN + elif lan == 'GERMAN': + stop_words = self.STOP_WORDS_DE + elif lan == 'SPANISH': + stop_words = self.STOP_WORDS_ES - # Determine the stopwords based on the language - stop_words = { - 'DUTCH': self.STOP_WORDS_NL, - 'ENGLISH': self.STOP_WORDS_EN, - 'GERMAN': self.STOP_WORDS_DE, - 'SPANISH': self.STOP_WORDS_ES - }.get(lan, []) - - # Split the text into words and remove stopwords text = text.split() return " ".join([word for word in text if word not in stop_words]) - def remove_words_from_string(self, text: str, words_to_remove: list[str]) -> str: - """ - Removes a list of words from a given text. - - This function takes a string of text and a list of words to remove, - and returns a new string with all occurrences of the words removed. - - Parameters - ---------- - text : str - The input text to have words removed from. - words_to_remove : list[str] - A list of words to remove from the text. - - Returns - ------- - str - The text with all occurrences of the words removed. - """ - + def remove_words_from_string(self, text, words_to_remove): # Join the words with the "|" (OR) operator in regex to create a pattern pattern = r'\b(?:' + '|'.join(re.escape(word) for word in words_to_remove) + r')\b' # Use re.sub() to replace all matches with an empty string result_text = re.sub(pattern, '', text) - return result_text + return result_text \ No newline at end of file diff --git a/setup.py b/setup.py index 20792e5..2642568 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='SqueakyCleanText', - version='0.2.5', + version='0.2.6', author='Rehan Fazal', description='A comprehensive text cleaning and preprocessing pipeline.', long_description=open('README.md', encoding='utf-8').read(), From e1f3adaca8f0f6549ea82981d3ee68b8c6253662 Mon Sep 17 00:00:00 2001 From: Rehan Fazal Date: Sun, 18 Aug 2024 13:06:00 +0200 Subject: [PATCH 2/2] Develop (#33) * Intial commit of squeaky clean text * updated the sct.py script with modular code * updated the sct.py script with pipeline method, which would ideally would help to make changes in the processing easier * removed unnecessary direction code * adding to do list * adding to do list * added requiremnt.txt file * added setup.py file * added test cases * updated config file * merging back * Develop (#2) (#3) * Intial commit of squeaky clean text * updated the sct.py script with modular code * updated the sct.py script with pipeline method, which would ideally would help to make changes in the processing easier * removed unnecessary direction code * adding to do list * adding to do list * added requiremnt.txt file * added setup.py file * added test cases * updated config file * merging back * rebase * update the license * added German and Spanish support * Updated file for pypi * Updated readme file * Add GitHub Actions workflow for publishing to PyPI * Updated readme file * Updated readme file * added the username to the publish.yml * update the API vriable name * update the API user name * Bump version to 0.1.1 * updated the readme file * updated the version * Update NER Process and added tag removal * Updated congig file * updated the code to have the option to not output language * fixed the bug for NER which was refrencing to the wrong model variable names, add the gpu support * fixed the Anonomyser Engine * fixed the Anonomyser Engine * added the test.yml file * added the test.yml file * added the test.yml file * added the German and Spanish language support in lingua * added the ability in the config to change the model name * added the ability in the config to change the model name * added the ability in the config to change the model name and fixed spanish model name * squased some bugs * added the language passing support * Refactored the code * fixed typing issue * reverted the refactor * Added the flow diagram of the pacckage in the readme --- README.md | 2 ++ resources/sct_flow.png | Bin 0 -> 127313 bytes 2 files changed, 2 insertions(+) create mode 100644 resources/sct_flow.png diff --git a/README.md b/README.md index e8cb273..191ee4a 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,8 @@ SqueakyCleanText simplifies the process by automatically addressing common text - Supports English, Dutch, German, and Spanish languages. - Provides text formatted for both Language Model processing and Statistical Model processing. +![Default Flow of cleaning Text](resources/sct_flow.png) + ##### Benefits for Statistical Models When working with statistical models, further optimization is often required, such as removing stopwords, special symbols, and punctuation. SqueakyCleanText streamlines this process, ensuring your text data is in optimal shape for classification and other downstream tasks. diff --git a/resources/sct_flow.png b/resources/sct_flow.png new file mode 100644 index 0000000000000000000000000000000000000000..cc7568a08312ff34dd66710796181e08abce7485 GIT binary patch literal 127313 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
    =S)lf~{z>*e|MWl#<_%OuSfhfTnQDN`a_ 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 literal 0 HcmV?d00001