ThemeFinder
ThemeFinder is a topic modelling Python package designed for analysing one-to-many question-answer data (i.e. survey responses, public consultations, etc.). See the docs for more info.
Quickstart
Install using your package manager of choice
For example pip install themefinder or uv add themefinder.
Usage
ThemeFinder takes as input a pandas DataFrame with two columns:
response_id: A unique identifier for each responseresponse: The free text survey response
ThemeFinder now supports a range of language models through structured outputs.
The function find_themes identifies common themes in responses and labels them, it also outputs results from intermediate steps in the theme finding pipeline.
For this example, import the following Python packages into your virtual environment: asyncio, pandas, lanchain. And import themefinder as described above.
If you are using environment variables (eg for API keys), you can use python-dotenv to read variables from a .env file.
If you are using an Azure OpenAI endpoint, you will need the following variables:
AZURE_OPENAI_API_KEYAZURE_OPENAI_ENDPOINTOPENAI_API_VERSIONDEPLOYMENT_NAMEAZURE_OPENAI_BASE_URL
Otherwise you will need whichever variables LangChain requires for your LLM of choice.
import asyncio
from dotenv import load_dotenv
import pandas as pd
from langchain_openai import AzureChatOpenAI
from themefinder import find_themes
# If needed, load LLM API settings from .env file
load_dotenv()
# Initialise your LLM of choice using langchain
llm = AzureChatOpenAI(
model="gpt-4o",
temperature=0,
)
# Set up your data
responses_df = pd.DataFrame({
"response_id": ["1", "2", "3", "4", "5"],
"response": ["I think it's awesome, I can use it for consultation analysis.",
"It's great.", "It's a good approach to topic modelling.", "I'm not sure, I need to trial it more.", "I don't like it so much."]
})
# Add your question
question = "What do you think of ThemeFinder?"
# Make the system prompt specific to your use case
system_prompt = "You are an AI evaluation tool analyzing survey responses about a Python package."
# Run the function to find themes, we use asyncio to query LLM endpoints asynchronously, so we need to await our function
async def main():
result = await find_themes(responses_df, llm, question, system_prompt=system_prompt)
print(result)
if __name__ == "__main__":
asyncio.run(main())
ThemeFinder pipeline
ThemeFinder's pipeline consists of five distinct stages, each utilizing a specialized LLM prompt:
Sentiment analysis
- Analyses the emotional tone and position of each response using sentiment-focused prompts
- Provides structured sentiment categorisation based on LLM analysis
Theme generation
- Uses exploratory prompts to identify initial themes from response batches
- Groups related responses for better context through guided theme extraction
Theme condensation
- Employs comparative prompts to combine similar or overlapping themes
- Reduces redundancy in identified topics through systematic theme evaluation
Theme refinement
- Leverages standardisation prompts to normalise theme descriptions
- Creates clear, consistent theme definitions through structured refinement
Theme target alignment
- Optional step to consolidate themes down to a target number
Theme mapping
- Utilizes classification prompts to map individual responses to refined themes
- Supports multiple theme assignments per response through detailed analysis
The prompts used at each stage can be found in src/themefinder/prompts/.
The file src/themefinder.core.py contains the function find_themes which runs the pipline. It also contains functions fo each individual stage.
For more detail - see the docs: https://i-dot-ai.github.io/themefinder/.
Model Compatibility
ThemeFinder's structured output approach makes it compatible with a wide range of language models from various providers. This list is non-exhaustive, and other models may also work effectively:
OpenAI Models
- GPT-4, GPT-4o, GPT-4.1
- All Azure OpenAI deployments
Google Models
- Gemini series (1.5 Pro, 2.0 Pro, etc.)
Anthropic Models
- Claude series (Claude 3 Opus, Sonnet, Haiku, etc.)
Open Source Models
- Llama 2, Llama 3
- Mistral models (e.g., Mistral 7B, Mixtral)
Development
This project uses uv for dependency management.
# Clone and set up development environment
git clone https://github.com/i-dot-ai/themefinder.git
cd themefinder
uv venv
source .venv/bin/activate
uv pip sync requirements-dev.txt
uv pip install -e .
# Run tests
pytest tests/
# Run linting
pre-commit run --all-files
License
This project is licensed under the MIT License - see the LICENSE file for details.
The documentation is © Crown copyright and available under the terms of the Open Government 3.0 licence.
Feedback
Contact us with questions or feedback at packages@cabinetoffice.gov.uk.
Metadata
Release files for themefinder 0.8.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| themefinder-0.8.2.tar.gz | 38.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| themefinder-0.8.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 67.8 kB
Release files / themefinder-0.8.2.tar.gz
| Download URL | themefinder-0.8.2.tar.gz |
|---|---|
| Size | 38.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4cdaa5fb20e4b3c1e319aa09e5211c633a2685866e30e64def34793b02c023b8
|
|
BLAKE2b-256 checksum How to use checksums |
b80673e3e3f53e12095eeae0295065d24d12a24c435c15c796c6f25c6158ab91
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 6, 2026.
Transparency logRelease files / themefinder-0.8.2-py3-none-any.whl
| Download URL | themefinder-0.8.2-py3-none-any.whl |
|---|---|
| Size | 29.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d6981590b17a557714f991211fb2321a95890c2940661cb714b2b868914a43ab
|
|
BLAKE2b-256 checksum How to use checksums |
5a119649c473ba4177f6bcc00649dd31287e5e775f2f00b19875327eeee67a16
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
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.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Mar 6, 2026.
Transparency log