From 1cda95385516befbdbb21a415fc41c816dee8f8b Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Thu, 11 Jan 2024 10:14:53 +0100 Subject: [PATCH 01/16] Added new AI/training strategy --- Documentation/t5-model/README.md | 21 +++++++++++++++++- .../t5-model/arcticle_title_generator.png | Bin 0 -> 37286 bytes .../t5-model/dslim_bert_base_NER.png | Bin 0 -> 57847 bytes .../keyphrase_extraction_kbir_inspec.png | Bin 0 -> 114456 bytes ...ned_t5_model_german_base_nl36_800_data.png | Bin .../fine_tuned_t5_model_large_8k_data.png | Bin .../fine_tuned_t5_model_small_8k_data.png | Bin 7 files changed, 20 insertions(+), 1 deletion(-) create mode 100644 Documentation/t5-model/arcticle_title_generator.png create mode 100644 Documentation/t5-model/dslim_bert_base_NER.png create mode 100644 Documentation/t5-model/keyphrase_extraction_kbir_inspec.png rename Documentation/t5-model/{ => training_results}/fine_tuned_t5_model_german_base_nl36_800_data.png (100%) rename Documentation/t5-model/{ => training_results}/fine_tuned_t5_model_large_8k_data.png (100%) rename Documentation/t5-model/{ => training_results}/fine_tuned_t5_model_small_8k_data.png (100%) diff --git a/Documentation/t5-model/README.md b/Documentation/t5-model/README.md index 3db2468d..856dcbbe 100644 --- a/Documentation/t5-model/README.md +++ b/Documentation/t5-model/README.md @@ -74,4 +74,23 @@ - What can be done with it? - Is it necessary, and should we use it? - Investigate how to use Monitoring: - - How can it be utilized for our training. \ No newline at end of file + - How can it be utilized for our training. + + +## NEW AI Strategy: +- Title will be generated via "czearing/article-title-generator" model from Hugging Face. + - https://huggingface.co/czearing/article-title-generator + ![img.png](arcticle_title_generator.png) + +- AffectedPerson will be generated via "dslim/bert-base-NER" model from Hugging Face. + - https://huggingface.co/dslim/bert-base-NER + ![img.png](dslim_bert_base_NER.png) + +- Keywords will be generated via "ml6team/keyphrase-extraction-kbir-inspec" model from Hugging Face. + - ![img.png](keyphrase_extraction_kbir_inspec.png) + +- Description will be the Problem description text (input text), where Subject and signatur is cut out. + +- Service & requestType will be our main focus for training: For that will fine tune a text classification model. +- Category & priority will be our second focus: For that will fine tune a text classification model. +- CustomerPriority: For that will also fine tune a text classification model. \ No newline at end of file diff --git a/Documentation/t5-model/arcticle_title_generator.png b/Documentation/t5-model/arcticle_title_generator.png new file mode 100644 index 0000000000000000000000000000000000000000..78fcaa41993bc0e1319355dbabba9c7dcf465b3d GIT binary patch literal 37286 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 BapnL3 literal 0 HcmV?d00001 diff --git a/Documentation/t5-model/dslim_bert_base_NER.png b/Documentation/t5-model/dslim_bert_base_NER.png new file mode 100644 index 0000000000000000000000000000000000000000..3d7f49a3683030e68bfbc18a9578497de066b777 GIT binary patch literal 57847 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

I#_a!~Xpyr(n;ijUv>)1vw~ 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

%Gw;_@05+!@%0Fo0P!qCZ1&z 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 Date: Sat, 13 Jan 2024 11:12:01 +0100 Subject: [PATCH 02/16] Added AI-Service which implements the new AI Strategy, now multiple models are used to create Ticket. Also Fixed logger-encoding error. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl Signed-off-by: Koffi Tino Gnagniko --- Backend/__init__.py | 0 Backend/app/api/v1/ticket_api.py | 22 +++--- Backend/app/dependency/ai_service.py | 5 ++ Backend/app/email/main.py | 3 +- Backend/app/model/ai_service/__init__.py | 0 .../app/model/ai_service/ai_ticket_service.py | 75 +++++++++++++++++++ Backend/app/model/train/__init__.py | 0 .../model/{t5 => train}/custom_data_set.py | 0 Backend/app/model/{t5 => train}/prompt.txt | 0 .../app/model/{ => train}/test_data/README.md | 0 .../test_data/test_data_anna/test_data.json | 0 .../test_data/test_data_fabian/data.json | 0 .../test_data/test_data_garvin/data.json | 0 .../test_data/test_data_irild/data.json | 0 .../test_data/test_data_marco/data.json | 0 .../test_data/test_data_sajjad/data.json | 0 .../test_data/test_data_tino/data.json | 0 Backend/app/model/{t5 => train}/text.csv | 0 Backend/app/model/{t5 => train}/tickets.json | 0 .../app/model/{t5 => train}/train_t5_model.py | 0 Backend/app/util/logger.py | 4 +- Backend/requirements.txt | 3 +- Documentation/t5-model/README.md | 7 +- 23 files changed, 100 insertions(+), 19 deletions(-) create mode 100644 Backend/__init__.py create mode 100644 Backend/app/dependency/ai_service.py create mode 100644 Backend/app/model/ai_service/__init__.py create mode 100644 Backend/app/model/ai_service/ai_ticket_service.py create mode 100644 Backend/app/model/train/__init__.py rename Backend/app/model/{t5 => train}/custom_data_set.py (100%) rename Backend/app/model/{t5 => train}/prompt.txt (100%) rename Backend/app/model/{ => train}/test_data/README.md (100%) rename Backend/app/model/{ => train}/test_data/test_data_anna/test_data.json (100%) rename Backend/app/model/{ => train}/test_data/test_data_fabian/data.json (100%) rename Backend/app/model/{ => train}/test_data/test_data_garvin/data.json (100%) rename Backend/app/model/{ => train}/test_data/test_data_irild/data.json (100%) rename Backend/app/model/{ => train}/test_data/test_data_marco/data.json (100%) rename Backend/app/model/{ => train}/test_data/test_data_sajjad/data.json (100%) rename Backend/app/model/{ => train}/test_data/test_data_tino/data.json (100%) rename Backend/app/model/{t5 => train}/text.csv (100%) rename Backend/app/model/{t5 => train}/tickets.json (100%) rename Backend/app/model/{t5 => train}/train_t5_model.py (100%) diff --git a/Backend/__init__.py b/Backend/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Backend/app/api/v1/ticket_api.py b/Backend/app/api/v1/ticket_api.py index f1dc83a1..0d349a3a 100644 --- a/Backend/app/api/v1/ticket_api.py +++ b/Backend/app/api/v1/ticket_api.py @@ -1,18 +1,17 @@ -from bson import ObjectId -from fastapi import APIRouter, HTTPException, UploadFile -from fastapi.params import Depends, File, Path, Body -from starlette import status -from app.service.email_service import EmailService -from app.dependency.email_service import get_email_service - from app.api.dto.text_input import TextInput from app.api.dto.ticket import Ticket +from app.dependency.ai_service import get_ai_ticket_service from app.dependency.db_service import get_ticket_db_service, get_user_db_service -from app.dependency.trained_t5_model import get_trained_t5_model -from app.model.t5.use_trained_t5_model import TrainedT5Model +from app.dependency.email_service import get_email_service +from app.model.ai_service.ai_ticket_service import AITicketService +from app.service.email_service import EmailService from app.service.ticket_db_service import TicketDBService from app.service.user_db_service import UserDBService from app.util.logger import logger +from bson import ObjectId +from fastapi import APIRouter, HTTPException, UploadFile +from fastapi.params import Depends, File, Path, Body +from starlette import status router = APIRouter() @@ -20,10 +19,10 @@ @router.post("/ticket/text", status_code=status.HTTP_201_CREATED, response_model=Ticket) async def process_text( input: TextInput = Body(default=TextInput()), - trained_t5_model: TrainedT5Model = Depends(get_trained_t5_model), ticket_db_service: TicketDBService = Depends(get_ticket_db_service), email_service: EmailService = Depends(get_email_service), user_db_service: UserDBService = Depends(get_user_db_service), + ticket_service: AITicketService = Depends(get_ai_ticket_service), ): """ Receive Text from the Frontend @@ -49,7 +48,7 @@ async def process_text( # Run the model to process the input text logger.info("Running the model...") - received_dict = trained_t5_model.run_model(input.text) + received_dict = ticket_service.create_ticket(input.text) logger.info("Model execution complete. Result: %s", received_dict) # Set service based on user's location @@ -57,6 +56,7 @@ async def process_text( user = user_db_service.get_user_by_email(input.email) if user and user.location: if not received_dict.get("location") or received_dict["location"] == "": + logger.info("Setting ticket's service to user's location...") received_dict["location"] = user.location # Save the ticket to the database using the TicketDBService diff --git a/Backend/app/dependency/ai_service.py b/Backend/app/dependency/ai_service.py new file mode 100644 index 00000000..cf76a9e4 --- /dev/null +++ b/Backend/app/dependency/ai_service.py @@ -0,0 +1,5 @@ +from app.model.ai_service.ai_ticket_service import AITicketService + + +def get_ai_ticket_service() -> AITicketService: + return AITicketService() diff --git a/Backend/app/email/main.py b/Backend/app/email/main.py index b55d5839..ace8cbaf 100644 --- a/Backend/app/email/main.py +++ b/Backend/app/email/main.py @@ -35,8 +35,7 @@ def run_proxy(): # print(attachments) # send message to backend - email = f"Von: {sender}\nBetreff: {subject}\n {content}" - json_input = {"text": email} + json_input = {"text": content} if content != "": response = requests.post( "http://localhost:8000/api/v1/ticket/text", diff --git a/Backend/app/model/ai_service/__init__.py b/Backend/app/model/ai_service/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Backend/app/model/ai_service/ai_ticket_service.py b/Backend/app/model/ai_service/ai_ticket_service.py new file mode 100644 index 00000000..70a5e3f8 --- /dev/null +++ b/Backend/app/model/ai_service/ai_ticket_service.py @@ -0,0 +1,75 @@ +from transformers import pipeline +from app.util.logger import logger +from app.enum.customer_prio import CustomerPrio +from app.enum.prio import Prio + + +class AITicketService: + def __init__(self): + self.title_generation_pipe = pipeline( + "text2text-generation", model="czearing/article-title-generator" + ) + self.affected_person_generation_pipe = pipeline( + "token-classification", model="dslim/bert-base-NER" + ) + self.keywords_generation_pipe = pipeline( + "token-classification", model="ml6team/keyphrase-extraction-kbir-inspec" + ) + + def create_ticket(self, input_text) -> dict: + title = self.generate_title(input_text) + keywords = self.generate_keywords(input_text) + affected_person = self.generate_affected_person(input_text) + + ticket_dict = { + "title": title, + "location": "", + "category": "", + "keywords": keywords, + "customerPriority": CustomerPrio.can_work, + "affectedPerson": affected_person, + "description": input_text, + "priority": Prio.low, + "attachments": [], + } + + return ticket_dict + + def generate_title(self, input_text) -> str: + generated_title = self.title_generation_pipe(input_text)[0]["generated_text"] + return generated_title + + def generate_affected_person(self, input_text) -> str: + generated_output = self.affected_person_generation_pipe(input_text) + + if len(generated_output) > 0: + persons = [ + entity["word"] + for entity in generated_output + if "PER" in entity["entity"] + ] + generated_affected_person = " ".join(persons) + + return generated_affected_person + else: + logger.error("AI: Could not generate Affected Person") + return "" + + def generate_keywords(self, input_text) -> list: + generated_output = self.keywords_generation_pipe(input_text) + + if len(generated_output) > 0: + keywords = [ + entity["word"] + for entity in generated_output + if "KEY" in entity["entity"] + ] + return keywords + else: + logger.error("AI: Could not generate keywords") + return [] + + # def remove_email_signature(self, email_content) -> str: + # parsed_email = EmailReplyParser.parse_reply(email_content) + # print("Generated parsed_email:", parsed_email) + # return parsed_email diff --git a/Backend/app/model/train/__init__.py b/Backend/app/model/train/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/Backend/app/model/t5/custom_data_set.py b/Backend/app/model/train/custom_data_set.py similarity index 100% rename from Backend/app/model/t5/custom_data_set.py rename to Backend/app/model/train/custom_data_set.py diff --git a/Backend/app/model/t5/prompt.txt b/Backend/app/model/train/prompt.txt similarity index 100% rename from Backend/app/model/t5/prompt.txt rename to Backend/app/model/train/prompt.txt diff --git a/Backend/app/model/test_data/README.md b/Backend/app/model/train/test_data/README.md similarity index 100% rename from Backend/app/model/test_data/README.md rename to Backend/app/model/train/test_data/README.md diff --git a/Backend/app/model/test_data/test_data_anna/test_data.json b/Backend/app/model/train/test_data/test_data_anna/test_data.json similarity index 100% rename from Backend/app/model/test_data/test_data_anna/test_data.json rename to Backend/app/model/train/test_data/test_data_anna/test_data.json diff --git a/Backend/app/model/test_data/test_data_fabian/data.json b/Backend/app/model/train/test_data/test_data_fabian/data.json similarity index 100% rename from Backend/app/model/test_data/test_data_fabian/data.json rename to Backend/app/model/train/test_data/test_data_fabian/data.json diff --git a/Backend/app/model/test_data/test_data_garvin/data.json b/Backend/app/model/train/test_data/test_data_garvin/data.json similarity index 100% rename from Backend/app/model/test_data/test_data_garvin/data.json rename to Backend/app/model/train/test_data/test_data_garvin/data.json diff --git a/Backend/app/model/test_data/test_data_irild/data.json b/Backend/app/model/train/test_data/test_data_irild/data.json similarity index 100% rename from Backend/app/model/test_data/test_data_irild/data.json rename to Backend/app/model/train/test_data/test_data_irild/data.json diff --git a/Backend/app/model/test_data/test_data_marco/data.json b/Backend/app/model/train/test_data/test_data_marco/data.json similarity index 100% rename from Backend/app/model/test_data/test_data_marco/data.json rename to Backend/app/model/train/test_data/test_data_marco/data.json diff --git a/Backend/app/model/test_data/test_data_sajjad/data.json b/Backend/app/model/train/test_data/test_data_sajjad/data.json similarity index 100% rename from Backend/app/model/test_data/test_data_sajjad/data.json rename to Backend/app/model/train/test_data/test_data_sajjad/data.json diff --git a/Backend/app/model/test_data/test_data_tino/data.json b/Backend/app/model/train/test_data/test_data_tino/data.json similarity index 100% rename from Backend/app/model/test_data/test_data_tino/data.json rename to Backend/app/model/train/test_data/test_data_tino/data.json diff --git a/Backend/app/model/t5/text.csv b/Backend/app/model/train/text.csv similarity index 100% rename from Backend/app/model/t5/text.csv rename to Backend/app/model/train/text.csv diff --git a/Backend/app/model/t5/tickets.json b/Backend/app/model/train/tickets.json similarity index 100% rename from Backend/app/model/t5/tickets.json rename to Backend/app/model/train/tickets.json diff --git a/Backend/app/model/t5/train_t5_model.py b/Backend/app/model/train/train_t5_model.py similarity index 100% rename from Backend/app/model/t5/train_t5_model.py rename to Backend/app/model/train/train_t5_model.py diff --git a/Backend/app/util/logger.py b/Backend/app/util/logger.py index 550c2aa6..48f33a6f 100644 --- a/Backend/app/util/logger.py +++ b/Backend/app/util/logger.py @@ -6,14 +6,14 @@ def setup_logger(): logger.setLevel(logging.DEBUG) # Create a file handler - file_handler = logging.FileHandler("backend.log") + file_handler = logging.FileHandler("backend.log", encoding="utf-8") file_handler.setLevel(logging.DEBUG) # Create a console handler console_handler = logging.StreamHandler() console_handler.setLevel(logging.DEBUG) - # Create a logging format + # Create a logging format with UTF-8 encoding formatter = logging.Formatter( "%(asctime)s - %(name)s - %(levelname)s - %(message)s" ) diff --git a/Backend/requirements.txt b/Backend/requirements.txt index b06f0cd6..c3363c6b 100644 --- a/Backend/requirements.txt +++ b/Backend/requirements.txt @@ -12,4 +12,5 @@ pymongo==4.6.0 fastapi-utils==0.2.1 requests==2.31.0 python-multipart==0.0.6 -beautifulsoup4==4.12.2 \ No newline at end of file +beautifulsoup4==4.12.2 +email_reply_parser==0.5.12 \ No newline at end of file diff --git a/Documentation/t5-model/README.md b/Documentation/t5-model/README.md index 856dcbbe..5fef38df 100644 --- a/Documentation/t5-model/README.md +++ b/Documentation/t5-model/README.md @@ -80,14 +80,15 @@ ## NEW AI Strategy: - Title will be generated via "czearing/article-title-generator" model from Hugging Face. - https://huggingface.co/czearing/article-title-generator - ![img.png](arcticle_title_generator.png) + ![img.png](arcticle_title_generator.png) - AffectedPerson will be generated via "dslim/bert-base-NER" model from Hugging Face. - https://huggingface.co/dslim/bert-base-NER - ![img.png](dslim_bert_base_NER.png) + ![img.png](dslim_bert_base_NER.png) - Keywords will be generated via "ml6team/keyphrase-extraction-kbir-inspec" model from Hugging Face. - - ![img.png](keyphrase_extraction_kbir_inspec.png) + - https://huggingface.co/ml6team/keyphrase-extraction-kbir-inspec + ![img.png](keyphrase_extraction_kbir_inspec.png) - Description will be the Problem description text (input text), where Subject and signatur is cut out. From 4419bb82b2a6db7e79918a7b07098949bd89150b Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Sat, 13 Jan 2024 11:32:49 +0100 Subject: [PATCH 03/16] Added tests for ai-service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl Co-authored-by: Garvin Konopka Signed-off-by: Koffi Tino Gnagniko --- Backend/test/model/ai_ticket_service_test.py | 58 ++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 Backend/test/model/ai_ticket_service_test.py diff --git a/Backend/test/model/ai_ticket_service_test.py b/Backend/test/model/ai_ticket_service_test.py new file mode 100644 index 00000000..82905064 --- /dev/null +++ b/Backend/test/model/ai_ticket_service_test.py @@ -0,0 +1,58 @@ +import unittest +from unittest.mock import patch, Mock + +from app.model.ai_service.ai_ticket_service import AITicketService + + +class TestAITicketService(unittest.TestCase): + def test_create_ticket(self): + # Arrange + input_text = "Sample input text" + service = AITicketService() + + # Act + ticket_dict = service.create_ticket(input_text) + + # Assert + self.assertIsInstance(ticket_dict, dict) + self.assertIn("title", ticket_dict) + self.assertIn("location", ticket_dict) + + @patch("app.ai_ticket_service.pipeline") + def test_generate_title(self, mock_pipeline): + # Arrange + input_text = "Sample input text" + service = AITicketService() + mock_pipeline.return_value = Mock(return_value=[{"generated_text": "Generated Title"}]) + + # Act + generated_title = service.generate_title(input_text) + + # Assert + self.assertEqual(generated_title, "Generated Title") + + @patch("app.ai_ticket_service.pipeline") + def test_generate_affected_person(self, mock_pipeline): + # Arrange + input_text = "Sample input text" + service = AITicketService() + mock_pipeline.return_value = Mock(return_value=[{"entity": "B-PER", "word": "John"}]) + + # Act + generated_person = service.generate_affected_person(input_text) + + # Assert + self.assertEqual(generated_person, "John") + + @patch("app.ai_ticket_service.pipeline") + def test_generate_keywords(self, mock_pipeline): + # Arrange + input_text = "Sample input text" + service = AITicketService() + mock_pipeline.return_value = Mock(return_value=[{"entity": "KEY", "word": "Keyword"}]) + + # Act + generated_keywords = service.generate_keywords(input_text) + + # Assert + self.assertEqual(generated_keywords, ["Keyword"]) From 52930e26f240dd46624adc4df4ecafcc1a50bfa0 Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Mon, 15 Jan 2024 15:19:07 +0100 Subject: [PATCH 04/16] Fixed bugs in training code. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl --- .../text_classification/custom_data_set.py | 25 +++++-- .../model/train/text_classification/train.py | 71 +++++++++++-------- .../use_fine_tuned_model.py | 48 +++++++++++++ Backend/requirements.txt | 3 +- Backend/test/model/ai_ticket_service_test.py | 12 +++- 5 files changed, 121 insertions(+), 38 deletions(-) create mode 100644 Backend/app/model/train/text_classification/use_fine_tuned_model.py diff --git a/Backend/app/model/train/text_classification/custom_data_set.py b/Backend/app/model/train/text_classification/custom_data_set.py index 2acd2a8b..674af270 100644 --- a/Backend/app/model/train/text_classification/custom_data_set.py +++ b/Backend/app/model/train/text_classification/custom_data_set.py @@ -1,19 +1,27 @@ import json from torch.utils.data import Dataset +from sklearn.preprocessing import LabelEncoder +import torch class CustomDataset(Dataset): - def __init__( - self, tokenizer, data_paths, output_field, max_length=1024 - ): + def __init__(self, tokenizer, data_paths, output_field, max_length=512): self.tokenizer = tokenizer - self.max_length = max_length self.data_paths = data_paths self.data_set = [] self.output_field = output_field + self.max_length = max_length + + self.label_encoder = LabelEncoder() + self.label_encoder.fit(["Incident", "Service Request"]) + + print("================================") + print("labels", self.label_encoder.transform(["Incident", "Service Request"])) + print("================================") - # load data from files self.load_json() + all_labels = [data["ticket"][self.output_field] for data in self.data_set] + self.label_encoder.fit(all_labels) def __len__(self): return len(self.data_set) @@ -22,6 +30,8 @@ def __getitem__(self, idx): text_description = "\n".join(self.data_set[idx]["text"]) request_type = self.data_set[idx]["ticket"][self.output_field] + request_type_encoded = self.label_encoder.transform([request_type])[0] + inputs = self.tokenizer( text_description, add_special_tokens=True, @@ -30,10 +40,13 @@ def __getitem__(self, idx): return_tensors="pt", truncation=True, ) + + labels = torch.tensor(request_type_encoded, dtype=torch.long) + return { "input_ids": inputs.input_ids.flatten(), "attention_mask": inputs.attention_mask.flatten(), - "labels": request_type, + "labels": labels, } def load_json(self): diff --git a/Backend/app/model/train/text_classification/train.py b/Backend/app/model/train/text_classification/train.py index 7be57342..94bf7293 100644 --- a/Backend/app/model/train/text_classification/train.py +++ b/Backend/app/model/train/text_classification/train.py @@ -1,16 +1,15 @@ import argparse import os import time - import torch from torch.optim import AdamW from torch.utils.data import DataLoader from tqdm import tqdm -from transformers import ( - get_linear_schedule_with_warmup, - RobertaForSequenceClassification, - RobertaTokenizer, -) +from transformers import RobertaForSequenceClassification, RobertaTokenizer +from transformers import get_linear_schedule_with_warmup +from sklearn.metrics import confusion_matrix +import seaborn as sns +import matplotlib.pyplot as plt from custom_data_set import CustomDataset @@ -45,7 +44,7 @@ def parse_args(): parser.add_argument( "--save_model", action="store_true", - default=False, + default=True, help="For Saving the current Model", ) return parser.parse_args() @@ -63,15 +62,17 @@ def parse_args(): data_paths = [ os.path.join(test_dir, "test_data_garvin", "data_translated.json"), os.path.join(test_dir, "test_data_irild", "data_translated.json"), - os.path.join(test_dir, "test_data_marco", "data_translated.json"), + os.path.join(test_dir, "test_data_fabian", "data_translated.json"), os.path.join(test_dir, "test_data_sajjad", "data_translated.json"), + os.path.join(test_dir, "test_data_marco", "data_translated.json"), os.path.join(test_dir, "test_data_tino", "data_translated.json"), + os.path.join(test_dir, "test_data_with_gpt", "data_1.json"), + os.path.join(test_dir, "test_data_with_gpt", "data_2.json"), + os.path.join(test_dir, "test_data_with_gpt", "test_data.json"), ] -prompt_path = os.path.join(root_directory, "prompt.txt") - # Create datasets -custom_dataset = CustomDataset(tokenizer, data_paths, prompt_path, "requestType") +custom_dataset = CustomDataset(tokenizer, data_paths, "requestType") train_set, val_set = torch.utils.data.random_split( custom_dataset, [ @@ -122,30 +123,44 @@ def parse_args(): average_loss = total_loss / len(train_loader) epoch_time = time.time() - start_time - # Validation + # Validation with Confusion Matrix model.eval() - total_accuracy = 0 + val_true_labels = [] + val_predictions = [] + with torch.no_grad(): for batch in valid_loader: - # input_ids = batch["input_ids"].to(device) - # attention_mask = batch["attention_mask"].to(device) - # labels = batch["labels"].to(device) - # - # outputs = model( - # input_ids=input_ids, attention_mask=attention_mask, labels=labels - # ) - # # Add your validation logic here - # total_accuracy += outputs.eq(labels).sum().item() # Replace this with actual accuracy calculation - pass - - average_accuracy = total_accuracy / len(valid_loader) + input_ids = batch["input_ids"].to(device) + attention_mask = batch["attention_mask"].to(device) + labels = batch["labels"].to(device) + + outputs = model(input_ids=input_ids, attention_mask=attention_mask) + logits = outputs.logits + preds = torch.argmax(logits, dim=1) + + val_true_labels.extend(labels.cpu().numpy()) + val_predictions.extend(preds.cpu().numpy()) + + conf_matrix = confusion_matrix(val_true_labels, val_predictions) + ax = sns.heatmap(conf_matrix, annot=True, cmap="Blues") + + ax.set_title("Confusion Matrix\n") + ax.set_xlabel("\nPredicted Values") + ax.set_ylabel("Actual Values ") + + ax.xaxis.set_ticklabels(["False", "True"]) + ax.yaxis.set_ticklabels(["False", "True"]) + + # Save the confusion matrix plot as a PNG file + plt.savefig(f"confusion_matrix_epoch_{epoch + 1}.png", bbox_inches="tight") + plt.close() + print( f"Epoch: {((epoch + 1) / args.epochs) * 100:.0f}% | {epoch + 1}/{args.epochs} [{epoch_time:.2f}s/epoch]" ) print(f"Train Loss: {average_loss}") - print(f"Validation Accuracy: {average_accuracy}") # Save the fine-tuned model if args.save_model: - model.save_pretrained("fine_tuned_t5_model") - tokenizer.save_pretrained("fine_tuned_t5_model") + model.save_pretrained("fine_tuned_roberta_model") + tokenizer.save_pretrained("fine_tuned_roberta_model") diff --git a/Backend/app/model/train/text_classification/use_fine_tuned_model.py b/Backend/app/model/train/text_classification/use_fine_tuned_model.py new file mode 100644 index 00000000..52d5131e --- /dev/null +++ b/Backend/app/model/train/text_classification/use_fine_tuned_model.py @@ -0,0 +1,48 @@ +import torch +from transformers import RobertaForSequenceClassification, RobertaTokenizer + + +def load_model(model_path): + model = RobertaForSequenceClassification.from_pretrained(model_path) + tokenizer = RobertaTokenizer.from_pretrained(model_path) + return model, tokenizer + + +def prepare_data(tokenizer, text, max_length=512): + inputs = tokenizer( + text, + add_special_tokens=True, + max_length=max_length, + padding="max_length", + return_tensors="pt", + truncation=True, + ) + return inputs + + +def predict(model, tokenizer, text, device): + model.to(device) + model.eval() + + inputs = prepare_data(tokenizer, text) + input_ids = inputs["input_ids"].to(device) + attention_mask = inputs["attention_mask"].to(device) + + with torch.no_grad(): + outputs = model(input_ids=input_ids, attention_mask=attention_mask) + logits = outputs.logits + + preds = torch.argmax(logits, dim=1) + return preds + + +model_path = "./fine_tuned_roberta_model_request_type" +model, tokenizer = load_model(model_path) + + +device = "cuda" if torch.cuda.is_available() else "cpu" + +text = "Tableau dashboard is not reflecting real-time data. The connection to the database seems intact, but updates are delayed. This is critical for our daily operations." + +predictions = predict(model, tokenizer, text, device) +print("Predictions:", predictions) diff --git a/Backend/requirements.txt b/Backend/requirements.txt index c3363c6b..d587da6c 100644 --- a/Backend/requirements.txt +++ b/Backend/requirements.txt @@ -13,4 +13,5 @@ fastapi-utils==0.2.1 requests==2.31.0 python-multipart==0.0.6 beautifulsoup4==4.12.2 -email_reply_parser==0.5.12 \ No newline at end of file +email_reply_parser==0.5.12 +scikit-learn==1.3.2 \ No newline at end of file diff --git a/Backend/test/model/ai_ticket_service_test.py b/Backend/test/model/ai_ticket_service_test.py index 82905064..00f36f07 100644 --- a/Backend/test/model/ai_ticket_service_test.py +++ b/Backend/test/model/ai_ticket_service_test.py @@ -23,7 +23,9 @@ def test_generate_title(self, mock_pipeline): # Arrange input_text = "Sample input text" service = AITicketService() - mock_pipeline.return_value = Mock(return_value=[{"generated_text": "Generated Title"}]) + mock_pipeline.return_value = Mock( + return_value=[{"generated_text": "Generated Title"}] + ) # Act generated_title = service.generate_title(input_text) @@ -36,7 +38,9 @@ def test_generate_affected_person(self, mock_pipeline): # Arrange input_text = "Sample input text" service = AITicketService() - mock_pipeline.return_value = Mock(return_value=[{"entity": "B-PER", "word": "John"}]) + mock_pipeline.return_value = Mock( + return_value=[{"entity": "B-PER", "word": "John"}] + ) # Act generated_person = service.generate_affected_person(input_text) @@ -49,7 +53,9 @@ def test_generate_keywords(self, mock_pipeline): # Arrange input_text = "Sample input text" service = AITicketService() - mock_pipeline.return_value = Mock(return_value=[{"entity": "KEY", "word": "Keyword"}]) + mock_pipeline.return_value = Mock( + return_value=[{"entity": "KEY", "word": "Keyword"}] + ) # Act generated_keywords = service.generate_keywords(input_text) From f2894c648b037fc6cc278792bee7f1baaa322ab3 Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Mon, 15 Jan 2024 22:02:32 +0100 Subject: [PATCH 05/16] Updated AI-Service tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl Co-authored-by: Garvin Konopka Signed-off-by: Koffi Tino Gnagniko --- Backend/{ => test/model}/__init__.py | 0 Backend/test/model/ai_ticket_service_test.py | 58 +++++++++++--------- 2 files changed, 32 insertions(+), 26 deletions(-) rename Backend/{ => test/model}/__init__.py (100%) diff --git a/Backend/__init__.py b/Backend/test/model/__init__.py similarity index 100% rename from Backend/__init__.py rename to Backend/test/model/__init__.py diff --git a/Backend/test/model/ai_ticket_service_test.py b/Backend/test/model/ai_ticket_service_test.py index 00f36f07..8f1f93c0 100644 --- a/Backend/test/model/ai_ticket_service_test.py +++ b/Backend/test/model/ai_ticket_service_test.py @@ -1,10 +1,31 @@ import unittest -from unittest.mock import patch, Mock +from unittest.mock import MagicMock -from app.model.ai_service.ai_ticket_service import AITicketService +from app.model.ai_ticket_service.ai_ticket_service import AITicketService class TestAITicketService(unittest.TestCase): + def setUp(self): + self.ai_ticket_service = AITicketService() + + self.mock_title_pipeline = MagicMock() + self.mock_title_pipeline.return_value = [{"generated_text": "Mocked Title"}] + self.ai_ticket_service.title_generation_pipe = self.mock_title_pipeline + + self.mock_affected_person_pipeline = MagicMock() + self.mock_affected_person_pipeline.return_value = [ + {"entity": "B-PER", "word": "John"} + ] + self.ai_ticket_service.affected_person_generation_pipe = ( + self.mock_affected_person_pipeline + ) + + self.mock_keywords_pipeline = MagicMock() + self.mock_keywords_pipeline.return_value = [ + {"entity": "KEY", "word": "Keyword"} + ] + self.ai_ticket_service.generate_keywords = self.mock_keywords_pipeline + def test_create_ticket(self): # Arrange input_text = "Sample input text" @@ -18,47 +39,32 @@ def test_create_ticket(self): self.assertIn("title", ticket_dict) self.assertIn("location", ticket_dict) - @patch("app.ai_ticket_service.pipeline") - def test_generate_title(self, mock_pipeline): + def test_generate_title(self): # Arrange - input_text = "Sample input text" - service = AITicketService() - mock_pipeline.return_value = Mock( - return_value=[{"generated_text": "Generated Title"}] - ) + input_text = "Test Input Text" # Act - generated_title = service.generate_title(input_text) + result = self.ai_ticket_service.generate_title(input_text) # Assert - self.assertEqual(generated_title, "Generated Title") + self.assertEqual(result, "Mocked Title") - @patch("app.ai_ticket_service.pipeline") - def test_generate_affected_person(self, mock_pipeline): + def test_generate_affected_person(self): # Arrange input_text = "Sample input text" - service = AITicketService() - mock_pipeline.return_value = Mock( - return_value=[{"entity": "B-PER", "word": "John"}] - ) # Act - generated_person = service.generate_affected_person(input_text) + generated_person = self.ai_ticket_service.generate_affected_person(input_text) # Assert self.assertEqual(generated_person, "John") - @patch("app.ai_ticket_service.pipeline") - def test_generate_keywords(self, mock_pipeline): + def test_generate_keywords(self): # Arrange input_text = "Sample input text" - service = AITicketService() - mock_pipeline.return_value = Mock( - return_value=[{"entity": "KEY", "word": "Keyword"}] - ) # Act - generated_keywords = service.generate_keywords(input_text) + generated_keywords = self.ai_ticket_service.generate_keywords(input_text) # Assert - self.assertEqual(generated_keywords, ["Keyword"]) + self.assertEqual(generated_keywords, [{"entity": "KEY", "word": "Keyword"}]) From 45d102f4d7d5dd80b61f7e0fb37bf382cb99d283 Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Fri, 19 Jan 2024 19:26:38 +0100 Subject: [PATCH 06/16] Updated training code to include confident-matrix and learning curve. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl Signed-off-by: Koffi Tino Gnagniko --- .../ai_ticket_service/ai_ticket_service.py | 24 +++- .../text_classification/custom_data_set.py | 46 ++++--- .../model/train/text_classification/train.py | 113 ++++++++++++------ .../use_fine_tuned_model.py | 11 +- 4 files changed, 134 insertions(+), 60 deletions(-) diff --git a/Backend/app/model/ai_ticket_service/ai_ticket_service.py b/Backend/app/model/ai_ticket_service/ai_ticket_service.py index 866e152f..636f2928 100644 --- a/Backend/app/model/ai_ticket_service/ai_ticket_service.py +++ b/Backend/app/model/ai_ticket_service/ai_ticket_service.py @@ -15,11 +15,15 @@ def __init__(self): self.keywords_generation_pipe = pipeline( "token-classification", model="ml6team/keyphrase-extraction-kbir-inspec" ) + self.request_type_generation_pipe = pipeline( + "text-classification", model="TalkTix/roberta-base-request-type" + ) def create_ticket(self, input_text) -> dict: title = self.generate_title(input_text) keywords = self.generate_keywords(input_text) affected_person = self.generate_affected_person(input_text) + request_type = self.generate_request_type(input_text) ticket_dict = { "title": title, @@ -30,7 +34,7 @@ def create_ticket(self, input_text) -> dict: "affectedPerson": affected_person, "description": input_text, "priority": Prio.low, - "requestType": "", + "requestType": request_type, "attachments": [], } @@ -67,9 +71,25 @@ def generate_keywords(self, input_text) -> list: ] return keywords else: - logger.error("AI: Could not generate keywords") + logger.info("AI: Could not generate keywords") return [] + def generate_request_type(self, input_text) -> str: + generated_output = self.request_type_generation_pipe(input_text) + request_type_values = ["Incident", "Service Request"] + print(generated_output) + + if len(generated_output) > 0: + prediction_score = max(generated_output['score']) + if prediction_score < 0: + logger.info("AI: Request type prediction is to worse") + return "" + else: + logger.info("AI: Could not generate request type") + return "" + + + # def remove_email_signature(self, email_content) -> str: # parsed_email = EmailReplyParser.parse_reply(email_content) # print("Generated parsed_email:", parsed_email) diff --git a/Backend/app/model/train/text_classification/custom_data_set.py b/Backend/app/model/train/text_classification/custom_data_set.py index 674af270..835faad9 100644 --- a/Backend/app/model/train/text_classification/custom_data_set.py +++ b/Backend/app/model/train/text_classification/custom_data_set.py @@ -1,37 +1,52 @@ -import json from torch.utils.data import Dataset from sklearn.preprocessing import LabelEncoder import torch +import json class CustomDataset(Dataset): - def __init__(self, tokenizer, data_paths, output_field, max_length=512): + def __init__(self, tokenizer, data_paths, output_field, classes, max_length=512): self.tokenizer = tokenizer self.data_paths = data_paths self.data_set = [] self.output_field = output_field self.max_length = max_length + # Initialize label encoder with the given classes self.label_encoder = LabelEncoder() - self.label_encoder.fit(["Incident", "Service Request"]) - - print("================================") - print("labels", self.label_encoder.transform(["Incident", "Service Request"])) - print("================================") + self.label_encoder.fit(classes) + # Loading the data and encoding the labels self.load_json() - all_labels = [data["ticket"][self.output_field] for data in self.data_set] - self.label_encoder.fit(all_labels) + + def load_json(self): + for data_path in self.data_paths: + with open(data_path, 'r') as file: + data = json.load(file) + for item in data: + if item["ticket"][self.output_field] in self.label_encoder.classes_: + self.data_set.append(item) + else: + print(f"Ungültiges Label: {item['ticket'][self.output_field]}") def __len__(self): return len(self.data_set) def __getitem__(self, idx): - text_description = "\n".join(self.data_set[idx]["text"]) - request_type = self.data_set[idx]["ticket"][self.output_field] + item = self.data_set[idx] + # Check whether 'text' key is present in the item + if 'text' in item: + text_description = "\n".join(item['text']) + else: + text_description = "" + + request_type = item["ticket"][self.output_field] + + # Kodieren des Labels request_type_encoded = self.label_encoder.transform([request_type])[0] + # Tokenisieren des Textes inputs = self.tokenizer( text_description, add_special_tokens=True, @@ -41,15 +56,8 @@ def __getitem__(self, idx): truncation=True, ) - labels = torch.tensor(request_type_encoded, dtype=torch.long) - return { "input_ids": inputs.input_ids.flatten(), "attention_mask": inputs.attention_mask.flatten(), - "labels": labels, + "labels": torch.tensor(request_type_encoded, dtype=torch.long), } - - def load_json(self): - for data_path in self.data_paths: - with open(data_path) as file: - self.data_set += json.load(file) diff --git a/Backend/app/model/train/text_classification/train.py b/Backend/app/model/train/text_classification/train.py index 94bf7293..de9ca74b 100644 --- a/Backend/app/model/train/text_classification/train.py +++ b/Backend/app/model/train/text_classification/train.py @@ -10,10 +10,10 @@ from sklearn.metrics import confusion_matrix import seaborn as sns import matplotlib.pyplot as plt +import torch.nn.functional as F from custom_data_set import CustomDataset - def parse_args(): parser = argparse.ArgumentParser( description="Train a neural network to diffuse images" @@ -52,27 +52,39 @@ def parse_args(): args = parse_args() +#classes = ["Incident", "Service Request"] +#ticket_field = "requestType" +#classes = ['SAP ERP', 'Atlassian', 'Adobe', 'Salesforce', 'Reporting', 'Microsoft Power Platform', 'Microsoft SharePoint', 'Snowflake', 'Microsoft Office'] +#ticket_field = "service" +classes = [ 'HANA -> Technical Issues', 'HANA -> Billing & Payment', 'HANA -> Product Inquiries', 'HANA -> Account Management', 'HANA -> Policy Questions', +'Business One -> Technical Issues', 'Business One -> Billing & Payment', 'Business One -> Product Inquiries', 'Business One -> Account Management', 'Business One -> Policy Questions', 'Jira -> Technical Issues', 'Jira -> Billing & Payment', 'Jira -> Product Inquiries', 'Jira -> Account Management', 'Jira -> Policy Questions', 'Sourcetree -> Technical Issues', 'Sourcetree -> Billing & Payment', 'Sourcetree -> Product Inquiries', 'Sourcetree -> Account Management', 'Sourcetree -> Policy Questions', 'Opsgenie -> Technical Issues', 'Opsgenie -> Billing & Payment', 'Opsgenie -> Product Inquiries', 'Opsgenie -> Account Management', 'Opsgenie -> Policy Questions', 'Trello -> Technical Issues', 'Trello -> Billing & Payment', 'Trello -> Product Inquiries', 'Trello -> Account Management', 'Trello -> Policy Questions', 'Illustrator -> Technical Issues', 'Illustrator -> Billing & Payment', 'Illustrator -> Product Inquiries', 'Illustrator -> Account Management', 'Illustrator -> Policy Questions', 'Photoshop -> Technical Issues', 'Photoshop -> Billing & Payment', 'Photoshop -> Product Inquiries', 'Photoshop -> Account Management', 'Photoshop -> Policy Questions', 'InDesign -> Technical Issues', 'InDesign -> Billing & Payment', 'InDesign -> Product Inquiries', 'InDesign -> Account Management', 'InDesign -> Policy Questions', 'Premiere -> Technical Issues', 'Premiere -> Billing & Payment', 'Premiere -> Product Inquiries', 'Premiere -> Account Management', 'Premiere -> Policy Questions', 'Apex -> Technical Issues', 'Apex -> Billing & Payment', 'Apex -> Product Inquiries', 'Apex -> Account Management', 'Apex -> Policy Questions', 'Trailhead -> Technical Issues', 'Trailhead -> Billing & Payment', 'Trailhead -> Product Inquiries', 'Trailhead -> Account Management', 'Trailhead -> Policy Questions', 'Visualforce -> Technical Issues', 'Visualforce -> Billing & Payment', 'Visualforce -> Product Inquiries', 'Visualforce -> Account Management', 'Visualforce -> Policy Questions', 'Sales Cloud -> Technical Issues', 'Sales Cloud -> Billing & Payment', 'Sales Cloud -> Product Inquiries', 'Sales Cloud -> Account Management', 'Sales Cloud -> Policy Questions', 'Tableau -> Technical Issues', 'Tableau -> Billing & Payment', 'Tableau -> Product Inquiries', 'Tableau -> Account Management', 'Tableau -> Policy Questions', 'Microsoft PowerBI -> Technical Issues', 'Microsoft PowerBI -> Billing & Payment', 'Microsoft PowerBI -> Product Inquiries', 'Microsoft PowerBI -> Account Management', 'Microsoft PowerBI -> Policy Questions', 'Datasource -> Technical Issues', 'Datasource -> Billing & Payment', 'Datasource -> Product Inquiries', 'Datasource -> Account Management', 'Datasource -> Policy Questions', 'DataFlow -> Technical Issues', 'DataFlow -> Billing & Payment', 'DataFlow -> Product Inquiries', 'DataFlow -> Account Management', 'DataFlow -> Policy Questions', 'Microsoft Power Apps -> Technical Issues', 'Microsoft Power App -> Billing & Payment', 'Microsoft Power App -> Product Inquiries', 'Microsoft Power App -> Account Management', 'Microsoft Power App -> Policy Questions', 'Microsoft Power BI -> Technical Issues', 'Microsoft Power BI -> Billing & Payment', 'Microsoft Power BI -> Product Inquiries', 'Microsoft Power BI -> Account Management', 'Microsoft Power BI -> Policy Questions', 'Microsoft Power Pages Automate -> Technical Issues', 'Microsoft Power Pages Automate -> Billing & Payment', 'Microsoft Power Pages Automate -> Product Inquiries', 'Microsoft Power Pages Automate -> Account Management', 'Microsoft Power Pages Automate -> Policy Questions', 'Microsoft SharePoint -> Technical Issues', 'Microsoft SharePoint -> Billing & Payment', 'Microsoft SharePoint -> Product Inquiries', 'Microsoft SharePoint -> Account Management', 'Microsoft SharePoint -> Policy Questions', 'SharePoint -> Technical Issues', 'SharePoint -> Billing & Payment', 'SharePoint -> Product Inquiries', 'SharePoint -> Account Management', 'SharePoint -> Policy Questions', 'SharePoint List -> Technical Issues', 'SharePoint List -> Billing & Payment', 'SharePoint List -> Product Inquiries', 'SharePoint List -> Account Management', 'SharePoint List -> Policy Questions', 'SharePoint Document Library -> Technical Issues', 'SharePoint Document Library -> Billing & Payment', 'SharePoint Document Library -> Product Inquiries', 'SharePoint Document Library -> Account Management', 'SharePoint Document Library -> Policy Questions', 'Snowflake -> Technical Issues', 'Snowflake -> Billing & Payment', 'Snowflake -> Product Inquiries', 'Snowflake -> Account Management', 'Snowflake -> Policy Question', 'SnowSQL -> Technical Issues', 'SnowSQL -> Billing & Payment', 'SnowSQL -> Product Inquiries', 'SnowSQL -> Account Management', 'SnowSQL -> Policy Question', 'Microsoft Office -> Technical Issues', 'Microsoft Office -> Billing & Payment', 'Microsoft Office -> Product Inquiries', 'Microsoft Office -> Account Management', 'Microsoft Office -> Policy Questions', 'Microsoft Word -> Technical Issues', 'Microsoft Word -> Billing & Payment', 'Microsoft Word -> Product Inquiries', 'Microsoft Word -> Account Management', 'Microsoft Word -> Policy Questions', 'Microsoft Excel -> Technical Issues', 'Microsoft Excel -> Billing & Payment', 'Microsoft Excel -> Product Inquiries', 'Microsoft Excel -> Account Management', 'Microsoft Excel -> Policy Questions', 'Microsoft PowerPoint -> Technical Issues', 'Microsoft PowerPoint -> Billing & Payment', 'Microsoft PowerPoint -> Product Inquiries', 'Microsoft PowerPoint -> Account Management', 'Microsoft PowerPoint -> Policy Questions' +] +ticket_field = "category" + model_name = "roberta-base" -model = RobertaForSequenceClassification.from_pretrained(model_name) +model = RobertaForSequenceClassification.from_pretrained(model_name, num_labels=len(classes)) tokenizer = RobertaTokenizer.from_pretrained(model_name) root_directory = os.path.dirname(__file__) test_dir = os.path.join(root_directory, "..", "test_data") data_paths = [ - os.path.join(test_dir, "test_data_garvin", "data_translated.json"), - os.path.join(test_dir, "test_data_irild", "data_translated.json"), - os.path.join(test_dir, "test_data_fabian", "data_translated.json"), - os.path.join(test_dir, "test_data_sajjad", "data_translated.json"), - os.path.join(test_dir, "test_data_marco", "data_translated.json"), - os.path.join(test_dir, "test_data_tino", "data_translated.json"), + # os.path.join(test_dir, "test_data_garvin", "data_translated.json"), + # os.path.join(test_dir, "test_data_irild", "data_translated.json"), + # os.path.join(test_dir, "test_data_fabian", "data_translated.json"), + # os.path.join(test_dir, "test_data_sajjad", "data_translated.json"), + # os.path.join(test_dir, "test_data_marco", "data_translated.json"), + # os.path.join(test_dir, "test_data_tino", "data_translated.json"), os.path.join(test_dir, "test_data_with_gpt", "data_1.json"), - os.path.join(test_dir, "test_data_with_gpt", "data_2.json"), - os.path.join(test_dir, "test_data_with_gpt", "test_data.json"), + #os.path.join(test_dir, "test_data_with_gpt", "data_2.json"), + #os.path.join(test_dir, "test_data_with_gpt", "data_3.json"), + #os.path.join(test_dir, "test_data_with_gpt", "data_4.json"), + #os.path.join(test_dir, "test_data_with_gpt", "data_5.json"), + #os.path.join(test_dir, "test_data_with_gpt", "test_data.json") ] # Create datasets -custom_dataset = CustomDataset(tokenizer, data_paths, "requestType") +custom_dataset = CustomDataset(tokenizer, data_paths, ticket_field, classes) train_set, val_set = torch.utils.data.random_split( custom_dataset, [ @@ -95,11 +107,14 @@ def parse_args(): device = "cuda" if not args.no_cuda and torch.cuda.is_available() else "cpu" model.to(device) +# Lists for learning curves +train_losses = [] +valid_losses = [] + # Training loop for epoch in range(args.epochs): model.train() - total_loss = 0 - start_time = time.time() + total_train_loss = 0 for batch in tqdm( train_loader, desc=f"Epoch {epoch + 1}/{args.epochs}", unit="batch" @@ -113,20 +128,20 @@ def parse_args(): outputs = model( input_ids=input_ids, attention_mask=attention_mask, labels=labels ) - loss = outputs.loss - total_loss += loss.item() + total_train_loss += loss.item() loss.backward() optimizer.step() scheduler.step() - average_loss = total_loss / len(train_loader) - epoch_time = time.time() - start_time + average_train_loss = total_train_loss / len(train_loader) + train_losses.append(average_train_loss) - # Validation with Confusion Matrix model.eval() + total_valid_loss = 0 val_true_labels = [] val_predictions = [] + val_confidence_scores = [] with torch.no_grad(): for batch in valid_loader: @@ -141,26 +156,56 @@ def parse_args(): val_true_labels.extend(labels.cpu().numpy()) val_predictions.extend(preds.cpu().numpy()) - conf_matrix = confusion_matrix(val_true_labels, val_predictions) - ax = sns.heatmap(conf_matrix, annot=True, cmap="Blues") + loss = torch.nn.functional.cross_entropy(logits, labels) + total_valid_loss += loss.item() - ax.set_title("Confusion Matrix\n") - ax.set_xlabel("\nPredicted Values") - ax.set_ylabel("Actual Values ") + # Calculate confidence scores + softmax_scores = F.softmax(logits, dim=1) + max_confidence_scores = torch.max(softmax_scores, dim=1) + val_confidence_scores.extend(max_confidence_scores.values.cpu().numpy()) - ax.xaxis.set_ticklabels(["False", "True"]) - ax.yaxis.set_ticklabels(["False", "True"]) + average_valid_loss = total_valid_loss / len(valid_loader) + valid_losses.append(average_valid_loss) - # Save the confusion matrix plot as a PNG file - plt.savefig(f"confusion_matrix_epoch_{epoch + 1}.png", bbox_inches="tight") + # Create and store confusion matrix + conf_matrix = confusion_matrix(val_true_labels, val_predictions) + plt.figure(figsize=(12, 8)) + ax = sns.heatmap(conf_matrix, annot=True, cmap='Blues') + ax.set_title(f'Confusion Matrix for {ticket_field} \n'); + ax.set_xlabel('\nPredicted Values') + ax.set_ylabel('Actual Values '); + ax.set_xticklabels(classes, rotation=45, ha="right") + ax.set_yticklabels(classes, rotation=45, ha="right") + plt.savefig(f'confusion_matrix_epoch_{epoch + 1}'+ ticket_field +'.png', bbox_inches='tight') plt.close() - print( - f"Epoch: {((epoch + 1) / args.epochs) * 100:.0f}% | {epoch + 1}/{args.epochs} [{epoch_time:.2f}s/epoch]" - ) - print(f"Train Loss: {average_loss}") +# Learning curves for training and validation loss +plt.figure(figsize=(10, 6)) +plt.plot(train_losses, label='Training Loss') +plt.plot(valid_losses, label='Validation Loss') +plt.title(f'Loss of training and validation for {ticket_field} over the epochs') +plt.xlabel('Epochs') +plt.ylabel('Loss') +plt.legend() + +# Save learning curve as an image +plt.savefig(f'training_validation_loss_curve_{ticket_field}.png') +plt.close() + +# Visualization of Confidence Scores +plt.figure(figsize=(10, 6)) +plt.hist(val_confidence_scores, bins=50, alpha=0.7, color='blue') +plt.title(f'Confidence Score Distribution for {ticket_field}') +plt.xlabel('Confidence Score') +plt.ylabel('Number of Predictions') +plt.grid(True) + +# Save Confidence Scores visualization as image +confidence_score_filename = f'confidence_scores_distribution_{ticket_field}.png' +plt.savefig(confidence_score_filename) +plt.close() # Save the fine-tuned model -if args.save_model: - model.save_pretrained("fine_tuned_roberta_model") - tokenizer.save_pretrained("fine_tuned_roberta_model") +# if args.save_model: +model.save_pretrained("fine_tuned_roberta_model_" + ticket_field + "28k_data") +tokenizer.save_pretrained("fine_tuned_roberta_model_" + ticket_field + "28k_data") \ No newline at end of file diff --git a/Backend/app/model/train/text_classification/use_fine_tuned_model.py b/Backend/app/model/train/text_classification/use_fine_tuned_model.py index 52d5131e..09e43041 100644 --- a/Backend/app/model/train/text_classification/use_fine_tuned_model.py +++ b/Backend/app/model/train/text_classification/use_fine_tuned_model.py @@ -1,13 +1,11 @@ import torch from transformers import RobertaForSequenceClassification, RobertaTokenizer - def load_model(model_path): model = RobertaForSequenceClassification.from_pretrained(model_path) tokenizer = RobertaTokenizer.from_pretrained(model_path) return model, tokenizer - def prepare_data(tokenizer, text, max_length=512): inputs = tokenizer( text, @@ -19,7 +17,6 @@ def prepare_data(tokenizer, text, max_length=512): ) return inputs - def predict(model, tokenizer, text, device): model.to(device) model.eval() @@ -32,17 +29,21 @@ def predict(model, tokenizer, text, device): outputs = model(input_ids=input_ids, attention_mask=attention_mask) logits = outputs.logits + print(logits) + preds = torch.argmax(logits, dim=1) return preds - +# Pfad zum gespeicherten Modell model_path = "./fine_tuned_roberta_model_request_type" model, tokenizer = load_model(model_path) - +# Gerät festlegen (CUDA, wenn verfügbar, sonst CPU) device = "cuda" if torch.cuda.is_available() else "cpu" +# Text für die Vorhersage text = "Tableau dashboard is not reflecting real-time data. The connection to the database seems intact, but updates are delayed. This is critical for our daily operations." +# Vorhersage predictions = predict(model, tokenizer, text, device) print("Predictions:", predictions) From 8707e2f715cba9c2f288d11575172cb991c74e22 Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Sun, 21 Jan 2024 13:36:22 +0100 Subject: [PATCH 07/16] integrated AIs for service, category and request-type fields MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl Signed-off-by: Koffi Tino Gnagniko --- Backend/app/api/dto/ticket.py | 3 +- .../ai_ticket_service/ai_ticket_service.py | 280 ++++++++++++++++-- .../text_classification/custom_data_set.py | 6 +- .../model/train/text_classification/train.py | 218 ++++++++++++-- .../use_fine_tuned_model.py | 4 + .../app/repository/entity/ticket_entity.py | 3 +- Backend/test/model/ai_ticket_service_test.py | 6 +- 7 files changed, 460 insertions(+), 60 deletions(-) diff --git a/Backend/app/api/dto/ticket.py b/Backend/app/api/dto/ticket.py index e4997b17..f7a0073c 100644 --- a/Backend/app/api/dto/ticket.py +++ b/Backend/app/api/dto/ticket.py @@ -8,11 +8,12 @@ class Ticket(BaseModel): id: str = "" title: str - location: str + service: str category: str keywords: list customerPriority: CustomerPrio affectedPerson: str description: str priority: Prio + requestType: str attachmentNames: list[str] = [] diff --git a/Backend/app/model/ai_ticket_service/ai_ticket_service.py b/Backend/app/model/ai_ticket_service/ai_ticket_service.py index 636f2928..300ad5a1 100644 --- a/Backend/app/model/ai_ticket_service/ai_ticket_service.py +++ b/Backend/app/model/ai_ticket_service/ai_ticket_service.py @@ -2,33 +2,231 @@ from app.util.logger import logger from app.enum.customer_prio import CustomerPrio from app.enum.prio import Prio +from sklearn.preprocessing import LabelEncoder class AITicketService: def __init__(self): - self.title_generation_pipe = pipeline( + self.label_encoder = LabelEncoder() + + # Pipes + self.title_generator_pipe = pipeline( "text2text-generation", model="czearing/article-title-generator" ) - self.affected_person_generation_pipe = pipeline( + self.affected_person_generator_pipe = pipeline( "token-classification", model="dslim/bert-base-NER" ) - self.keywords_generation_pipe = pipeline( + self.keywords_generator_pipe = pipeline( "token-classification", model="ml6team/keyphrase-extraction-kbir-inspec" ) - self.request_type_generation_pipe = pipeline( + self.request_type_generator_pipe = pipeline( "text-classification", model="TalkTix/roberta-base-request-type" ) + self.category_generator_pipe = pipeline( + "text-classification", + model="TalkTix/roberta-base-category-type-generator-28k", + ) + + self.service_generator_pipe = pipeline( + "text-classification", + model="TalkTix/roberta-base-service-type-generator-28k", + ) + + # Possible Field values + self.request_type_values = ["Incident", " 'Service Request"] + self.service_values = [ + "SAP ERP", + "Atlassian", + "Adobe", + "Salesforce", + "Reporting", + "Microsoft Power Platform", + "Microsoft SharePoint", + "Snowflake", + "Microsoft Office", + ] + self.category_values = [ + "HANA -> Technical Issues", + "HANA -> Billing & Payment", + "HANA -> Product Inquiries", + "HANA -> Account Management", + "HANA -> Policy Questions", + "Business One -> Technical Issues", + "Business One -> Billing & Payment", + "Business One -> Product Inquiries", + "Business One -> Account Management", + "Business One -> Policy Questions", + "Jira -> Technical Issues", + "Jira -> Billing & Payment", + "Jira -> Product Inquiries", + "Jira -> Account Management", + "Jira -> Policy Questions", + "Sourcetree -> Technical Issues", + "Sourcetree -> Billing & Payment", + "Sourcetree -> Product Inquiries", + "Sourcetree -> Account Management", + "Sourcetree -> Policy Questions", + "Opsgenie -> Technical Issues", + "Opsgenie -> Billing & Payment", + "Opsgenie -> Product Inquiries", + "Opsgenie -> Account Management", + "Opsgenie -> Policy Questions", + "Trello -> Technical Issues", + "Trello -> Billing & Payment", + "Trello -> Product Inquiries", + "Trello -> Account Management", + "Trello -> Policy Questions", + "Illustrator -> Technical Issues", + "Illustrator -> Billing & Payment", + "Illustrator -> Product Inquiries", + "Illustrator -> Account Management", + "Illustrator -> Policy Questions", + "Photoshop -> Technical Issues", + "Photoshop -> Billing & Payment", + "Photoshop -> Product Inquiries", + "Photoshop -> Account Management", + "Photoshop -> Policy Questions", + "InDesign -> Technical Issues", + "InDesign -> Billing & Payment", + "InDesign -> Product Inquiries", + "InDesign -> Account Management", + "InDesign -> Policy Questions", + "Premiere -> Technical Issues", + "Premiere -> Billing & Payment", + "Premiere -> Product Inquiries", + "Premiere -> Account Management", + "Premiere -> Policy Questions", + "Apex -> Technical Issues", + "Apex -> Billing & Payment", + "Apex -> Product Inquiries", + "Apex -> Account Management", + "Apex -> Policy Questions", + "Trailhead -> Technical Issues", + "Trailhead -> Billing & Payment", + "Trailhead -> Product Inquiries", + "Trailhead -> Account Management", + "Trailhead -> Policy Questions", + "Visualforce -> Technical Issues", + "Visualforce -> Billing & Payment", + "Visualforce -> Product Inquiries", + "Visualforce -> Account Management", + "Visualforce -> Policy Questions", + "Sales Cloud -> Technical Issues", + "Sales Cloud -> Billing & Payment", + "Sales Cloud -> Product Inquiries", + "Sales Cloud -> Account Management", + "Sales Cloud -> Policy Questions", + "Tableau -> Technical Issues", + "Tableau -> Billing & Payment", + "Tableau -> Product Inquiries", + "Tableau -> Account Management", + "Tableau -> Policy Questions", + "Microsoft PowerBI -> Technical Issues", + "Microsoft PowerBI -> Billing & Payment", + "Microsoft PowerBI -> Product Inquiries", + "Microsoft PowerBI -> Account Management", + "Microsoft PowerBI -> Policy Questions", + "Datasource -> Technical Issues", + "Datasource -> Billing & Payment", + "Datasource -> Product Inquiries", + "Datasource -> Account Management", + "Datasource -> Policy Questions", + "DataFlow -> Technical Issues", + "DataFlow -> Billing & Payment", + "DataFlow -> Product Inquiries", + "DataFlow -> Account Management", + "DataFlow -> Policy Questions", + "Microsoft Power Apps -> Technical Issues", + "Microsoft Power App -> Billing & Payment", + "Microsoft Power App -> Product Inquiries", + "Microsoft Power App -> Account Management", + "Microsoft Power App -> Policy Questions", + "Microsoft Power BI -> Technical Issues", + "Microsoft Power BI -> Billing & Payment", + "Microsoft Power BI -> Product Inquiries", + "Microsoft Power BI -> Account Management", + "Microsoft Power BI -> Policy Questions", + "Microsoft Power Pages Automate -> Technical Issues", + "Microsoft Power Pages Automate -> Billing & Payment", + "Microsoft Power Pages Automate -> Product Inquiries", + "Microsoft Power Pages Automate -> Account Management", + "Microsoft Power Pages Automate -> Policy Questions", + "Microsoft SharePoint -> Technical Issues", + "Microsoft SharePoint -> Billing & Payment", + "Microsoft SharePoint -> Product Inquiries", + "Microsoft SharePoint -> Account Management", + "Microsoft SharePoint -> Policy Questions", + "SharePoint -> Technical Issues", + "SharePoint -> Billing & Payment", + "SharePoint -> Product Inquiries", + "SharePoint -> Account Management", + "SharePoint -> Policy Questions", + "SharePoint List -> Technical Issues", + "SharePoint List -> Billing & Payment", + "SharePoint List -> Product Inquiries", + "SharePoint List -> Account Management", + "SharePoint List -> Policy Questions", + "SharePoint Document Library -> Technical Issues", + "SharePoint Document Library -> Billing & Payment", + "SharePoint Document Library -> Product Inquiries", + "SharePoint Document Library -> Account Management", + "SharePoint Document Library -> Policy Questions", + "Snowflake -> Technical Issues", + "Snowflake -> Billing & Payment", + "Snowflake -> Product Inquiries", + "Snowflake -> Account Management", + "Snowflake -> Policy Question", + "SnowSQL -> Technical Issues", + "SnowSQL -> Billing & Payment", + "SnowSQL -> Product Inquiries", + "SnowSQL -> Account Management", + "SnowSQL -> Policy Question", + "Microsoft Office -> Technical Issues", + "Microsoft Office -> Billing & Payment", + "Microsoft Office -> Product Inquiries", + "Microsoft Office -> Account Management", + "Microsoft Office -> Policy Questions", + "Microsoft Word -> Technical Issues", + "Microsoft Word -> Billing & Payment", + "Microsoft Word -> Product Inquiries", + "Microsoft Word -> Account Management", + "Microsoft Word -> Policy Questions", + "Microsoft Excel -> Technical Issues", + "Microsoft Excel -> Billing & Payment", + "Microsoft Excel -> Product Inquiries", + "Microsoft Excel -> Account Management", + "Microsoft Excel -> Policy Questions", + "Microsoft PowerPoint -> Technical Issues", + "Microsoft PowerPoint -> Billing & Payment", + "Microsoft PowerPoint -> Product Inquiries", + "Microsoft PowerPoint -> Account Management", + "Microsoft PowerPoint -> Policy Questions", + ] + def create_ticket(self, input_text) -> dict: + # generate prediction for each field title = self.generate_title(input_text) keywords = self.generate_keywords(input_text) affected_person = self.generate_affected_person(input_text) - request_type = self.generate_request_type(input_text) + request_type = self.generate_prediction( + input_text, + self.request_type_generator_pipe, + "requestType", + self.request_type_values, + ) + category = self.generate_prediction( + input_text, self.category_generator_pipe, "category", self.category_values + ) + service = self.generate_prediction( + input_text, self.service_generator_pipe, "service", self.service_values + ) + # Create Ticket ticket_dict = { "title": title, - "location": "", - "category": "", + "service": service, + "category": category, "keywords": keywords, "customerPriority": CustomerPrio.can_work, "affectedPerson": affected_person, @@ -41,11 +239,11 @@ def create_ticket(self, input_text) -> dict: return ticket_dict def generate_title(self, input_text) -> str: - generated_title = self.title_generation_pipe(input_text)[0]["generated_text"] + generated_title = self.title_generator_pipe(input_text)[0]["generated_text"] return generated_title def generate_affected_person(self, input_text) -> str: - generated_output = self.affected_person_generation_pipe(input_text) + generated_output = self.affected_person_generator_pipe(input_text) if len(generated_output) > 0: persons = [ @@ -55,13 +253,20 @@ def generate_affected_person(self, input_text) -> str: ] generated_affected_person = " ".join(persons) + logger.info( + "[AI] Prediction successfully generated. {}: {}".format( + "affectedPerson", generated_affected_person + ) + ) return generated_affected_person else: - logger.error("AI: Could not generate Affected Person") + logger.info( + "[AI] Could not generate prediction for Affected Person. Generated output is empty" + ) return "" def generate_keywords(self, input_text) -> list: - generated_output = self.keywords_generation_pipe(input_text) + generated_output = self.keywords_generator_pipe(input_text) if len(generated_output) > 0: keywords = [ @@ -69,26 +274,55 @@ def generate_keywords(self, input_text) -> list: for entity in generated_output if "KEY" in entity["entity"] ] + + logger.info( + "[AI] Prediction successfully generated. {}: {}".format( + "keywords", keywords + ) + ) return keywords else: - logger.info("AI: Could not generate keywords") + logger.info("[AI] Could not generate keywords. Generated output is empty.") return [] - def generate_request_type(self, input_text) -> str: - generated_output = self.request_type_generation_pipe(input_text) - request_type_values = ["Incident", "Service Request"] - print(generated_output) + def generate_prediction(self, input_text, pipe, field, field_values) -> str: + generated_output = pipe(input_text) + prediction = "" + + print("=======================================================") + print("generated_output: " + field + " ", generated_output) + print("=======================================================") if len(generated_output) > 0: - prediction_score = max(generated_output['score']) - if prediction_score < 0: - logger.info("AI: Request type prediction is to worse") - return "" + prediction_score = generated_output[0]["score"] + if prediction_score < 0.5: + logger.info( + "[AI] Could not generate prediction for {}. Prediction score are to worse.".format( + field + ) + ) + return prediction + else: + prediction = self.map_label_to_class( + generated_output[0]["label"], field_values + ) + logger.info( + "[AI] Prediction successfully generated. {}: {}".format( + field, prediction + ) + ) + return prediction else: - logger.info("AI: Could not generate request type") - return "" - + logger.info( + "[AI] Could not generate prediction for {}. Generated output is empty".format( + field + ) + ) + return prediction + def map_label_to_class(self, label, classes) -> str: + index = int(label[-1]) + return classes[index] # def remove_email_signature(self, email_content) -> str: # parsed_email = EmailReplyParser.parse_reply(email_content) diff --git a/Backend/app/model/train/text_classification/custom_data_set.py b/Backend/app/model/train/text_classification/custom_data_set.py index 835faad9..ba556b0b 100644 --- a/Backend/app/model/train/text_classification/custom_data_set.py +++ b/Backend/app/model/train/text_classification/custom_data_set.py @@ -21,7 +21,7 @@ def __init__(self, tokenizer, data_paths, output_field, classes, max_length=512) def load_json(self): for data_path in self.data_paths: - with open(data_path, 'r') as file: + with open(data_path, "r") as file: data = json.load(file) for item in data: if item["ticket"][self.output_field] in self.label_encoder.classes_: @@ -36,8 +36,8 @@ def __getitem__(self, idx): item = self.data_set[idx] # Check whether 'text' key is present in the item - if 'text' in item: - text_description = "\n".join(item['text']) + if "text" in item: + text_description = "\n".join(item["text"]) else: text_description = "" diff --git a/Backend/app/model/train/text_classification/train.py b/Backend/app/model/train/text_classification/train.py index de9ca74b..ee672f38 100644 --- a/Backend/app/model/train/text_classification/train.py +++ b/Backend/app/model/train/text_classification/train.py @@ -14,6 +14,7 @@ from custom_data_set import CustomDataset + def parse_args(): parser = argparse.ArgumentParser( description="Train a neural network to diffuse images" @@ -52,17 +53,173 @@ def parse_args(): args = parse_args() -#classes = ["Incident", "Service Request"] -#ticket_field = "requestType" -#classes = ['SAP ERP', 'Atlassian', 'Adobe', 'Salesforce', 'Reporting', 'Microsoft Power Platform', 'Microsoft SharePoint', 'Snowflake', 'Microsoft Office'] -#ticket_field = "service" -classes = [ 'HANA -> Technical Issues', 'HANA -> Billing & Payment', 'HANA -> Product Inquiries', 'HANA -> Account Management', 'HANA -> Policy Questions', -'Business One -> Technical Issues', 'Business One -> Billing & Payment', 'Business One -> Product Inquiries', 'Business One -> Account Management', 'Business One -> Policy Questions', 'Jira -> Technical Issues', 'Jira -> Billing & Payment', 'Jira -> Product Inquiries', 'Jira -> Account Management', 'Jira -> Policy Questions', 'Sourcetree -> Technical Issues', 'Sourcetree -> Billing & Payment', 'Sourcetree -> Product Inquiries', 'Sourcetree -> Account Management', 'Sourcetree -> Policy Questions', 'Opsgenie -> Technical Issues', 'Opsgenie -> Billing & Payment', 'Opsgenie -> Product Inquiries', 'Opsgenie -> Account Management', 'Opsgenie -> Policy Questions', 'Trello -> Technical Issues', 'Trello -> Billing & Payment', 'Trello -> Product Inquiries', 'Trello -> Account Management', 'Trello -> Policy Questions', 'Illustrator -> Technical Issues', 'Illustrator -> Billing & Payment', 'Illustrator -> Product Inquiries', 'Illustrator -> Account Management', 'Illustrator -> Policy Questions', 'Photoshop -> Technical Issues', 'Photoshop -> Billing & Payment', 'Photoshop -> Product Inquiries', 'Photoshop -> Account Management', 'Photoshop -> Policy Questions', 'InDesign -> Technical Issues', 'InDesign -> Billing & Payment', 'InDesign -> Product Inquiries', 'InDesign -> Account Management', 'InDesign -> Policy Questions', 'Premiere -> Technical Issues', 'Premiere -> Billing & Payment', 'Premiere -> Product Inquiries', 'Premiere -> Account Management', 'Premiere -> Policy Questions', 'Apex -> Technical Issues', 'Apex -> Billing & Payment', 'Apex -> Product Inquiries', 'Apex -> Account Management', 'Apex -> Policy Questions', 'Trailhead -> Technical Issues', 'Trailhead -> Billing & Payment', 'Trailhead -> Product Inquiries', 'Trailhead -> Account Management', 'Trailhead -> Policy Questions', 'Visualforce -> Technical Issues', 'Visualforce -> Billing & Payment', 'Visualforce -> Product Inquiries', 'Visualforce -> Account Management', 'Visualforce -> Policy Questions', 'Sales Cloud -> Technical Issues', 'Sales Cloud -> Billing & Payment', 'Sales Cloud -> Product Inquiries', 'Sales Cloud -> Account Management', 'Sales Cloud -> Policy Questions', 'Tableau -> Technical Issues', 'Tableau -> Billing & Payment', 'Tableau -> Product Inquiries', 'Tableau -> Account Management', 'Tableau -> Policy Questions', 'Microsoft PowerBI -> Technical Issues', 'Microsoft PowerBI -> Billing & Payment', 'Microsoft PowerBI -> Product Inquiries', 'Microsoft PowerBI -> Account Management', 'Microsoft PowerBI -> Policy Questions', 'Datasource -> Technical Issues', 'Datasource -> Billing & Payment', 'Datasource -> Product Inquiries', 'Datasource -> Account Management', 'Datasource -> Policy Questions', 'DataFlow -> Technical Issues', 'DataFlow -> Billing & Payment', 'DataFlow -> Product Inquiries', 'DataFlow -> Account Management', 'DataFlow -> Policy Questions', 'Microsoft Power Apps -> Technical Issues', 'Microsoft Power App -> Billing & Payment', 'Microsoft Power App -> Product Inquiries', 'Microsoft Power App -> Account Management', 'Microsoft Power App -> Policy Questions', 'Microsoft Power BI -> Technical Issues', 'Microsoft Power BI -> Billing & Payment', 'Microsoft Power BI -> Product Inquiries', 'Microsoft Power BI -> Account Management', 'Microsoft Power BI -> Policy Questions', 'Microsoft Power Pages Automate -> Technical Issues', 'Microsoft Power Pages Automate -> Billing & Payment', 'Microsoft Power Pages Automate -> Product Inquiries', 'Microsoft Power Pages Automate -> Account Management', 'Microsoft Power Pages Automate -> Policy Questions', 'Microsoft SharePoint -> Technical Issues', 'Microsoft SharePoint -> Billing & Payment', 'Microsoft SharePoint -> Product Inquiries', 'Microsoft SharePoint -> Account Management', 'Microsoft SharePoint -> Policy Questions', 'SharePoint -> Technical Issues', 'SharePoint -> Billing & Payment', 'SharePoint -> Product Inquiries', 'SharePoint -> Account Management', 'SharePoint -> Policy Questions', 'SharePoint List -> Technical Issues', 'SharePoint List -> Billing & Payment', 'SharePoint List -> Product Inquiries', 'SharePoint List -> Account Management', 'SharePoint List -> Policy Questions', 'SharePoint Document Library -> Technical Issues', 'SharePoint Document Library -> Billing & Payment', 'SharePoint Document Library -> Product Inquiries', 'SharePoint Document Library -> Account Management', 'SharePoint Document Library -> Policy Questions', 'Snowflake -> Technical Issues', 'Snowflake -> Billing & Payment', 'Snowflake -> Product Inquiries', 'Snowflake -> Account Management', 'Snowflake -> Policy Question', 'SnowSQL -> Technical Issues', 'SnowSQL -> Billing & Payment', 'SnowSQL -> Product Inquiries', 'SnowSQL -> Account Management', 'SnowSQL -> Policy Question', 'Microsoft Office -> Technical Issues', 'Microsoft Office -> Billing & Payment', 'Microsoft Office -> Product Inquiries', 'Microsoft Office -> Account Management', 'Microsoft Office -> Policy Questions', 'Microsoft Word -> Technical Issues', 'Microsoft Word -> Billing & Payment', 'Microsoft Word -> Product Inquiries', 'Microsoft Word -> Account Management', 'Microsoft Word -> Policy Questions', 'Microsoft Excel -> Technical Issues', 'Microsoft Excel -> Billing & Payment', 'Microsoft Excel -> Product Inquiries', 'Microsoft Excel -> Account Management', 'Microsoft Excel -> Policy Questions', 'Microsoft PowerPoint -> Technical Issues', 'Microsoft PowerPoint -> Billing & Payment', 'Microsoft PowerPoint -> Product Inquiries', 'Microsoft PowerPoint -> Account Management', 'Microsoft PowerPoint -> Policy Questions' +# classes = ["Incident", "Service Request"] +# ticket_field = "requestType" +# classes = ['SAP ERP', 'Atlassian', 'Adobe', 'Salesforce', 'Reporting', 'Microsoft Power Platform', 'Microsoft SharePoint', 'Snowflake', 'Microsoft Office'] +# ticket_field = "service" +classes = [ + "HANA -> Technical Issues", + "HANA -> Billing & Payment", + "HANA -> Product Inquiries", + "HANA -> Account Management", + "HANA -> Policy Questions", + "Business One -> Technical Issues", + "Business One -> Billing & Payment", + "Business One -> Product Inquiries", + "Business One -> Account Management", + "Business One -> Policy Questions", + "Jira -> Technical Issues", + "Jira -> Billing & Payment", + "Jira -> Product Inquiries", + "Jira -> Account Management", + "Jira -> Policy Questions", + "Sourcetree -> Technical Issues", + "Sourcetree -> Billing & Payment", + "Sourcetree -> Product Inquiries", + "Sourcetree -> Account Management", + "Sourcetree -> Policy Questions", + "Opsgenie -> Technical Issues", + "Opsgenie -> Billing & Payment", + "Opsgenie -> Product Inquiries", + "Opsgenie -> Account Management", + "Opsgenie -> Policy Questions", + "Trello -> Technical Issues", + "Trello -> Billing & Payment", + "Trello -> Product Inquiries", + "Trello -> Account Management", + "Trello -> Policy Questions", + "Illustrator -> Technical Issues", + "Illustrator -> Billing & Payment", + "Illustrator -> Product Inquiries", + "Illustrator -> Account Management", + "Illustrator -> Policy Questions", + "Photoshop -> Technical Issues", + "Photoshop -> Billing & Payment", + "Photoshop -> Product Inquiries", + "Photoshop -> Account Management", + "Photoshop -> Policy Questions", + "InDesign -> Technical Issues", + "InDesign -> Billing & Payment", + "InDesign -> Product Inquiries", + "InDesign -> Account Management", + "InDesign -> Policy Questions", + "Premiere -> Technical Issues", + "Premiere -> Billing & Payment", + "Premiere -> Product Inquiries", + "Premiere -> Account Management", + "Premiere -> Policy Questions", + "Apex -> Technical Issues", + "Apex -> Billing & Payment", + "Apex -> Product Inquiries", + "Apex -> Account Management", + "Apex -> Policy Questions", + "Trailhead -> Technical Issues", + "Trailhead -> Billing & Payment", + "Trailhead -> Product Inquiries", + "Trailhead -> Account Management", + "Trailhead -> Policy Questions", + "Visualforce -> Technical Issues", + "Visualforce -> Billing & Payment", + "Visualforce -> Product Inquiries", + "Visualforce -> Account Management", + "Visualforce -> Policy Questions", + "Sales Cloud -> Technical Issues", + "Sales Cloud -> Billing & Payment", + "Sales Cloud -> Product Inquiries", + "Sales Cloud -> Account Management", + "Sales Cloud -> Policy Questions", + "Tableau -> Technical Issues", + "Tableau -> Billing & Payment", + "Tableau -> Product Inquiries", + "Tableau -> Account Management", + "Tableau -> Policy Questions", + "Microsoft PowerBI -> Technical Issues", + "Microsoft PowerBI -> Billing & Payment", + "Microsoft PowerBI -> Product Inquiries", + "Microsoft PowerBI -> Account Management", + "Microsoft PowerBI -> Policy Questions", + "Datasource -> Technical Issues", + "Datasource -> Billing & Payment", + "Datasource -> Product Inquiries", + "Datasource -> Account Management", + "Datasource -> Policy Questions", + "DataFlow -> Technical Issues", + "DataFlow -> Billing & Payment", + "DataFlow -> Product Inquiries", + "DataFlow -> Account Management", + "DataFlow -> Policy Questions", + "Microsoft Power Apps -> Technical Issues", + "Microsoft Power App -> Billing & Payment", + "Microsoft Power App -> Product Inquiries", + "Microsoft Power App -> Account Management", + "Microsoft Power App -> Policy Questions", + "Microsoft Power BI -> Technical Issues", + "Microsoft Power BI -> Billing & Payment", + "Microsoft Power BI -> Product Inquiries", + "Microsoft Power BI -> Account Management", + "Microsoft Power BI -> Policy Questions", + "Microsoft Power Pages Automate -> Technical Issues", + "Microsoft Power Pages Automate -> Billing & Payment", + "Microsoft Power Pages Automate -> Product Inquiries", + "Microsoft Power Pages Automate -> Account Management", + "Microsoft Power Pages Automate -> Policy Questions", + "Microsoft SharePoint -> Technical Issues", + "Microsoft SharePoint -> Billing & Payment", + "Microsoft SharePoint -> Product Inquiries", + "Microsoft SharePoint -> Account Management", + "Microsoft SharePoint -> Policy Questions", + "SharePoint -> Technical Issues", + "SharePoint -> Billing & Payment", + "SharePoint -> Product Inquiries", + "SharePoint -> Account Management", + "SharePoint -> Policy Questions", + "SharePoint List -> Technical Issues", + "SharePoint List -> Billing & Payment", + "SharePoint List -> Product Inquiries", + "SharePoint List -> Account Management", + "SharePoint List -> Policy Questions", + "SharePoint Document Library -> Technical Issues", + "SharePoint Document Library -> Billing & Payment", + "SharePoint Document Library -> Product Inquiries", + "SharePoint Document Library -> Account Management", + "SharePoint Document Library -> Policy Questions", + "Snowflake -> Technical Issues", + "Snowflake -> Billing & Payment", + "Snowflake -> Product Inquiries", + "Snowflake -> Account Management", + "Snowflake -> Policy Question", + "SnowSQL -> Technical Issues", + "SnowSQL -> Billing & Payment", + "SnowSQL -> Product Inquiries", + "SnowSQL -> Account Management", + "SnowSQL -> Policy Question", + "Microsoft Office -> Technical Issues", + "Microsoft Office -> Billing & Payment", + "Microsoft Office -> Product Inquiries", + "Microsoft Office -> Account Management", + "Microsoft Office -> Policy Questions", + "Microsoft Word -> Technical Issues", + "Microsoft Word -> Billing & Payment", + "Microsoft Word -> Product Inquiries", + "Microsoft Word -> Account Management", + "Microsoft Word -> Policy Questions", + "Microsoft Excel -> Technical Issues", + "Microsoft Excel -> Billing & Payment", + "Microsoft Excel -> Product Inquiries", + "Microsoft Excel -> Account Management", + "Microsoft Excel -> Policy Questions", + "Microsoft PowerPoint -> Technical Issues", + "Microsoft PowerPoint -> Billing & Payment", + "Microsoft PowerPoint -> Product Inquiries", + "Microsoft PowerPoint -> Account Management", + "Microsoft PowerPoint -> Policy Questions", ] ticket_field = "category" model_name = "roberta-base" -model = RobertaForSequenceClassification.from_pretrained(model_name, num_labels=len(classes)) +model = RobertaForSequenceClassification.from_pretrained( + model_name, num_labels=len(classes) +) tokenizer = RobertaTokenizer.from_pretrained(model_name) root_directory = os.path.dirname(__file__) @@ -76,11 +233,11 @@ def parse_args(): # os.path.join(test_dir, "test_data_marco", "data_translated.json"), # os.path.join(test_dir, "test_data_tino", "data_translated.json"), os.path.join(test_dir, "test_data_with_gpt", "data_1.json"), - #os.path.join(test_dir, "test_data_with_gpt", "data_2.json"), - #os.path.join(test_dir, "test_data_with_gpt", "data_3.json"), - #os.path.join(test_dir, "test_data_with_gpt", "data_4.json"), - #os.path.join(test_dir, "test_data_with_gpt", "data_5.json"), - #os.path.join(test_dir, "test_data_with_gpt", "test_data.json") + # os.path.join(test_dir, "test_data_with_gpt", "data_2.json"), + # os.path.join(test_dir, "test_data_with_gpt", "data_3.json"), + # os.path.join(test_dir, "test_data_with_gpt", "data_4.json"), + # os.path.join(test_dir, "test_data_with_gpt", "data_5.json"), + # os.path.join(test_dir, "test_data_with_gpt", "test_data.json") ] # Create datasets @@ -170,42 +327,45 @@ def parse_args(): # Create and store confusion matrix conf_matrix = confusion_matrix(val_true_labels, val_predictions) plt.figure(figsize=(12, 8)) - ax = sns.heatmap(conf_matrix, annot=True, cmap='Blues') - ax.set_title(f'Confusion Matrix for {ticket_field} \n'); - ax.set_xlabel('\nPredicted Values') - ax.set_ylabel('Actual Values '); + ax = sns.heatmap(conf_matrix, annot=True, cmap="Blues") + ax.set_title(f"Confusion Matrix for {ticket_field} \n") + ax.set_xlabel("\nPredicted Values") + ax.set_ylabel("Actual Values ") ax.set_xticklabels(classes, rotation=45, ha="right") ax.set_yticklabels(classes, rotation=45, ha="right") - plt.savefig(f'confusion_matrix_epoch_{epoch + 1}'+ ticket_field +'.png', bbox_inches='tight') + plt.savefig( + f"confusion_matrix_epoch_{epoch + 1}" + ticket_field + ".png", + bbox_inches="tight", + ) plt.close() # Learning curves for training and validation loss plt.figure(figsize=(10, 6)) -plt.plot(train_losses, label='Training Loss') -plt.plot(valid_losses, label='Validation Loss') -plt.title(f'Loss of training and validation for {ticket_field} over the epochs') -plt.xlabel('Epochs') -plt.ylabel('Loss') +plt.plot(train_losses, label="Training Loss") +plt.plot(valid_losses, label="Validation Loss") +plt.title(f"Loss of training and validation for {ticket_field} over the epochs") +plt.xlabel("Epochs") +plt.ylabel("Loss") plt.legend() # Save learning curve as an image -plt.savefig(f'training_validation_loss_curve_{ticket_field}.png') +plt.savefig(f"training_validation_loss_curve_{ticket_field}.png") plt.close() # Visualization of Confidence Scores plt.figure(figsize=(10, 6)) -plt.hist(val_confidence_scores, bins=50, alpha=0.7, color='blue') -plt.title(f'Confidence Score Distribution for {ticket_field}') -plt.xlabel('Confidence Score') -plt.ylabel('Number of Predictions') +plt.hist(val_confidence_scores, bins=50, alpha=0.7, color="blue") +plt.title(f"Confidence Score Distribution for {ticket_field}") +plt.xlabel("Confidence Score") +plt.ylabel("Number of Predictions") plt.grid(True) # Save Confidence Scores visualization as image -confidence_score_filename = f'confidence_scores_distribution_{ticket_field}.png' +confidence_score_filename = f"confidence_scores_distribution_{ticket_field}.png" plt.savefig(confidence_score_filename) plt.close() # Save the fine-tuned model # if args.save_model: model.save_pretrained("fine_tuned_roberta_model_" + ticket_field + "28k_data") -tokenizer.save_pretrained("fine_tuned_roberta_model_" + ticket_field + "28k_data") \ No newline at end of file +tokenizer.save_pretrained("fine_tuned_roberta_model_" + ticket_field + "28k_data") diff --git a/Backend/app/model/train/text_classification/use_fine_tuned_model.py b/Backend/app/model/train/text_classification/use_fine_tuned_model.py index 09e43041..5f0b4329 100644 --- a/Backend/app/model/train/text_classification/use_fine_tuned_model.py +++ b/Backend/app/model/train/text_classification/use_fine_tuned_model.py @@ -1,11 +1,13 @@ import torch from transformers import RobertaForSequenceClassification, RobertaTokenizer + def load_model(model_path): model = RobertaForSequenceClassification.from_pretrained(model_path) tokenizer = RobertaTokenizer.from_pretrained(model_path) return model, tokenizer + def prepare_data(tokenizer, text, max_length=512): inputs = tokenizer( text, @@ -17,6 +19,7 @@ def prepare_data(tokenizer, text, max_length=512): ) return inputs + def predict(model, tokenizer, text, device): model.to(device) model.eval() @@ -34,6 +37,7 @@ def predict(model, tokenizer, text, device): preds = torch.argmax(logits, dim=1) return preds + # Pfad zum gespeicherten Modell model_path = "./fine_tuned_roberta_model_request_type" model, tokenizer = load_model(model_path) diff --git a/Backend/app/repository/entity/ticket_entity.py b/Backend/app/repository/entity/ticket_entity.py index deb641e7..be33006e 100644 --- a/Backend/app/repository/entity/ticket_entity.py +++ b/Backend/app/repository/entity/ticket_entity.py @@ -10,11 +10,12 @@ class TicketEntity(TypedDict): _id: ObjectId title: str - location: str + service: str category: str keywords: list customerPriority: CustomerPrio affectedPerson: str description: str priority: Prio + requestType: str attachments: list[AttachmentEntity] diff --git a/Backend/test/model/ai_ticket_service_test.py b/Backend/test/model/ai_ticket_service_test.py index 8f1f93c0..811f411a 100644 --- a/Backend/test/model/ai_ticket_service_test.py +++ b/Backend/test/model/ai_ticket_service_test.py @@ -10,13 +10,13 @@ def setUp(self): self.mock_title_pipeline = MagicMock() self.mock_title_pipeline.return_value = [{"generated_text": "Mocked Title"}] - self.ai_ticket_service.title_generation_pipe = self.mock_title_pipeline + self.ai_ticket_service.title_generator_pipe = self.mock_title_pipeline self.mock_affected_person_pipeline = MagicMock() self.mock_affected_person_pipeline.return_value = [ {"entity": "B-PER", "word": "John"} ] - self.ai_ticket_service.affected_person_generation_pipe = ( + self.ai_ticket_service.affected_person_generator_pipe = ( self.mock_affected_person_pipeline ) @@ -37,7 +37,7 @@ def test_create_ticket(self): # Assert self.assertIsInstance(ticket_dict, dict) self.assertIn("title", ticket_dict) - self.assertIn("location", ticket_dict) + self.assertIn("service", ticket_dict) def test_generate_title(self): # Arrange From 2faee85a35842880c570eb27df70997578c830f4 Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Mon, 22 Jan 2024 16:38:59 +0100 Subject: [PATCH 08/16] Integrated Customer-Priority-Generator-AI into project. And Merged main into current branch. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl Signed-off-by: Koffi Tino Gnagniko --- .../ai_ticket_service/ai_ticket_service.py | 33 +++++++++++++++---- 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/Backend/app/model/ai_ticket_service/ai_ticket_service.py b/Backend/app/model/ai_ticket_service/ai_ticket_service.py index 300ad5a1..2130f552 100644 --- a/Backend/app/model/ai_ticket_service/ai_ticket_service.py +++ b/Backend/app/model/ai_ticket_service/ai_ticket_service.py @@ -33,8 +33,15 @@ def __init__(self): model="TalkTix/roberta-base-service-type-generator-28k", ) + self.customer_priority_generator_pipe = pipeline( + "text-classification", + model="TalkTix/roberta-base-customer-priority-type-generator-28k", + ) + # Possible Field values - self.request_type_values = ["Incident", " 'Service Request"] + self.request_type_values = ["Incident", "Service Request"] + self.request_type_values.sort() + self.service_values = [ "SAP ERP", "Atlassian", @@ -46,6 +53,8 @@ def __init__(self): "Snowflake", "Microsoft Office", ] + self.service_values.sort() + self.category_values = [ "HANA -> Technical Issues", "HANA -> Billing & Payment", @@ -203,6 +212,15 @@ def __init__(self): "Microsoft PowerPoint -> Account Management", "Microsoft PowerPoint -> Policy Questions", ] + self.category_values.sort() + + self.customer_priority_values = [ + "Disruption but can work", + "Disruption cannot work", + "Disruption several cannot work", + "Disruption department cannot work", + ] + self.customer_priority_values.sort() def create_ticket(self, input_text) -> dict: # generate prediction for each field @@ -222,13 +240,20 @@ def create_ticket(self, input_text) -> dict: input_text, self.service_generator_pipe, "service", self.service_values ) + customer_priority = self.generate_prediction( + input_text, + self.customer_priority_generator_pipe, + "customerPriority", + self.customer_priority_values, + ) + # Create Ticket ticket_dict = { "title": title, "service": service, "category": category, "keywords": keywords, - "customerPriority": CustomerPrio.can_work, + "customerPriority": customer_priority, "affectedPerson": affected_person, "description": input_text, "priority": Prio.low, @@ -289,10 +314,6 @@ def generate_prediction(self, input_text, pipe, field, field_values) -> str: generated_output = pipe(input_text) prediction = "" - print("=======================================================") - print("generated_output: " + field + " ", generated_output) - print("=======================================================") - if len(generated_output) > 0: prediction_score = generated_output[0]["score"] if prediction_score < 0.5: From 0391235105d401bc9016634ab74e0ebca714415b Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Mon, 22 Jan 2024 17:09:59 +0100 Subject: [PATCH 09/16] Changed customer prio enum from german to english and fixed bugs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl Signed-off-by: Koffi Tino Gnagniko --- Backend/app/api/dto/ticket.py | 12 ++++++------ Backend/app/enum/customer_prio.py | 8 ++++---- .../app/model/ai_ticket_service/ai_ticket_service.py | 2 +- Backend/app/service/ticket_db_service.py | 2 -- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/Backend/app/api/dto/ticket.py b/Backend/app/api/dto/ticket.py index 57584715..f629a794 100644 --- a/Backend/app/api/dto/ticket.py +++ b/Backend/app/api/dto/ticket.py @@ -9,13 +9,13 @@ class Ticket(BaseModel): id: str = "" - title: str - service: Location | ServiceEnum - category: str + title: str | None + service: Location | ServiceEnum | None + category: str | None keywords: list - customerPriority: CustomerPrio + customerPriority: CustomerPrio | None affectedPerson: str description: str - priority: Prio - requestType: str + priority: Prio | None + requestType: str | None attachmentNames: list[str] = [] diff --git a/Backend/app/enum/customer_prio.py b/Backend/app/enum/customer_prio.py index cd64f6d6..17e6036e 100644 --- a/Backend/app/enum/customer_prio.py +++ b/Backend/app/enum/customer_prio.py @@ -2,7 +2,7 @@ class CustomerPrio(str, Enum): - can_work = "Stoerung aber kann arbeiten" - can_not_work = "Stoerung kann nicht arbeiten" - multiple_people_can_not_work = "Stoerung mehrere können nicht arbeiten" - department_can_not_work = "Stoerung Abteilung kann nicht arbeiten" + can_work = "Disruption but can work" + can_not_work = "Disruption cannot work" + multiple_people_can_not_work = "Disruption several cannot work" + department_can_not_work = "Disruption department cannot work" diff --git a/Backend/app/model/ai_ticket_service/ai_ticket_service.py b/Backend/app/model/ai_ticket_service/ai_ticket_service.py index 2130f552..aeb88d09 100644 --- a/Backend/app/model/ai_ticket_service/ai_ticket_service.py +++ b/Backend/app/model/ai_ticket_service/ai_ticket_service.py @@ -312,7 +312,7 @@ def generate_keywords(self, input_text) -> list: def generate_prediction(self, input_text, pipe, field, field_values) -> str: generated_output = pipe(input_text) - prediction = "" + prediction = None if len(generated_output) > 0: prediction_score = generated_output[0]["score"] diff --git a/Backend/app/service/ticket_db_service.py b/Backend/app/service/ticket_db_service.py index 6b2e537a..d36db8b1 100644 --- a/Backend/app/service/ticket_db_service.py +++ b/Backend/app/service/ticket_db_service.py @@ -17,8 +17,6 @@ def __init__(self, ticket_repository: TicketRepository): def create_ticket(self, ticket_entity: TicketEntity | dict) -> Ticket: logger.info("Creating ticket...") - # temporary implementation so it doesn't create an error - ticket_entity["service"] = "Fürth" insert_one_result = self.ticket_repository.create_ticket(ticket_entity) if not insert_one_result.acknowledged: self._throw_internal_server_error("Ticket creation failed.") From 52f236485384a663c1637b95efea6868c5519660 Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Tue, 23 Jan 2024 17:50:12 +0100 Subject: [PATCH 10/16] Integrated priority AI MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl Signed-off-by: Koffi Tino Gnagniko --- Backend/app/enum/prio.py | 8 ++++---- .../model/ai_ticket_service/ai_ticket_service.py | 14 +++++++++++++- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Backend/app/enum/prio.py b/Backend/app/enum/prio.py index 33ce5829..00bbd8c5 100644 --- a/Backend/app/enum/prio.py +++ b/Backend/app/enum/prio.py @@ -2,7 +2,7 @@ class Prio(str, Enum): - low = "Niedrig" - medium = "Mittel" - high = "Hoch" - very_high = " Sehr Hoch" + low = "Low" + medium = "Medium" + high = "High" + very_high = "Very High" diff --git a/Backend/app/model/ai_ticket_service/ai_ticket_service.py b/Backend/app/model/ai_ticket_service/ai_ticket_service.py index aeb88d09..b42b0968 100644 --- a/Backend/app/model/ai_ticket_service/ai_ticket_service.py +++ b/Backend/app/model/ai_ticket_service/ai_ticket_service.py @@ -38,6 +38,11 @@ def __init__(self): model="TalkTix/roberta-base-customer-priority-type-generator-28k", ) + self.priority_generator_pipe = pipeline( + "text-classification", + model="TalkTix/roberta-base-priority-type-generator-28k", + ) + # Possible Field values self.request_type_values = ["Incident", "Service Request"] self.request_type_values.sort() @@ -222,6 +227,9 @@ def __init__(self): ] self.customer_priority_values.sort() + self.priority_values = ["Low", "Medium", "High", "Very High"] + self.priority_values.sort() + def create_ticket(self, input_text) -> dict: # generate prediction for each field title = self.generate_title(input_text) @@ -247,6 +255,10 @@ def create_ticket(self, input_text) -> dict: self.customer_priority_values, ) + priority = self.generate_prediction( + input_text, self.priority_generator_pipe, "priority", self.priority_values + ) + # Create Ticket ticket_dict = { "title": title, @@ -256,7 +268,7 @@ def create_ticket(self, input_text) -> dict: "customerPriority": customer_priority, "affectedPerson": affected_person, "description": input_text, - "priority": Prio.low, + "priority": priority, "requestType": request_type, "attachments": [], } From bdde6901136750a4b976637f4fe45c6dc9e346ce Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Tue, 23 Jan 2024 18:03:47 +0100 Subject: [PATCH 11/16] Fixed Test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl Signed-off-by: Koffi Tino Gnagniko --- Backend/test/api/v1/ticket_api_test.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Backend/test/api/v1/ticket_api_test.py b/Backend/test/api/v1/ticket_api_test.py index 2714b12a..9ae59d10 100644 --- a/Backend/test/api/v1/ticket_api_test.py +++ b/Backend/test/api/v1/ticket_api_test.py @@ -167,13 +167,13 @@ def test_update_ticket_attributes_success(self): updated_ticket_json = { "id": "6554b34d82161e93bff08df6", "title": "Test Ticket", - "service": "Fürth", + "service": Location.fuerth, "category": "", "keywords": [], - "customerPriority": "Stoerung aber kann arbeiten", + "customerPriority": CustomerPrio.can_work, "affectedPerson": "", "description": "", - "priority": "Niedrig", + "priority": Prio.low, "attachments": [], "requestType": "Incident", } From 0b1728b089924a6cf3b7c07565e8674e18deb6fa Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Tue, 23 Jan 2024 18:47:23 +0100 Subject: [PATCH 12/16] Resolved merge conflicts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Marco Martin Härtl Signed-off-by: Koffi Tino Gnagniko --- Backend/app/api/dto/ticket.py | 2 +- Backend/test/api/v1/ticket_api_test.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Backend/app/api/dto/ticket.py b/Backend/app/api/dto/ticket.py index 7bd62d20..6adc2def 100644 --- a/Backend/app/api/dto/ticket.py +++ b/Backend/app/api/dto/ticket.py @@ -8,7 +8,7 @@ class Ticket(BaseModel): id: str = "" title: str | None - service: Location | ServiceEnum | None + service: str | None category: str | None keywords: list customerPriority: CustomerPrio | None diff --git a/Backend/test/api/v1/ticket_api_test.py b/Backend/test/api/v1/ticket_api_test.py index 5d4973d3..572aa253 100644 --- a/Backend/test/api/v1/ticket_api_test.py +++ b/Backend/test/api/v1/ticket_api_test.py @@ -151,7 +151,7 @@ def test_update_ticket_attributes_success(self): ticket_entity = TicketEntity( _id=self.ticket_id, title="Test Ticket", - service="Fürth", + service="", category="", keywords=[], customerPriority=CustomerPrio.can_work, @@ -166,7 +166,7 @@ def test_update_ticket_attributes_success(self): updated_ticket_json = { "id": "6554b34d82161e93bff08df6", "title": "Test Ticket", - "service": Location.fuerth, + "service": "", "category": "", "keywords": [], "customerPriority": CustomerPrio.can_work, From b361d96bdcc12ed051c0b3cff93461ef546a8757 Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Tue, 23 Jan 2024 18:59:18 +0100 Subject: [PATCH 13/16] =?UTF-8?q?Updated=20tests=20Co-authored-by:=20Marco?= =?UTF-8?q?=20Martin=20H=C3=A4rtl=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Koffi Tino Gnagniko --- Backend/test/api/v1/ticket_api_test.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Backend/test/api/v1/ticket_api_test.py b/Backend/test/api/v1/ticket_api_test.py index 572aa253..fba62434 100644 --- a/Backend/test/api/v1/ticket_api_test.py +++ b/Backend/test/api/v1/ticket_api_test.py @@ -180,7 +180,7 @@ def test_update_ticket_attributes_success(self): exp_ticket = Ticket( id=str(self.ticket_id), title="Test Ticket", - service="Fürth", + service="", category="", keywords=[], customerPriority=CustomerPrio.can_work, From 3a6abef50591fef95c0eee1a0958d5d3c3571374 Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Tue, 23 Jan 2024 20:24:03 +0100 Subject: [PATCH 14/16] =?UTF-8?q?Updated=20tests=20Co-authored-by:=20Marco?= =?UTF-8?q?=20Martin=20H=C3=A4rtl=20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Koffi Tino Gnagniko --- Backend/app/api/dto/ticket.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Backend/app/api/dto/ticket.py b/Backend/app/api/dto/ticket.py index 6adc2def..29f6971a 100644 --- a/Backend/app/api/dto/ticket.py +++ b/Backend/app/api/dto/ticket.py @@ -15,5 +15,5 @@ class Ticket(BaseModel): affectedPerson: str description: str priority: Prio | None - requestType: str | None attachmentNames: list[str] = [] + requestType: str | None From 75cac6fdfbfed96727fec5062a9a543fad2bdfb2 Mon Sep 17 00:00:00 2001 From: garvinkon Date: Tue, 23 Jan 2024 22:16:07 +0100 Subject: [PATCH 15/16] update requirements --- Backend/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/Backend/requirements.txt b/Backend/requirements.txt index cf645c93..95ab754f 100644 --- a/Backend/requirements.txt +++ b/Backend/requirements.txt @@ -14,5 +14,6 @@ requests==2.31.0 python-multipart==0.0.6 beautifulsoup4==4.12.2 scikit-learn==1.3.2 +openai==1.7.2 python-jose==3.3.0 From fec947bc8a94bee4bb52322d248a496d1bcf517c Mon Sep 17 00:00:00 2001 From: Koffi Tino Gnagniko Date: Tue, 23 Jan 2024 22:54:23 +0100 Subject: [PATCH 16/16] Fixed requestType bug in frontend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Garvin Konopka Co-authored-by: Marco Martin Härtl Signed-off-by: Koffi Tino Gnagniko --- Frontend/src/app/app.component.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/Frontend/src/app/app.component.ts b/Frontend/src/app/app.component.ts index 0a225077..40c4d450 100644 --- a/Frontend/src/app/app.component.ts +++ b/Frontend/src/app/app.component.ts @@ -158,8 +158,6 @@ export class AppComponent implements OnInit { this.logger.log('RequestType updated.'); } else { this.logger.log('RequestType exists.'); - // Only show the latest response in the UI - this.chatMessages.pop(); // Remove the user message } if (response.requestType) {