Persuasion Index
Persuasion Index (PI) is a Python toolkit for asking a simple question: what persuasive moves does a text make? It breaks English argumentative text into 55 inspectable signals and groups them into 15 rhetorical dimensions.
This repository accompanies Persuasion Index: A Theory-Guided Framework for Persuasion Analysis, accepted to the EMNLP 2026 Main Conference. The current paper is available on arXiv.
Quick start: choose how you want to use PI
Both options provide the same command-line and Python interfaces. Choose the first if you only want to run PI. Choose the second if you want to inspect or change how individual features are computed.
Option 1: install the package without cloning the repository
This is the simplest route for analysis. pip installs PI and its required dependencies from PyPI.
Install
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install persuasion-index
In a Jupyter notebook, use %pip in place of python -m pip, then restart the
kernel.
Run
Score a text from the command line:
persuasion-index \
"According to recent studies, this policy could reduce costs by 20%."
Or use the Python API:
from persuasion_index import score
scores = score(
"According to recent studies, this policy could reduce costs by 20%."
)
print(scores["Evidence"])
No repository checkout, web service, or API key is needed.
Option 2: clone the repository to inspect or change modules
Use an editable install if you want to read the implementation, replace a feature detector, modify a lexicon, or contribute code.
Install for development
git clone https://github.com/krystalgong/Persuasion_Index_Code.git
cd Persuasion_Index_Code
python3 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev,notebooks]"
Run and modify
Use the same persuasion-index command or Python API shown above. Because the
installation is editable, saved source changes are used the next time the code
runs; reinstalling the package is not necessary.
The main places to start are:
PI_score_generator.pyfor individual feature implementations.persuasion_runner.pyfor string, list, and DataFrame scoring.persuasion_index/api.pyfor the public Python interface.helper_features/for the bundled lexicons and stored coefficients.
After a change, run the automated tests:
python -m pytest -q
See the repository map for the rest of the codebase.
That is enough to start in either mode. A few features can use additional linguistic resources; the base package still runs when those resources are absent.
For a complete first analysis—from checking resource coverage to exporting a DataFrame—see the usage and analysis guide.
What PI returns
PI organizes its dimensions around the Aristotelian triad:
| Appeal | Dimensions |
|---|---|
| Logos | Evidence, Logic/Cohesion, Argumentation, Specificity, Opponent’s View |
| Ethos | Authority/Credibility, Politeness, Commitment, Style |
| Pathos | Sentiment, Impact, Engagement, Reciprocity, Scarcity/Urgency, Propaganda |
Every subfeature and dimension score is in [0, 1]. A result contains all 55
subfeatures as well as the mean for each of the 15 dimensions, so it is possible
to inspect why two texts receive different profiles.
Before comparing dimension means, run persuasion-index doctor. Missing
optional resources keep the output schema stable, but their fallback values
still affect the means. Compare texts only when they were scored with the same
PI version, lexicon choice, and resource configuration; the
usage guide explains this with examples.
Installation notes
PI supports Python 3.10 and newer. Python 3.11 or 3.12 is recommended. If you also plan to run the lexicon-expansion pipeline from a cloned repository, install its dependencies with:
python -m pip install -e ".[lexicon,notebooks,dev]"
Optional features
The bundled lexicons and lightweight detectors work immediately. The resources below add the remaining features:
| Resource | Features it adds | Setup |
|---|---|---|
spaCy en_core_web_sm |
Named entities and organization mentions | Install spaCy, then run python -m spacy download en_core_web_sm |
| Single-word concreteness ratings | Specificity.lexical_concreteness |
Set PI_CONCRETENESS_FILE |
| Multiword concreteness ratings | Specificity.lexical_concreteness |
Set PI_MWE_CONCRETENESS_FILE |
| LIWC-compatible dictionary | LIWC cues used by Specificity, Sentiment, and Engagement | Set PI_LIWC_FILE to a compatible, locally licensed .dic file |
| NRC-VAD v2.1 | Sentiment.valence, Sentiment.arousal, and Sentiment.dominance |
Set PI_NRC_VAD_FILE |
Example configuration:
python -m pip install "spacy>=3.7" "openpyxl>=3.1"
python -m spacy download en_core_web_sm
export PI_CONCRETENESS_FILE=/absolute/path/to/concreteness_ratings.xlsx
export PI_MWE_CONCRETENESS_FILE=/absolute/path/to/mwe_concreteness.csv
export PI_LIWC_FILE=/absolute/path/to/LIWC.dic
export PI_NRC_VAD_FILE=/absolute/path/to/nrc_vad.tsv
From an editable source checkout, install the corresponding extras with:
python -m pip install -e ".[spacy,excel]"
Run the resource checker to see what is active and which features are affected:
persuasion-index doctor
Missing resources produce warnings but do not stop ordinary scoring. If that is
the configuration you intend to use, you can silence those warnings with
PI_QUIET_OPTIONAL_WARNINGS=1.
Download links, expected file columns, citations, and license notes live in THIRD_PARTY_RESOURCES.md. These external files are not included in the package.
Python usage
Score several texts
from persuasion_index import score_batch
texts = [
"This action is urgent.",
"The available evidence remains mixed.",
]
subfeatures, dimensions = score_batch(texts)
print(subfeatures.shape) # (2, 55)
print(dimensions.shape) # (2, 15)
Score a DataFrame
import pandas as pd
from persuasion_index import score_batch
data = pd.DataFrame(
{
"document_id": ["a", "b"],
"text": [
"This action is urgent.",
"The available evidence remains mixed.",
],
}
).set_index("document_id")
subfeatures, dimensions = score_batch(data, text_col="text")
analysis = data.join(dimensions).join(subfeatures)
analysis.to_csv("pi_scores.csv")
PI preserves the DataFrame index, which makes it easy to join scores back to document IDs and other metadata.
Use the UKP-weighted profile
from persuasion_index import get_report
raw_scores, ukp_profile = get_report(
"This proposal is practical and evidence-based."
)
The raw scores describe the text directly. The optional weighted profile uses coefficients estimated on UKP data and is most useful when that empirical context matches the analysis.
The expanded, audited lexicons are used by default. For comparisons with the
original seed lexicons, pass lexicon="seeded" to score, score_batch, or
get_report.
For more examples, output details, and a reproducibility checklist, see the analysis guide.
Command line
The CLI accepts text as an argument or through standard input:
persuasion-index "This plan is urgent."
echo "This plan is urgent." | persuasion-index --profile
Useful commands:
persuasion-index --version
persuasion-index doctor
persuasion-index doctor --json
Use --compact for single-line JSON and --profile to include the
UKP-weighted profile.
How scoring works
Most lexical cues are counted per 100 tokens and passed through a saturating transform:
score = 1 - exp(-0.5 * r)
Here, r is the match rate per 100 tokens. Sparse signals use binary
presence/absence scores. When lexicon matches overlap, PI keeps the longest
non-contained span. A dimension score is the unweighted mean of its
subfeatures.
PI measures rhetorical cues rather than whether a claim is true or whether a particular audience will ultimately be persuaded. For example, Evidence finds statistics, attribution phrases, and named entities; it does not fact-check them. Keeping that distinction in mind makes the scores much easier to interpret.
Repository map
persuasion_index/: public Python API and CLI.PI_score_generator.py: individual feature implementations.persuasion_runner.py: string, list, and DataFrame scoring.persuasion_profile.py: raw scores and the UKP-weighted profile.helper_features/: bundled PI lexicons and stored UKP coefficients.analysis_example.ipynb: a short analysis walkthrough.lexicons/: lexicon expansion and validation code.docs/: the analysis guide and release documentation.
The repository focuses on scoring, interpretation, and lexicon construction. The evaluation datasets used in the paper are not bundled here.
Notebooks and development
analysis_example.ipynb demonstrates the public API, seeded versus expanded
lexicons, DataFrame scoring, and weighted reports. The validation notebook at
lexicons/lexicons_validation/lexicon_code_validation.ipynb exercises scoring
behavior and split-half lexicon checks.
Run the package tests with:
python -m pip install -e ".[dev]"
python -m pytest -q
The full release checklist is in docs/testing-and-release.md. The LLM-assisted expansion pipeline has its own instructions in lexicons/LLM_expansion/README.md.
Scope and limitations
PI currently works best on English argumentative text. It sees the text itself, not the audience, speaker reputation, relationship history, or broader social setting. It will also miss some implicit framing, irony, sarcasm, and long-range argument structure.
Treat PI scores as interpretable features for describing and comparing texts, not as a universal probability of persuasion. When applying PI in a new domain, we recommend looking at score distributions and reading representative high-scoring and low-scoring examples before drawing conclusions.
Citation
If you use Persuasion Index in academic work, please cite our paper:
Liancheng Gong, Zhiyang Wang, Yiwei Xu, and Julia Mendelsohn. 2026.
Persuasion Index: A Theory-Guided Framework for Persuasion Analysis.
Accepted to the EMNLP 2026 Main Conference.
@misc{gong2026persuasionindex,
title = {Persuasion Index: A Theory-Guided Framework for Persuasion Analysis},
author = {Gong, Liancheng and Wang, Zhiyang and Xu, Yiwei and Mendelsohn, Julia},
year = {2026},
eprint = {2606.14580},
archiveprefix = {arXiv},
primaryclass = {cs.CL},
doi = {10.48550/arXiv.2606.14580},
note = {Accepted to the EMNLP 2026 Main Conference},
url = {https://arxiv.org/abs/2606.14580}
}
Machine-readable citation metadata is available in CITATION.cff. We will replace the arXiv entry with the ACL Anthology citation when the proceedings are published.
License
Project code, documentation, and project-created PI lexicons are released under the Apache License 2.0. External resources keep their own terms; see THIRD_PARTY_RESOURCES.md for details.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file persuasion_index-0.2.1.tar.gz.
File metadata
- Download URL: persuasion_index-0.2.1.tar.gz
- Upload date:
- Size: 91.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b48378809cda45c7bcae868aaf2a15eb84e6d4cb04a915953805d9f048cad458
|
|
| MD5 |
c9004bfbce60dbb391793311c5ce0855
|
|
| BLAKE2b-256 |
0e8e1231150588a7d59bd16f2b3dca88c501c69a9fd9ef95b4edbb75892c57b0
|
Provenance
The following attestation bundles were made for persuasion_index-0.2.1.tar.gz:
Publisher:
release.yml on krystalgong/Persuasion_Index_Code
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
persuasion_index-0.2.1.tar.gz -
Subject digest:
b48378809cda45c7bcae868aaf2a15eb84e6d4cb04a915953805d9f048cad458 - Sigstore transparency entry: 2582034717
- Sigstore integration time:
-
Permalink:
krystalgong/Persuasion_Index_Code@768a8b6c97a7cc8f94a94c800a6d70eca7635860 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/krystalgong
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@768a8b6c97a7cc8f94a94c800a6d70eca7635860 -
Trigger Event:
push
-
Statement type:
File details
Details for the file persuasion_index-0.2.1-py3-none-any.whl.
File metadata
- Download URL: persuasion_index-0.2.1-py3-none-any.whl
- Upload date:
- Size: 75.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6792eaf7a80023fb405b1a34aa6450d383cddc2e12d465a965dfe3dc31b3c8cc
|
|
| MD5 |
907874daccaf249bd17152939fed5826
|
|
| BLAKE2b-256 |
4cbc56923213a377fe4f9f37d9209c7c58f3d0b945c581f719ce39fff977ecf8
|
Provenance
The following attestation bundles were made for persuasion_index-0.2.1-py3-none-any.whl:
Publisher:
release.yml on krystalgong/Persuasion_Index_Code
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
persuasion_index-0.2.1-py3-none-any.whl -
Subject digest:
6792eaf7a80023fb405b1a34aa6450d383cddc2e12d465a965dfe3dc31b3c8cc - Sigstore transparency entry: 2582034723
- Sigstore integration time:
-
Permalink:
krystalgong/Persuasion_Index_Code@768a8b6c97a7cc8f94a94c800a6d70eca7635860 -
Branch / Tag:
refs/tags/v0.2.1 - Owner: https://github.com/krystalgong
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@768a8b6c97a7cc8f94a94c800a6d70eca7635860 -
Trigger Event:
push
-
Statement type: