Update utils.py
Browse files
    	
        utils.py
    CHANGED
    
    | @@ -24,30 +24,60 @@ class CSVAnalyzer: | |
| 24 | 
             
                    self.tokenizer, self.model = CSVAnalyzer.load_model()
         | 
| 25 |  | 
| 26 | 
             
                def prepare_context(self, df: pd.DataFrame) -> str:
         | 
|  | |
|  | |
|  | |
| 27 | 
             
                    try:
         | 
| 28 | 
             
                        if df.empty:
         | 
| 29 | 
             
                            return "Keine Daten verfügbar"
         | 
| 30 |  | 
| 31 | 
            -
                        #  | 
| 32 | 
            -
                         | 
| 33 |  | 
| 34 | 
            -
                         | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
|  | |
|  | |
| 41 |  | 
| 42 | 
            -
                             | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 43 |  | 
| 44 | 
            -
                        #  | 
| 45 | 
            -
                         | 
| 46 | 
            -
                         | 
| 47 | 
            -
                            context +=  | 
| 48 | 
            -
                            for  | 
| 49 | 
            -
                                context += f"- { | 
| 50 | 
            -
             | 
|  | |
|  | |
|  | |
|  | |
|  | |
|  | |
| 51 |  | 
| 52 | 
             
                        return context
         | 
| 53 |  | 
| @@ -55,17 +85,23 @@ class CSVAnalyzer: | |
| 55 | 
             
                        raise Exception(f"Fehler bei der Kontextvorbereitung: {str(e)}")
         | 
| 56 |  | 
| 57 | 
             
                def generate_response(self, context: str, query: str) -> str:
         | 
| 58 | 
            -
                    prompt = f"""<|system|> | 
|  | |
| 59 | 
             
            Berücksichtige dabei:
         | 
| 60 | 
            -
            1.  | 
| 61 | 
            -
            2.  | 
| 62 | 
            -
            3.  | 
|  | |
|  | |
|  | |
|  | |
| 63 |  | 
| 64 | 
             
            <|user|>
         | 
|  | |
| 65 | 
             
            {context}
         | 
| 66 |  | 
|  | |
| 67 | 
             
            {query}
         | 
| 68 | 
            -
            Nenne direkt das problematischste Gebäude und begründe kurz warum.
         | 
| 69 |  | 
| 70 | 
             
            <|assistant|>"""
         | 
| 71 |  | 
| @@ -74,7 +110,7 @@ Nenne direkt das problematischste Gebäude und begründe kurz warum. | |
| 74 | 
             
                            prompt,
         | 
| 75 | 
             
                            return_tensors="pt",
         | 
| 76 | 
             
                            truncation=True,
         | 
| 77 | 
            -
                            max_length= | 
| 78 | 
             
                            padding=True,
         | 
| 79 | 
             
                            return_attention_mask=True
         | 
| 80 | 
             
                        )
         | 
| @@ -83,8 +119,8 @@ Nenne direkt das problematischste Gebäude und begründe kurz warum. | |
| 83 | 
             
                            outputs = self.model.generate(
         | 
| 84 | 
             
                                input_ids=inputs["input_ids"],
         | 
| 85 | 
             
                                attention_mask=inputs["attention_mask"],
         | 
| 86 | 
            -
                                max_new_tokens= | 
| 87 | 
            -
                                temperature=0. | 
| 88 | 
             
                                top_p=0.95,
         | 
| 89 | 
             
                                repetition_penalty=1.15,
         | 
| 90 | 
             
                                do_sample=True
         | 
|  | |
| 24 | 
             
                    self.tokenizer, self.model = CSVAnalyzer.load_model()
         | 
| 25 |  | 
| 26 | 
             
                def prepare_context(self, df: pd.DataFrame) -> str:
         | 
| 27 | 
            +
                    """
         | 
| 28 | 
            +
                    Bereitet einen allgemeinen Kontext aus dem DataFrame vor.
         | 
| 29 | 
            +
                    """
         | 
| 30 | 
             
                    try:
         | 
| 31 | 
             
                        if df.empty:
         | 
| 32 | 
             
                            return "Keine Daten verfügbar"
         | 
| 33 |  | 
| 34 | 
            +
                        # Grundlegende Informationen
         | 
| 35 | 
            +
                        context = "DATASET ÜBERSICHT:\n\n"
         | 
| 36 |  | 
| 37 | 
            +
                        # Dimensionen
         | 
| 38 | 
            +
                        context += f"Datensatzgröße: {len(df)} Zeilen, {len(df.columns)} Spalten\n\n"
         | 
| 39 | 
            +
                        
         | 
| 40 | 
            +
                        # Spaltenliste mit Datentypen
         | 
| 41 | 
            +
                        context += "SPALTENINFORMATIONEN:\n"
         | 
| 42 | 
            +
                        for col in df.columns:
         | 
| 43 | 
            +
                            dtype = df[col].dtype
         | 
| 44 | 
            +
                            non_null = df[col].count()
         | 
| 45 | 
            +
                            null_percentage = (len(df) - non_null) / len(df) * 100
         | 
| 46 |  | 
| 47 | 
            +
                            # Erkennung spezieller Datentypen
         | 
| 48 | 
            +
                            if pd.api.types.is_datetime64_any_dtype(df[col]):
         | 
| 49 | 
            +
                                date_range = f"von {df[col].min()} bis {df[col].max()}"
         | 
| 50 | 
            +
                                context += f"- {col} (Datum): {date_range}, {null_percentage:.1f}% NULL\n"
         | 
| 51 | 
            +
                            elif pd.api.types.is_numeric_dtype(df[col]):
         | 
| 52 | 
            +
                                context += f"- {col} (Numerisch): Min={df[col].min():.2f}, Max={df[col].max():.2f}, {null_percentage:.1f}% NULL\n"
         | 
| 53 | 
            +
                            else:
         | 
| 54 | 
            +
                                unique_values = df[col].nunique()
         | 
| 55 | 
            +
                                context += f"- {col} (Text): {unique_values} eindeutige Werte, {null_percentage:.1f}% NULL\n"
         | 
| 56 | 
            +
                        
         | 
| 57 | 
            +
                        # Grundlegende Statistiken für numerische Spalten
         | 
| 58 | 
            +
                        numeric_cols = df.select_dtypes(include=['int64', 'float64']).columns
         | 
| 59 | 
            +
                        if not numeric_cols.empty:
         | 
| 60 | 
            +
                            context += "\nNUMERISCHE STATISTIKEN:\n"
         | 
| 61 | 
            +
                            stats = df[numeric_cols].describe()
         | 
| 62 | 
            +
                            for col in numeric_cols:
         | 
| 63 | 
            +
                                context += f"- {col}:\n"
         | 
| 64 | 
            +
                                context += f"  Durchschnitt: {stats[col]['mean']:.2f}\n"
         | 
| 65 | 
            +
                                context += f"  Median: {stats[col]['50%']:.2f}\n"
         | 
| 66 | 
            +
                                context += f"  Standardabweichung: {stats[col]['std']:.2f}\n"
         | 
| 67 |  | 
| 68 | 
            +
                        # Zeitliche Informationen, falls vorhanden
         | 
| 69 | 
            +
                        date_cols = df.select_dtypes(include=['datetime64']).columns
         | 
| 70 | 
            +
                        if not date_cols.empty:
         | 
| 71 | 
            +
                            context += "\nZEITLICHE INFORMATIONEN:\n"
         | 
| 72 | 
            +
                            for col in date_cols:
         | 
| 73 | 
            +
                                context += f"- {col}:\n"
         | 
| 74 | 
            +
                                context += f"  Zeitspanne: von {df[col].min()} bis {df[col].max()}\n"
         | 
| 75 | 
            +
                                context += f"  Anzahl eindeutiger Daten: {df[col].nunique()}\n"
         | 
| 76 | 
            +
                        
         | 
| 77 | 
            +
                        # Stichprobe der Daten
         | 
| 78 | 
            +
                        context += "\nDATENBEISPIELE:\n"
         | 
| 79 | 
            +
                        sample = df.head(3).to_string()
         | 
| 80 | 
            +
                        context += f"{sample}\n"
         | 
| 81 |  | 
| 82 | 
             
                        return context
         | 
| 83 |  | 
|  | |
| 85 | 
             
                        raise Exception(f"Fehler bei der Kontextvorbereitung: {str(e)}")
         | 
| 86 |  | 
| 87 | 
             
                def generate_response(self, context: str, query: str) -> str:
         | 
| 88 | 
            +
                    prompt = f"""<|system|>
         | 
| 89 | 
            +
            Du bist ein Datenanalyst, der CSV-Dateien analysiert. Deine Aufgabe ist es, Fragen über die Daten zu beantworten.
         | 
| 90 | 
             
            Berücksichtige dabei:
         | 
| 91 | 
            +
            1. Die Struktur und die Arten der verfügbaren Daten
         | 
| 92 | 
            +
            2. Statistische Informationen, falls relevant
         | 
| 93 | 
            +
            3. Mögliche Zusammenhänge zwischen verschiedenen Spalten
         | 
| 94 | 
            +
            4. Zeitliche Muster, falls Datumsinformationen vorhanden sind
         | 
| 95 | 
            +
             | 
| 96 | 
            +
            Antworte präzise und faktenbasiert. Wenn die Frage nicht mit den verfügbaren Daten beantwortet werden kann, 
         | 
| 97 | 
            +
            erkläre warum.
         | 
| 98 |  | 
| 99 | 
             
            <|user|>
         | 
| 100 | 
            +
            KONTEXT:
         | 
| 101 | 
             
            {context}
         | 
| 102 |  | 
| 103 | 
            +
            FRAGE:
         | 
| 104 | 
             
            {query}
         | 
|  | |
| 105 |  | 
| 106 | 
             
            <|assistant|>"""
         | 
| 107 |  | 
|  | |
| 110 | 
             
                            prompt,
         | 
| 111 | 
             
                            return_tensors="pt",
         | 
| 112 | 
             
                            truncation=True,
         | 
| 113 | 
            +
                            max_length=2048,  # Erhöht für komplexere Analysen
         | 
| 114 | 
             
                            padding=True,
         | 
| 115 | 
             
                            return_attention_mask=True
         | 
| 116 | 
             
                        )
         | 
|  | |
| 119 | 
             
                            outputs = self.model.generate(
         | 
| 120 | 
             
                                input_ids=inputs["input_ids"],
         | 
| 121 | 
             
                                attention_mask=inputs["attention_mask"],
         | 
| 122 | 
            +
                                max_new_tokens=256,  # Erhöht für ausführlichere Antworten
         | 
| 123 | 
            +
                                temperature=0.7,     # Erhöht für kreativere Analysen
         | 
| 124 | 
             
                                top_p=0.95,
         | 
| 125 | 
             
                                repetition_penalty=1.15,
         | 
| 126 | 
             
                                do_sample=True
         |