Skip to main content

sentikit

A sentiment analysis library that goes beyond lexicon tools like VADER and TextBlob by actually fixing their known failure modes instead of just adding more words to a dictionary.

Why not just use VADER?

Problem VADER / TextBlob sentikit
Negation scope Fixed 3-4 token window Real dependency-parse scope (spaCy), or clause-bounded fallback
Contrastive discourse ("but", "however") Averages both clauses Detects the marker, upweights the post-marker clause
Idioms ("break a leg", "a nightmare") Scores each word literally Phrase-level lookup, scored as a unit, excluded from word-level pass
Aspect-based sentiment Not supported Optional transformer stage: per-aspect sentiment, not one blended score
Sarcasm Not supported Optional transformer gate that dampens/inverts the score by confidence, not a hard flip
Implicit / contextual sentiment Word-lookup only Optional transformer backbone blended with the rule-based score

Honest scope note: sarcasm and fully implicit sentiment (no sentiment words at all) are open research problems. sentikit ships best-effort modules for these with documented confidence handling — it does not claim to solve them outright.

Install

pip install sentikit                 # lite mode only, zero heavy deps
pip install sentikit[parse]          # + spaCy for accurate negation scope
pip install sentikit[transformers]   # + transformer sentiment/sarcasm/ABSA
pip install sentikit[all]            # everything

python -m spacy download en_core_web_sm   # needed if you installed [parse]

Lite mode works completely offline with zero downloads. Full mode downloads models from HuggingFace on first use of that feature (not at import time).

Usage

Lite mode (default) — fast, offline, no downloads

from sentikit import Analyzer

sa = Analyzer()  # mode="lite" by default

r = sa.analyze("I do not think this movie was particularly good")
print(r.compound, r.label)          # -0.356 negative
print(r.negation_applied)           # True — correctly scoped "not ... good"
                                     # despite them being far apart

r = sa.analyze("The food was great, but the service was awful")
print(r.label)                      # negative — post-"but" clause dominates

r = sa.analyze("This laptop is a nightmare to work with")
print(r.idioms_matched)             # ['a nightmare']

Full mode — adds transformer sentiment, sarcasm gate, ABSA

sa = Analyzer(mode="full")

result = sa.analyze(
    "The battery life is terrible but the camera is excellent",
    aspects=True,
)
print(result.label)                 # blended rule + transformer score
for a in result.aspects:
    print(a["aspect"], a["sentiment"], a["confidence"])
    # battery life  negative  0.91
    # the camera    positive  0.94

result = sa.analyze("Oh great, another Monday", sarcasm=True)
print(result.sarcasm_probability, result.sarcasm_adjusted, result.label)

Architecture

text
 ├─ idiom phrase matching (masks matched spans before word-level scoring)
 ├─ tokenize
 ├─ negation scope (spaCy dependency parse, or clause-bounded regex fallback)
 ├─ contrastive discourse split ("but"/"however"/...) + asymmetric reweighting
 ├─ lexicon lookup + intensifier scaling
 └─ [full mode only]
     ├─ transformer sentiment backbone (blended with rule-based score)
     ├─ sarcasm gate (confidence-weighted dampen/invert, not a hard switch)
     └─ aspect extraction (noun chunks) + per-aspect transformer classification

Each module (negation.py, contrast.py, idioms.py, sarcasm.py, aspect.py) is independently testable and swappable — this is intentionally a pipeline of small fit-for-purpose components, not one model trying to do everything.

What's still unsolved / roadmap

  • Conditionals ("it would be amazing if it worked") — not yet detected; currently scores the embedded positive word at face value.
  • Rhetorical questions — not yet detected as a distinct category.
  • Quoted/reported speech attribution (whose opinion is it?) — not handled.
  • Word sense disambiguation ("sick" as slang vs. illness) — lexicon uses a single fixed value per word; a WSD stage would help here.
  • Idiom coverage — the bundled idiom lexicon (data/idioms.json) is a small starter set (~30 entries); swap in a larger corpus (e.g. MAGPIE) for production use.

Development

pip install -e .[dev,all]
pytest tests/

Metadata

Release files for sentikit 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sentikit 0.1.0
File Size Uploaded Provenance Actions
sentikit-0.1.0.tar.gz 53.8 kB Without provenance Details for sentikit-0.1.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for sentikit 0.1.0
File Interpreter ABI Platform Actions
sentikit-0.1.0-py3-none-any.whl Python 3 none any Details for sentikit-0.1.0-py3-none-any.whl

Total release size: 104.8 kB

Release files / sentikit-0.1.0.tar.gz

Download URL sentikit-0.1.0.tar.gz
Size 53.8 kB
Tags Source
SHA-256 checksum
How to use checksums
282fad768a574318b395df9396d57a19309673a04db71fa2beaa03cb67fa6a57
BLAKE2b-256 checksum
How to use checksums
119c159ec45c6b37c9788306d3adc644c63089365f2f9e3d38515e32de885061
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Release files / sentikit-0.1.0-py3-none-any.whl

Download URL sentikit-0.1.0-py3-none-any.whl
Size 51.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c0e94ade672a81f51c2f24665adaa0681e4c5b50fbab5d85f686441276985770
BLAKE2b-256 checksum
How to use checksums
eae2ed26ef794a1ee011d41deae6e44309bcddff46ef9c622930857fbd47fa86
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.13

Security for sentikit 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page