ProgramasElectorales: The Python Script That Tries to Hear What Spanish Party Programs Mean

A compact civic-tech toolkit that extracts manifesto PDFs, normalizes political language, expands synonyms, and compares parties by both word choice and semantic overlap.

8 min read • View on GitHub • More from fsanchez83

A stack of political manifesto pages feeds into a narrow mechanical sorter, which emits clean token labels on the other side. Two nearby labels are linked by a small bridging arm, suggesting that political language can be grouped by meaning instead of counted as isolated words.
The repo’s core idea is simple and unusual: count concepts, not just tokens.
Key Takeaways

Most text tools are literal. They count exact words and call it analysis. This repo takes a sharper view: in politics, empleo and trabajo may be different tokens, but they can carry the same policy signal.

That matters because party programs are written to avoid easy counting. They repeat themes, swap synonyms, and bury meaning in bureaucratic phrasing. ProgramasElectorales tries to hear through that noise.

Why counting exact words misses the point

Por ello, hoy te traemos un modelo de IA de Newtral llamado ProgramIA, la cual te ayudará a comparar los programas electorales de los principales partidos.

The quote is about ProgramIA, not this repo directly, but it frames the same civic problem. People do not read manifestos by counting nouns. They ask what each party means when it talks about work, housing, taxes, or growth.

That is why a frequency script can be more interesting than it first looks. Once you accept that political language is strategic, exact matching starts to feel too crude. The real question is whether a tool can normalize the rhetoric without flattening the politics.

How ProgramasElectorales turns PDFs into analyzable text

The repository is a plain Python workbench, not a packaged library. The flow is easy to read: extract text from PDFs, cache it as `.txt`, remove stopwords and custom noise, then run frequency and similarity analysis over the cleaned corpus.

The repo’s pipeline is simple enough to inspect and opinionated enough to matter: it reshapes PDFs into semantic units before comparing them.

The hardcoded paths and manual exclusions are not bugs in the editorial sense. They tell you what kind of tool this is. It is a research instrument built for a specific corpus, with the friction left visible.

synsets = wn.synsets(stemmer.stem(word), lang='spa')
for synset in synsets:
    for lemma in synset.lemma_names('spa'):
        synonyms.add(lemma.lower())

The clever part: stemming first, synonyms second

A close-up of one stemmed word branching into several synonym tags, like a grafted plant or switchboard. One branch stretches too far toward a misleading neighbor, showing both the power and the risk of semantic expansion.
Stemming first broadens recall, but it can also pull in words that only look related on paper.

This is the repo’s signature move. It stems a word, looks up Spanish WordNet synsets, and then pulls in related lemmas so the analysis can count meaning families rather than isolated spellings.

That is powerful because it helps solve the thesaurus problem in political writing. A party can rename the same idea and still be talking about the same policy terrain. The method is a bet that semantic overlap is more revealing than raw repetition.

But it is also a trade-off. Stemming before synonym lookup raises recall, yet it can blur distinctions that matter. In other words, the script gets better at seeing related language by becoming less picky about what counts as related.

Interactive semantic pipeline

The middle of the article should show the logic as a living system: manifestos enter, noise is stripped, stems are generated, synonyms fan out, and then the concept buckets feed a similarity matrix. The point is not flash. It is to make the judgment call visible.

What the heatmap reveals about ideological overlap

`Similitud.py` takes the cleaned corpus and turns it into TF-IDF vectors, then compares those vectors with cosine similarity. The result is a matrix that says which manifestos are lexically closer, not which ones are morally or politically equivalent.

That distinction matters. A heatmap can look decisive, but it is still a model. It measures overlap in the language the programs use, which is useful precisely because it stays humble about what it cannot know.

ApproachWhat it answers wellWhat it missesBest trait
ProgramasElectoralesWhich concepts are being reused, renamed, or semantically crowded togetherContext, sarcasm, and policy nuance outside the text pipelineTransparent fuzzy matching
ProgramIA / chat-style toolsWhat a party says about a specific topic in natural languageHow the answer was assembled from the source textAccessibility
Lexical visualization toolsWhich words dominate or distinguish each programSynonymy and conceptual equivalenceQuick visual contrast

The repo’s heatmap is strongest when read as a comparative lens, not a verdict. It gives you a map of rhetorical proximity, which is often enough to start a serious conversation.

What this repo does better than conversational election tools

Compared with a chat interface, this project is less friendly and more inspectable. You can see where the text comes from, how it is cleaned, and how similarity is computed. That is a virtue when the subject is politics.

Compared with pure word-frequency visualizations, it is more opinionated. It tries to collapse synonym families into a single analytical idea, which makes it better at comparing rhetoric that changes its vocabulary without changing its message.

That does not make it superior in every case. It makes it better for one question: where are parties speaking with different words but similar concepts?

A research notebook with civic ambitions

The codebase feels like a personal instrument rather than a public product. There are hardcoded paths, manual stoplists, and limited error handling. There is also a clear analytic spine, and that is more important here than polish.

This is what good civic tech often looks like before it becomes a product. It makes an argument about how to read public language, then leaves enough of the machinery exposed that the reader can disagree with it.

That openness is the real value. It does not pretend to eliminate interpretation. It makes interpretation easier to audit.