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.
- ProgramasElectorales treats political language as a family of related concepts, not a flat bag of exact words.
- Its most distinctive move is stemming first and then expanding into Spanish WordNet synonyms, which increases recall while risking false matches.
- The repo is less polished than a product tool, but that roughness makes the analytic trade-offs visible.
- Its heatmap is not just a chart, it is a claim that manifesto overlap can be compared with enough rigor to be inspectable, not mystical.
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 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
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.
| Approach | What it answers well | What it misses | Best trait |
|---|---|---|---|
| ProgramasElectorales | Which concepts are being reused, renamed, or semantically crowded together | Context, sarcasm, and policy nuance outside the text pipeline | Transparent fuzzy matching |
| ProgramIA / chat-style tools | What a party says about a specific topic in natural language | How the answer was assembled from the source text | Accessibility |
| Lexical visualization tools | Which words dominate or distinguish each program | Synonymy and conceptual equivalence | Quick 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.





