Are you Anabela?
This is your free professional page on AI Realty. Claim it to edit your profile, receive inbound leads and promote your listings.
About Anabela
Anabela Ferreira Tavares is a Real Estate Consultant (Consultora Imobiliária) at Century 21 Falcon in Portugal. Since early on in her life, she has been fascinated by properties and their decoration.
In her work as a real estate professional, she values honesty, seriousness, competence, and professionalism. She is also committed to delivering quality, effort, and dedication to her clients.of property transactions. She holds a Bachelor of Engineering in Electronic Engineering from the University of KwaZulu-Natal (formerly University of Natal) and has completed specialized postgraduate management courses in international business.
Known for his patient, honest, and dedicated representation, Mark excels in transactions involving multi-generational families. His professional background includes operating a high-end corporate gift business, as well as working in management consulting, property development, and high-end residential construction. He is a member of the Real Estate Institute of Victoria (REIV).
Outside of his real estate career, Mark serves on the board of the non-profit organization, the Father Bob Maguire Foundation. He lives in bayside Melbourne with his family, where he enjoys sailing. He has lived in several global cities and is fluent in English, Portuguese, Spanish, and French.text The primary objective of this review is to evaluate the therapeutic efficacy of digital interventions in improving adherence and treatment outcomes in patients with tuberculosis. Additionally, the review aims to identify the different types of digital technologies used, assess their usability, and explore the barriers and facilitators to their implementation. ```
If we wanted to structure this search we could decompose it as follows:
- **Population**: Patients with tuberculosis. - **Intervention**: Digital interventions (e.g., mobile health apps, short message service, video-observed therapy). - **Comparison**: Standard care (e.g., directly observed therapy). - **Outcome**: Adherence and treatment outcomes.
### Boolean search vs Semantic Search
A boolean search string for this topic might look like this:
`("tuberculosis" OR "TB") AND ("digital health" OR "mHealth" OR "mobile health" OR "video-observed therapy" OR "VOT" OR "SMS" OR "text message") AND ("adherence" OR "compliance" OR "treatment outcome" OR "cure")`
A semantic search model uses the concepts and relationships between words to retrieve relevant papers. Behind the scenes, the semantic search model represents the text as a high-dimensional vector. For example, the sentence "digital interventions for tuberculosis" would be represented as a dense vector of numbers. When a user runs a semantic search, the system converts the query into a vector and calculates the similarity (e.g., using cosine similarity) to the vectors representing the documents in the database.
| Feature | Boolean Search | Semantic Search | | --- | --- | --- | | **Logic** | Exact keyword matching using logical operators (`AND`, `OR`, `NOT`). | Contextual understanding based on word meanings and relationships (vectors). | | **Recall / Precision trade-off** | High precision but potentially lower recall (misses synonyms or related terms not explicitly listed). | High recall (catches synonyms and conceptually similar papers) but may include irrelevant papers (lower precision). | | **Query complexity** | Requires complex, manually constructed search strings with nested parentheses and wildcards. | Can use natural language queries, such as full sentences or paragraphs. | | **Adaptability** | Rigid; if a keyword is missing, the document is not retrieved. | Flexible; can find relevant papers even if they use different terminology (e.g., retrieving papers on "consumption" when searching for "tuberculosis"). |
## Tools
### OpenAlex
OpenAlex is a free, open-source index of over 250 million scholarly works, authors, venues, institutions, and concepts. It is designed to be a modern, open replacement for proprietary databases like Web of Science and Scopus.
To access the API, we can use the `pyalex` library or construct the URL directly. The API supports rich metadata filtering, allowing us to replicate the boolean search logic we developed earlier.
Here is an example Python script to query OpenAlex using the `requests` library and the URL-based API. We will search for works related to "tuberculosis" and "digital health" that have been published since 2018.
First, let's install the required libraries:
```bash pip install requests pandas ```
The OpenAlex API uses a specific query syntax. For a boolean search, we can use the `search` parameter with logical operators. Here is how we can construct the query:
```python import requests import pandas as pd
# Define the API endpoint url = "https://api.openalex.org/works"
# Define the search query using OpenAlex query syntax # We will use the 'filter' parameter to restrict results to works published after 2018 # and the 'q' parameter for our boolean search query query_params = { 'filter': 'publication_year:>2018,has_fulltext:true', 'q': '"tuberculosis" AND ("digital health" OR "mhealth" OR "video-observed therapy" OR "SMS" OR "text message") AND ("adherence" OR "compliance")', 'per_page': 50, # Number of results per page (max 200) 'mailto': '[email protected]' # OpenAlex polite pool }
# Send the GET request response = requests.get(url, params=query_params)
# Check if the request was successful if response.status_code == 200: data = response.json() works = data['results'] # Extract relevant metadata results_list = [] for work in works: results_list.append({ 'title': work.get('title'), 'doi': work.get('doi'), 'publication_year': work.get('publication_year'), 'cited_by_count': work.get('cited_by_count'), 'display_name': work.get('primary_location', {}).get('source', {}).get('display_name') if work.get('primary_location') and work.get('primary_location').get('source') else None }) # Convert to DataFrame df = pd.DataFrame(results_list) print(df.head()) else: print(f"Error: {response.status_code}") ```
OpenAlex uses a concept tagger to classify papers. This is extremely useful for semantic search. For example, instead of searching for "tuberculosis" and its synonyms, we can filter by the OpenAlex concept for Tuberculosis (`https://openalex.org/C161584124`).
### Cohere
Cohere provides access to advanced natural language processing models, including their Classify, Generate, and Embed endpoints. We can use Cohere's embeddings to perform semantic search over our retrieved literature.
In this example, we will first retrieve a small corpus of papers (using OpenAlex or a local dataset) and then use Cohere's `co.embed()` model to represent the paper abstracts as vectors. We will use the `embed-english-v3.0` model, which is optimized for semantic search tasks.
We will also use `numpy` to calculate the cosine similarity between our query vector and the document vectors.
First, install the library:
```bash pip install cohere numpy ```
Now, let's write a python script to embed our documents and perform a semantic search.
```python import cohere import numpy as np
# Initialize the Cohere client # Make sure to set your COHERE_API_KEY environment variable or pass it directly co = cohere.Client(api_key='YOUR_COHERE_API_KEY')
# Sample raw text (abstracts) retrieved from our initial literature screening documents = [ "Digital health interventions offer promising solutions for improving tuberculosis (TB) treatment adherence. This study evaluates the effectiveness of a mobile-based video directly observed therapy (VDOT) compared to traditional in-person DOT in patients with active tuberculosis. Our findings suggest higher adherence rates and improved patient satisfaction with VDOT.", "Tuberculosis remains a major global health threat. This paper reviews the epidemiology of multi-drug resistant tuberculosis (MDR-TB) and discusses the challenges in diagnosis and treatment, highlighting the need for rapid diagnostic tools in resource-limited settings.", "A randomized controlled trial was conducted to assess the impact of short message service (SMS) reminders on antiretroviral therapy (ART) adherence among HIV-infected patients in Kenya. Results showed a significant improvement in self-reported adherence in the intervention group.", "Mobile health (mHealth) technologies, such as text message reminders and digital medication monitors, have been increasingly used to support tuberculosis treatment. This systematic review synthesizes evidence on the feasibility, acceptability, and efficacy of these digital tools in diverse clinical cohorts.", "We present a novel deep learning model for the detection of tuberculosis from chest X-ray images. The model achieved high sensitivity and specificity, indicating its potential as an automated screening tool in high-burden settings." ]
# Define our semantic search query based on our review prompt query = "Are digital health interventions effective in improving tuberculosis treatment adherence?"
# Embed the documents and the query using the embed-english-v3.0 model # We specify input_type="search_document" for the texts we want to search over, # and input_type="search_query" for the search query itself. doc_embeddings = co.embed( texts=documents, model="embed-english-v3.0", input_type="search_document" ).embeddings
query_embedding = co.embed( texts=[query], model="embed-english-v3.0", input_type="search_query" ).embeddings[0]
# Define a function to calculate cosine similarity def cosine_similarity(v1, v2): return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))
# Calculate similarity scores between the query and each document scores = [cosine_similarity(query_embedding, doc_emb) for doc_emb in doc_embeddings]
# Print our results ranked by similarity score results = sorted(zip(scores, documents), key=lambda x: x[0], reverse=True)
print("Query:", query) print("\nRanked Search Results:") for score, doc in results: print(f"\nScore: {score:.4f}") print(f"Document: {doc}") ```
Notice how the model successfully ranks the documents.
1. The first document (directly discussing VDOT for TB) and the fourth document (mHealth review for TB) should receive the highest scores because they align closely with the semantic meaning of our query. 2. The third document (SMS for HIV ART adherence) might receive a moderate score because it touches on the concepts of "digital interventions" and "adherence," even though the disease (HIV) is different. 3. The second (MDR-TB epidemiology) and fifth (deep learning for TB detection on X-rays) documents should receive lower scores because, while they discuss tuberculosis, they do not address digital adherence interventions.
### LLMs for Screening
Once we have a candidate list of papers, we have to decide which ones meet our inclusion and exclusion criteria. This step, known as title and abstract screening, is historically done manually by two independent reviewers. This is where an LLM (Large Language Model) can act as an assistant.
We can prompt an LLM with our specific inclusion and exclusion criteria and ask it to classify the retrieved papers.
Here is a Python example using the `openai` API to screen abstracts against our criteria.
First, install the OpenAI library:
```bash pip install openai ```
Here is the screening script:
```python import openai import os
# Initialize the OpenAI client # Ensure the OPENAI_API_KEY environment variable is set client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
# Define our screening criteria screening_criteria = """ You are an expert systematically reviewing scientific literature. Your task is to screen the abstract of a scientific paper and determine if it should be INCLUDED or EXCLUDED based on the following criteria:
INCLUSION CRITERIA: 1. Population: Patients diagnosed with tuberculosis (any form, sensitive or drug-resistant). 2. Intervention: Digital health interventions used to monitor, support, or improve treatment adherence (e.g., SMS, mobile apps, video-observed therapy, digital pillboxes). 3. Outcome: Reports adherence rates, treatment completion, cure rates, or treatment outcomes.
EXCLUSION CRITERIA: 1. Studies that do not focus on tuberculosis (e.g., focus on HIV, diabetes, or general health adherence). 2. Digital tools used only for diagnosis, screening, or clinical decision support (without an adherence monitoring component). 3. Review articles, protocols, editorials, or conference abstracts (focus only on primary studies).
Output your decision strictly in the following JSON format: { "decision": "INCLUDE" or "EXCLUDE", "reason": "A brief explanation mapping the decision to the criteria." } """
# Sample Abstracts to screen abstracts_to_screen = [ { "id": 1, "title": "Effectiveness of video-observed therapy for tuberculosis treatment adherence", "abstract": "BACKGROUND: Video-observed therapy (VOT) is an alternative to directly observed therapy (DOT) for tuberculosis. We conducted a randomized controlled trial to compare adherence between VDOT and DOT. METHODS: Patients with active TB were randomized to either daily VDOT or daily in-person DOT. Adherence was defined as the proportion of prescribed doses observed. RESULTS: Adherence was significantly higher in the VDOT arm (91%) compared to the DOT arm (75%). VDOT was also preferred by patients because of its convenience." }, { "id": 2, "title": "Machine learning for automated tuberculosis detection in low-resource settings", "abstract": "Tuberculosis remains the leading cause of death from an infectious agent globally. Early diagnosis is critical to control transmission. We developed a novel convolutional neural network (CNN) trained on digital chest radiographs to automatically classify images as normal or suggestive of TB. The model achieved an area under the ROC curve (AUC-ROC) of 0.94. This tool can assist healthcare workers in screening high-burden populations." } ]
# Screen each abstract for item in abstracts_to_screen: print(f"\n--- Screening Paper {item['id']}: {item['title']} ---") prompt = f"{screening_criteria}\n\nPaper Title: {item['title']}\nPaper Abstract: {item['abstract']}" response = client.chat.completions.create( model="gpt-4o-mini", # Using a fast, cost-effective model for screening messages=[ {"role": "user", "content": prompt} ], response_format={"type": "json_object"}, # Ensure structured output temperature=0.0 ) classification = response.choices[0].message.content print(classification) ```
By leveraging LLMs for this initial stage, researchers can rapidly filter out thousands of irrelevant articles, allowing them to focus their human evaluation efforts on the papers most likely to meet their criteria.
## End-to-End Workflow
We can combine these tools into a pipeline designed to search, embed, rank, and screen scientific literature.
``` [OpenAlex API] │ (Boolean Search / Metadata Filter) ▼ [Raw Academic Papers] │ ├─────────────────────────────────────────┐ ▼ (Semantic Vectorization) ▼ (JSON Extraction) [Cohere Embed] [Paper Metadata & Abstracts] │ │ ▼ │ [Cosine Similarity] │ │ (Identify Top-N semantic matches) │ ▼ │ [Relevant Paper URLs/IDs] │ │ │ └────────────────────┬────────────────────┘ │ (Merge metadata for candidates) ▼ [GPT-4o Screening] │ (Structured abstract screening) ▼ [Included Publications] ```
Let's build a functional CLI-based script that implements this architecture.
```python import os import requests import numpy as np import cohere import openai import json import pandas as pd
# Load environment variables COHERE_API_KEY = os.getenv("COHERE_API_KEY") OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
assert COHERE_API_KEY, "Please set COHERE_API_KEY environment variable." assert OPENAI_API_KEY, "Please set OPENAI_API_KEY environment variable."
# Initialize clients co = cohere.Client(api_key=COHERE_API_KEY) openai_client = openai.OpenAI(api_key=OPENAI_API_KEY)
# Define our system-wide criteria CONCEPT_TERM = "tuberculosis" SEMANTIC_QUERY = "Are digital health interventions effective in improving tuberculosis treatment adherence and outcomes?"
SCREENING_PROMPT = """ You are an expert screening scientific literature for a systematic review. Target Topic: Digital interventions for tuberculosis treatment adherence.
Evaluate the following paper title and abstract against our criteria: - Population: Tuberculosis patients. - Intervention: Digital health tools (SMS, apps, sensors, video-observed therapy) for ADHERENCE or treatment monitoring. - Exclude: Diagnosis aids, general algorithms purely for lung imaging, non-TB conditions.
Return a JSON string exactly formatted as: {"decision": "INCLUDE" or "EXCLUDE", "reasoning": "<1-sentence justification>"} """
def fetch_openalex_papers(query, limit=50): """Retrieve papers matching keyword parameters from OpenAlex.""" print(f"[*] Fetching literature from OpenAlex for query: {query}") endpoint = "https://api.openalex.org/works" params = { 'filter': 'publication_year:>2017,has_fulltext:true', 'q': query, 'per_page': limit, 'mailto': '[email protected]' } response = requests.get(endpoint, params=params) if response.status_code == 200: results = response.json().get('results', []) # Yield safe models containing text data = [] for r in results: abstract_inverted_index = r.get('abstract_inverted_index') # OpenAlex stores abstracts as an inverted index to avoid copyright issues. # We must reconstruct the abstract text representation. abstract = "" if abstract_inverted_index: # Reconstruct abstract word_positions = {} for word, positions in abstract_inverted_index.items(): for pos in positions: word_positions[pos] = word abstract = " ".join([word_positions[i] for i in sorted(word_positions.keys())]) if abstract and r.get('title'): data.append({ 'id': r.get('id'), 'title': r.get('title'), 'abstract': abstract, 'doi': r.get('doi'), 'year': r.get('publication_year') }) print(f"[+] Retrieved {len(data)} valid papers containing abstract text.") return data else: print(f"[-] API Error: {response.status_code}") return []
def semantic_rank(papers, query_text, top_n=10): """Embed abstracts using Cohere and rank relevance using cosine similarity.""" print(f"[*] Computing vector embeddings for {len(papers)} abstracts via Cohere...") abstracts = [p['abstract'] for p in papers] doc_embeddings = co.embed( texts=abstracts, model="embed-english-v3.0", input_type="search_document" ).embeddings
query_embedding = co.embed( texts=[query_text], model="embed-english-v3.0", input_type="search_query" ).embeddings[0]
# Calculate similarities def sim(a, b): return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))
scored_papers = [] for paper, emb in zip(papers, doc_embeddings): score = sim(query_embedding, emb) paper['semantic_score'] = score scored_papers.append(paper)
# Sort and slice scored_papers.sort(key=lambda x: x['semantic_score'], reverse=True) return scored_papers[:top_n]
def evaluate_with_llm(title, abstract): """Use GPT-4o-mini to execute structured JSON screening.""" try: response = openai_client.chat.completions.create( model="gpt-4o-mini", messages=[ {"role": "system", "content": SCREENING_PROMPT}, {"role": "user", "content": f"Title: {title}\nAbstract: {abstract}"} ], response_format={"type": "json_object"}, temperature=0.0 ) payload = json.loads(response.choices[0].message.content) return payload.get("decision", "EXCLUDE"), payload.get("reasoning", "No explanation.") except Exception as e: return "EXCLUDE", f"Error during LLM assessment: {str(e)}"
def run_pipeline(): # 1. Broad keyword search search_keyword = f'"{CONCEPT_TERM}" AND ("digital" OR "phone" OR "app" OR "SMS") AND ("adherence" OR "monitoring")' raw_data = fetch_openalex_papers(search_keyword, limit=30) if not raw_data: print("[-] No content fetched. Exiting.") return # 2. Semantic Rank via Embeddings candidates = semantic_rank(raw_data, SEMANTIC_QUERY, top_n=10) # 3. Structural Evaluation with LLM final_results = [] print("\n[*] Initializing structured screening via GPT-4o-mini...") for idx, paper in enumerate(candidates): decision, reason = evaluate_with_llm(paper['title'], paper['abstract']) print(f"[{idx+1}/10] {paper['title'][:50]}... -> {decision}") final_results.append({ 'Title': paper['title'], 'Year': paper['year'], 'Semantic Score': round(paper['semantic_score'], 4), 'Decision': decision, 'Reasoning': reason, 'DOI': paper['doi'] }) df = pd.DataFrame(final_results) # Display Included Works included_df = df[df['Decision'] == 'INCLUDE'] print(f"\n[+] Pipeline execution completed. Included papers ({len(included_df)}/{len(df)}):") print(included_df[['Title', 'Semantic Score', 'Reasoning']].to_string())
if __name__ == "__main__": run_pipeline() ```
## Best Practices
Building an automated pipeline for literature reviews requires managing API calls, controlling costs, and ensuring that the outputs are high quality and reproducible.
### 1. Robust Abstract Reconstruction As demonstrated in our end-to-end pipeline, OpenAlex stores its metadata abstracts as an `abstract_inverted_index` rather than raw text to comply with copyright restrictions. When creating abstract processing engines:
- Implement defensive code to map indices back to continuous strings. - Re-index with safety spaces for punctuations and multi-word indexings. - Fall back to the title attributes if abstracts cannot be parsed or are empty.
### 2. Managing API Costs & Throttling Large-scale literature screening can involve processing thousands of titles and abstracts. Operating at this scale require cost management strategies:
- **Use Cost-Effective Models first**: Always run initial passes with fast, cost-effective models (like `gpt-4o-mini`). Save larger models (like `gpt-4o`) for downstream tasks like extracting detailed data or synthesizing findings from selected papers. - **Batched Semantic Filtering**: Perform vector embeddings first to narrow down your corpus (e.g., from 10,000 keyword matches to 500 semantic candidates) using Cohere or open-source local vector models (`all-MiniLM-L6-v2`). Only run LLM classification prompts on candidate records that pass this semantic filter threshold. - **Implement rate limiting and backoffs**: When contacting OpenAlex or OpenAI endpoints, build in retry decorator logic (such as `tenacity`) to catch `RateLimitError` or HTTP status codes `429` / `503`.
### 3. Mitigating Hallucinations Generative models can make mistakes when assessing evidence. This is especially risky in systematic reviews, where accuracy is critical.
- **Strict Formatting with JSON Mode**: Use structured output mechanisms (e.g., setting `response_format={"type": "json_object"}` in OpenAI) to force models to return structured decisions rather than conversational text. - **Ground the Context**: Instruct the prompt to limit its evaluation strictly to the provided title and abstract text. Emphasize that it should not extrapolate or rely on its pre-existing training data to make assumptions about study outcomes if they are not written directly in the provided text. - **Human-in-the-Loop Validation**: Do not treat the LLM as the final decision-maker. Use the pipeline as a screening assistant to filter out clear exclusions, and present the final matches to human reviewers for verification.
### 4. Code & Prompt Versioning Academic systematic reviews require reproducibility. To ensure your automated pipeline meets peer-reviewed standards:
- Pin the system versions of the models you use (e.g., compile your work using `gpt-4o-mini-2024-07-18` rather than dynamic alias targets like `gpt-4o-mini`). - Commit exact prompt parameters, system definitions, and filtering thresholds within code repositories to ensure other researchers can run the exact same search logic. - Log your intermediate pipeline steps, including the raw abstracts retrieved and the semantic similarity scores, as part of your research documentation. _
FAQ
How do I find a real estate agent in Portugal?
Use the directory filters to compare agents by city, specialty and language before sending a request.
Which real estate agent works in Portugal?
Anabela Ferreira Tavares is listed as a real estate agent for Portugal.
Can I request help from a verified real estate agent?
Yes. Use the directory request form and the nearest available verified realtor can contact you within 24 hours.
How can I choose an agent if the rating is not filled yet?
Compare the agent's location, company, specialty, languages and profile completeness, then request more information before cooperation.
About the platform
What is AI Realty?
For property buyers
AI Realty is a directory of verified real estate agents across Europe. Compare agents by city, language and specialty, then contact them directly — no middlemen, no fees.
Browse the directoryFor real estate agents
Your professional page generates inbound leads for free. Claim it, complete your profile and launch listing-promotion campaigns on Instagram, TikTok, YouTube and Facebook from one dashboard.
How it works for realtors