clean-text

repository·main·Indexed 21 days ago

https://github.com/jfilter/clean-text

A text preprocessing library version 0.7.1 designed to normalize user-generated content from the web and social media. It provides functions to fix unicode errors, transliterate to ASCII, and strip or replace entities such as URLs, emails, and punctuation. The library includes a `clean()` function for single strings, `clean_texts()` for parallel processing of large batches, and a `CleanTransformer` class for scikit-learn compatibility.

Tokens
2.5K
Snippets
9
Records
12
Agent score
75%

What's inside clean-text

  1. Choosing between sequential and parallel `clean_texts()`

    main

    When using clean_texts(), you can control parallelism via the n_jobs parameter. Choosing the right value depends on your batch size and hardware:

    • Small batches (< 1,000 texts): Use sequential processing (n_jobs=1). The overhead of spawning processes and Inter-Process Communication (IPC) makes parallelization slower than sequential execution for small workloads.
    • Large batches (10,000+ texts): Use parallel processing (n_jobs > 1). Parallelization provides significant speedups for large corpora.
    • Optimal worker count: Increasing n_jobs does not always result in faster execution. There is a 'sweet spot' where adding more workers increases coordination overhead without proportional performance gains. The optimal number of workers depends on your specific corpus size and CPU core count.

    Note: The default value is n_jobs=1, which ensures zero overhead for single-text or small-batch workflows.

  2. Configure PyPI authentication for Poetry

    main

    If you encounter authentication errors when running poetry publish, you must configure your PyPI API token. You can do this via the Poetry configuration command or by setting an environment variable.

    # Option 1: Using poetry config
    poetry config pypi-token.pypi <your-token>
    
    # Option 2: Using environment variable
    export POETRY_PYPI_TOKEN_PYPI=pypi-XXXXXXXXXXXX
  3. Install clean-text

    main

    Install the base package via pip. Note that the package name is clean-text, not cleantext.

    To include the GPL-licensed unidecode package (which provides superior transliteration to ASCII), use the [gpl] extra. If unidecode is not installed, the library will fallback to Python's unicodedata.normalize.

    # Install with unidecode (GPL)
    pip install clean-text[gpl]
    
    # Install without unidecode
    pip install clean-text
    
    # Install with scikit-learn compatibility
    pip install clean-text[sklearn]
    pip install clean-text[gpl]
  4. Release a new version of clean-text

    main

    To release a new version of clean-text, follow these steps:

    1. Verify CI: Ensure all tests pass on the main branch using gh run list --limit 5.
    2. Update Versions: Manually update the version number in pyproject.toml (version = "X.Y.Z") and cleantext/__init__.py (__version__ = "X.Y.Z") following Semantic Versioning.
    3. Update CHANGELOG.md: Move entries from the [Unreleased] section to a new version section (e.g., ## [X.Y.Z] - YYYY-MM-DD) categorized by Added, Changed, or Fixed.
    4. Commit and Tag: Commit the changes and create a git tag.
    5. Create GitHub Release: Use the GitHub CLI to create a release with notes.
    6. Publish to PyPI: Build the package with poetry and publish it.
    7. Verify: Upgrade the package via pip and check the version in Python.
    # Full release flow example (replace X.Y.Z with actual version)
    VERSION="X.Y.Z"
    
    gh run list --limit 3
    
    git add pyproject.toml cleantext/__init__.py CHANGELOG.md
    git commit -m "Release v${VERSION}"
    git tag "v${VERSION}"
    git push origin main --tags
    
    gh release create "v${VERSION}" --generate-notes
    
    poetry build
    poetry publish
    
    pip install --upgrade clean-text
    python -c "import cleantext; print(cleantext.__version__)"
  5. Preserve patterns with exceptions

    main

    Use the exceptions argument to protect specific text patterns from being modified. Each entry in the exceptions list must be a regex pattern string. Matches are preserved verbatim (they are not lowered, not transliterated, and remain exactly as they appeared in the input).

    from cleantext import clean
    
    # Preserve a literal compound word while removing other punctuation
    clean("drive-thru and text---cleaning", no_punct=True, exceptions=["drive-thru"])
    # => 'drive-thru and textcleaning'
    
    # Preserve all hyphenated compound words using a regex
    clean("drive-thru and pick-up", no_punct=True, exceptions=[r"\w+-\w+"])
    # => 'drive-thru and pick-up'
    
    # Multiple exception patterns
    clean("drive-thru costs $5", no_punct=True, no_currency_symbols=True,
          exceptions=[r"\w+-\w+", r"\$\d+"])
    # => 'drive-thru costs $5'
  6. Fix an existing Git tag

    main

    If you need to re-tag a version (for example, if you forgot to include a fix), you must delete both the local and remote tags before re-tagging.

    # Delete local and remote tag
    git tag -d vX.Y.Z
    git push origin :refs/tags/vX.Y.Z
    
    # Re-tag after fixing
    git tag vX.Y.Z
    git push origin --tags
  7. Handle failed PyPI uploads

    main
    PyPI does not allow re-uploading the same version number. If a poetry publish command fails partially, you cannot retry the same version. You must increment the version number (e.g., from 0.7.0 to 0.7.1) and attempt the release again.
  8. Run clean-text benchmarks

    main

    To evaluate the performance of the clean_texts() function, you can run the included benchmark script. This script compares sequential processing against parallel processing using different n_jobs configurations.

    python benchmarks/bench_clean_texts.py
  9. Use CleanTransformer with scikit-learn

    main

    For integration into machine learning pipelines, use the CleanTransformer class. It provides a scikit-learn compatible API and accepts the same parameters as the clean() function.

    from cleantext.sklearn import CleanTransformer
    
    cleaner = CleanTransformer(no_punct=False, lower=False)
    cleaner.transform(['Happily clean your text!', 'Another Input'])
  10. Clean multiple texts in parallel with clean_texts()

    main

    To process a list of strings, use clean_texts(). You can enable parallel processing using the n_jobs parameter to leverage Python's multiprocessing.

    n_jobs semantics:

    • 1 or None: Sequential processing (default, zero overhead).
    • -1: Use all available CPU cores.
    • -2: Use all cores except one.
    • Any positive integer: Use exactly that many workers.
    • 0: Raises ValueError.
    from cleantext import clean_texts
    
    # Sequential (default)
    clean_texts(["text one", "text two", "text three"])
    
    # Use all available CPU cores
    clean_texts(["text one", "text two", "text three"], n_jobs=-1)
    
    # Use a specific number of workers
    clean_texts(["text one", "text two", "text three"], n_jobs=4)
    
    # Pass all clean() keyword arguments
    clean_texts(texts, n_jobs=-1, no_urls=True, lang="de", lower=False)
  11. Use the clean() function

    main

    The clean() function is the primary API for normalizing text. It allows you to fix unicode errors, transliterate to ASCII, lowercase text, and remove or replace various entities like URLs, emails, phone numbers, and punctuation.

    All parameters are optional and follow the defaults provided in the signature.

    from cleantext import clean
    
    clean("some input",
        fix_unicode=True,
        to_ascii=True,
        lower=True,
        no_line_breaks=False,
        no_code=False,
        no_urls=False,
        no_emails=False,
        no_phone_numbers=False,
        no_ip_addresses=False,
        no_file_paths=False,
        no_numbers=False,
        no_digits=False,
        no_currency_symbols=False,
        no_punct=False,
        no_emoji=False,
        replace_with_punct="",
        exceptions=None,
        replace_with_code="<CODE>",
        replace_with_url="<URL>",
        replace_with_email="<EMAIL>",
        replace_with_phone_number="<PHONE>",
        replace_with_ip_address="<IP>",
        replace_with_file_path="<FILE_PATH>",
        replace_with_number="<NUMBER>",
        replace_with_digit="0",
        replace_with_currency_symbol="<CUR>",
        lang="en"
    )