Grobe Funktionsdarstellung:
- Dokument einlesen
- Inhalt(e) auswerten
- „Fragen“ an die Inhalte „stellen“ und geeignete Antworten identifizieren
- Reporting.
import fitz # PyMuPDF
from transformers import pipeline, AutoModelForQuestionAnswering, AutoTokenizer
import re
import pandas as pd
from io import BytesIO
# Funktion zum Einlesen des Kontextes aus einer PDF-Datei
def read_text_from_pdf(file_path):
document = http://fitz.open(file_path)
pages = []
for page_num, page in enumerate(document):
text = page.get_text()
pages.append((text, page_num + 1)) # Speichert den Text und die Seitennummer
document.close()
return pages
# Funktion zum Einlesen der Fragen aus einer Textdatei
def read_questions_from_file(file_path):
with open(file_path, 'r', encoding='utf-8') as file:
questions = file.readlines()
return [question.strip() for question in questions]
# Funktion zur Bereinigung der Zahlenformatierung
def clean_number_format(text):
# Entfernt Tausendertrennzeichen und stellt Dezimalpunkte sicher
text = re.sub(r'(\d)(?=(\d{3})+(\.|\b))', r'\1.', text) # Tausendertrennzeichen entfernen
text = re.sub(r'(?<!\d)(\d+)(?=\.\d+)', r'\1.', text) # Dezimalpunkt hinzufügen
return text
# Funktion zum Finden des relevanten Textabschnitts
def find_relevant_text(context, answer_start, answer_end):
# Finde die Textstelle um die Antwort herum
context_len = len(context)
start = max(answer_start - 100, 0)
end = min(answer_end + 100, context_len)
return context[start:end]
# Funktion zum Erstellen von Reports in verschiedenen Formaten
def generate_reports(answers, html_file, csv_file, xlsx_file):
# Erstellen eines DataFrames für die Berichterstellung
df = pd.DataFrame(answers, columns=["Frage", "Antwort", "Seite", "Score", "Textstelle"])
# HTML-Bericht
html_content = http://df.to_html(index=False, escape=False, formatters={'Textstelle': lambda x: x.replace('\n', '<br>')})
# HTML-Kopf und -Fuß
html_header = """
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Frage-Antwort-Bericht</title>
<style>
body { font-family: Arial, sans-serif; margin: 20px; }
h1 { color: #333; }
table { width: 100%; border-collapse: collapse; margin-top: 20px; }
th, td { padding: 12px; text-align: left; border-bottom: 1px solid #ddd; }
th { background-color: #f4f4f4; }
tr:hover { background-color: #f1f1f1; }
</style>
</head>
<body>
<h1>Frage-Antwort-Bericht</h1>
<p>Erstellt am: {date}</p>
<p>Bericht über Fragen und Antworten basierend auf dem bereitgestellten Kontext.</p>
""".format(date=http://pd.Timestamp.now().strftime("%d.%m.%Y %H:%M:%S"))
html_footer = """
</body>
</html>
"""
full_html_content = html_header + html_content + html_footer
with open(html_file, 'w', encoding='utf-8') as f:
f.write(full_html_content)
# CSV-Bericht
http://df.to_csv(csv_file, index=False, encoding='utf-8')
# XLSX-Bericht
http://df.to_excel(xlsx_file, index=False, engine='openpyxl')
# Pfad zur Datei mit dem Kontext und zur Textdatei mit den Fragen
context_file = "module/content.pdf" # Pfad zur PDF-Datei mit dem Kontext
questions_file = "module/fragen.txt" # Pfad zur Datei mit den Fragen
# Pfade zu den Berichtdateien
html_file = "report.html"
csv_file = "report.csv"
xlsx_file = "report.xlsx"
# Laden des Modells und Tokenizers für deutsche Frage-Antwort-Aufgaben
model_name = "deepset/gelectra-base-germanquad"
model = AutoModelForQuestionAnswering.from_pretrained(model_name)
tokenizer = AutoTokenizer.from_pretrained(model_name)
# Erstellen der Frage-Antwort-Pipeline
nlp = pipeline("question-answering", model=model, tokenizer=tokenizer)
# Einlesen des Kontextes aus der PDF-Datei
contexts = read_text_from_pdf(context_file)
# Einlesen der Fragen
questions = read_questions_from_file(questions_file)
# Beantwortung der Fragen und Sammlung der Ergebnisse
answers = []
for question in questions:
for context, page_num in contexts:
cleaned_context = clean_number_format(context) # Bereinigung des Kontextes
result = nlp(question=question, context=cleaned_context, max_answer_len=100)
if result['score'] > 0.5: # Optional: Setze einen Schwellenwert für die Mindest-Score
answer_start = result['start']
answer_end = result['end']
relevant_text = find_relevant_text(cleaned_context, answer_start, answer_end)
answers.append((question, result['answer'], page_num, result['score'], relevant_text))
# Konsolenausgabe und Generierung der Berichte
for question in questions:
answers_found = [a for a in answers if a[0] == question]
if answers_found:
print(f"Frage: {question}")
for answer, page_num, score, relevant_text in answers_found:
print(f"Antwort: {answer}")
print(f"Seite: {page_num}")
print(f"Score: {score:.2f}")
print(f"Textstelle: {relevant_text}\n")
else:
print(f"Frage: {question}")
print("Antwort: Keine Antwort gefunden\n")
# Generierung der Berichte
generate_reports(answers, html_file, csv_file, xlsx_file)