SystemyDialogowe/mark_data.ipynb

12 KiB

import pandas as pd
import regex as re

# sample values

titles = [
    "Batman",
    "Batmana",
    "Ambulans",
    "Bunkier strachu",
    "Córka",
    "Curka"
    "Uncharted",
    "Inni ludzie",
    "Śmierć na Nilu",
    "Skarb Mikołajka",
        ]

dates = [
    "w najbliższy poniedziałek", 
    "w najbliższy wtorek", 
    "w najbliższą środę", 
    "w najbliższy czwartek", 
    "w najbliższy piątek",
    "w najbliższą sobotę",
    "w najbliższą niedzielę",
    "w poniedziałek", 
    "we wtorek", 
    "w środę", 
    "w czwartek", 
    "w piątek",
    "w sobotę",
    "w niedzielę",
    "na najbliższy poniedziałek", 
    "na najbliższy wtorek", 
    "na najbliższą środę", 
    "na najbliższy czwartek", 
    "na najbliższy piątek",
    "na najbliższą sobotę",
    "na najbliższą niedzielę",
    "najbliższy poniedziałek", 
    "najbliższy wtorek", 
    "najbliższa środa", 
    "najbliższy czwartek", 
    "najbliższy piątek",
    "najbliższa sobota",
    "najbliższa niedziela",
    "na jutro", 
    "jutro", 
    "w dniu jutrzejszym",
    "po jutrze", 
    "pojutrze", 
    "za dwa dni", 
    "za trzy dni",
    "za tydzień", 
    "dzisiaj",
    "dziś",
    r"na dzień [0-9]{1,2}[ /][0-9]{1,2}",
    r"na [0-9]{1,2}[ /][0-9]{1,2}",
    r"dzień [0-9]{1,2}[ /][0-9]{1,2}",
    r"dnia [0-9]{1,2}[ /][0-9]{1,2}",
    r"[0-9]{1,2}[ /][0-9]{1,2}",
    ]

times = [
    r"wybieram: [0-9]{1,2}[:][0-9]{1,2}",
    r"wybieram [0-9]{1,2}[:][0-9]{1,2}",
    r"na godzinę [0-9]{1,2}[:][0-9]{1,2}",
    r"na godzina [0-9]{1,2}[:][0-9]{1,2}",
    r"o godzinie [0-9]{1,2}[:][0-9]{1,2}",
    r"o [0-9]{1,2}[:][0-9]{1,2}",
    r"o [0-9]{2}",
    r"na [0-9]{1,2}",
    r"na [0-9]{1,2}[:][0-9]{1,2}",
    r"godzina [0-9]{1,2}[:][0-9]{1,2}",
    r"[0-9]{1,2}[:][0-9]{1,2}",
    "rano",
    "wieczorem",
    "w południe",
    "po południu",
    "popołudniu",
    "w nocy",
    "pierwszą",
    "drugą",
    "trzecią",
    "piątą",
    "szóstą",
    "siódmą",
    "ósmą",
    "dziewiatą",
    "dziesiątą",
    "jedenastą",
    "dwunastą",
    "trzynastą",
    "czternastą",
    "piętnastą",
    "szesnastą",
    "siedemnastą",
    "osiemnastą",
    "dziewiętnastą",
    "dwudziestą pierwszą",
    "dwudziestą drugą",
    "dwudziestą trzecią",
    "dwudziestą czwartą",
    "o północy"
    ]

quantities = [
    r"chcę [1-9][0-9]{0,1}",
    r"poproszę [1-9][0-9]{0,1}",
    r"[1-9][0-9]{0,1}",
]

seats = [
    r'[a-zA-Z][0-9]{1,2} [a-zA-Z][0-9]{1,2} [a-zA-Z][0-9]{1,2} [a-zA-Z][0-9]{1,2} [a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2} [a-zA-Z][0-9]{1,2} [a-zA-Z][0-9]{1,2} [a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2} [a-zA-Z][0-9]{1,2} [a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2} [a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2},[a-zA-Z][0-9]{1,2},[a-zA-Z][0-9]{1,2},[a-zA-Z][0-9]{1,2},[a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2},[a-zA-Z][0-9]{1,2},[a-zA-Z][0-9]{1,2},[a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2},[a-zA-Z][0-9]{1,2},[a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2},[a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2}, [a-zA-Z][0-9]{1,2}, [a-zA-Z][0-9]{1,2}, [a-zA-Z][0-9]{1,2}, [a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2}, [a-zA-Z][0-9]{1,2}, [a-zA-Z][0-9]{1,2}, [a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2}, [a-zA-Z][0-9]{1,2}, [a-zA-Z][0-9]{1,2}',
    r'[a-zA-Z][0-9]{1,2}, [a-zA-Z][0-9]{1,2}',    
]

areas = [
    "u góry po prawej",
    "u góry po lewej",
    "u góry na środku",
    "na środku po prawej",
    "na środku po lewej",
    "na dole po prawej",
    "na dole po lewej",
    "na dole na środku",
    "po lewej",
    "po prawej",
    "na środku",
    "lewo",
    "prawo",
    "środek",
    "blisko od ekranu",
    "daleko od ekranu",
    "blisko ekranu",
    "daleko ekranu",
]

genres = [
    'akcja',
    'akcji'
    'dramat',
    'komedia',
    'Horror',
    'Thriller',
    'science fiction',
    'romans',
    'bajka',
    'rodzinny',
    'animowany',
    'bajka',
    'komedia romantyczna',

]

# slots names
slots = [
    "tytul",
    "date",
    "time",
    "quantity",
    "seats",
    "area",
    "genres",
    ]

def removePunctation(text):
    return re.sub(r'[!@#$,\"\'\?\'\"\|.]', '', text)

def dummyTextAnnotation(text, sampelValuesList, slotName):
    textJoin = text
    for sampleValue in sampelValuesList:
        if re.search(r"(^|\s)" + sampleValue + r"($|\s)", textJoin):
            textJoin = re.sub(r'(^|\s)(' + sampleValue + r')($|\s)', f"\g<1> **/start** {slotName} \g<2> **/end** \g<3>", textJoin)
            break # can one sentence has only one slot of a given type?
    return textJoin

def parseAnnotation(text, intent, textLen, cleanText, isTest, pathOut):
    textTokenize = text.split()
    slotLabel =  ""
    col1 = [i for i in range(1, textLen + 1)]
    col2 = []
    col3 = [intent for _ in range(textLen)]
    col4 = []
    isSlot = False
    slotVal = None
    annotation = ""
    i = 0
    while i < len(textTokenize):
        if textTokenize[i] == "**/start**":
            isSlot = True
            slotVal = textTokenize[i + 1]
            if len(slotLabel) > 0:
                slotLabel += f','
            i += 2
            annotation = "B-"
        elif textTokenize[i] == "**/end**":
            isSlot = False
            slotLabel += ":" + slotVal
            slotVal = None
            i += 1
        elif isSlot:
            slotLabel += textTokenize[i]
            col2.append(textTokenize[i])
            col4.append(annotation + slotVal)
            annotation = "I-"
            i += 1
        elif not isSlot:
            col2.append(textTokenize[i])
            col4.append("NoLabel")
            i += 1
    df = pd.DataFrame(list(zip(col1, col2, col3, col4)))
    path = ""
    if isTest: path = pathOut + 'test.conllu'
    else: path =  pathOut + 'train.conllu'
    with open(path, "a", encoding="utf-8") as outputFile:
        outputFile.write(f"# text: {cleanText}\n# intent: {intent}\n# slots: {slotLabel}\n")
    df.to_csv(path, header=None, index=None, sep='\t', mode='a')
    with open(path, "a", encoding="utf-8") as outputFile:
        outputFile.write(f"\n")
    

def processFile(pathIn, pathOut, fileName, isTest):
    # path = './data/dialog-16-01-01.tsv'
    encoding = "utf-8"
    # encoding = "cp1250"
    dialog_df = pd.read_csv(pathIn + fileName, sep='\t', header=None, encoding=encoding)
    
    dialog_df = dialog_df.reset_index()  # make sure indexes pair with number of rows
    for _, row in dialog_df.iterrows():
        if row[0].strip() == "user":
            text = removePunctation(row[1]).lower()
            
            # movies annotation
            annotatedText = dummyTextAnnotation(text, titles, slots[0])

            # dates annotation
            annotatedText = dummyTextAnnotation(annotatedText, dates, slots[1])

            # time
            annotatedText = dummyTextAnnotation(annotatedText, times, slots[2])

            # quantity
            annotatedText = dummyTextAnnotation(annotatedText, quantities, slots[3])

            # seats 
            annotatedText = dummyTextAnnotation(annotatedText, seats, slots[4])

            # area
            annotatedText = dummyTextAnnotation(annotatedText, areas, slots[5])
            
            #genre
            annotatedText = dummyTextAnnotation(annotatedText, genres, slots[5])
            
            parseAnnotation(annotatedText, row[2], len(row[1].split()), text, isTest, pathOut)
            
    # dialog_df.to_csv(pathOut + "test.conllu", sep="\t", index=False, header=None)

def annotateData():
    pathOut = './train_data/'
    pathIn = "./empty_data/"
    i = 0
    j = 0
    nr = 0
    for i in range(11,16):
        for j in range(20):
            for nr in range(1,5):
                fileName = "dialog-" + str(i).zfill(2) + "-" + str(j).zfill(2) + "-" + str(nr).zfill(2) + ".tsv"
                try:
                    processFile(pathIn, pathOut, fileName, False)
                except:
                    pass
                try:
                    fileName = "dialog-" + str(i).zfill(2) + "-" + str(j).zfill(2) + "-" + str(nr).zfill(2) + "(test)" + ".tsv"
                    processFile(pathIn, pathOut, fileName, True)
                except:
                    pass
annotateData()
# processFile("./empty_data/", './train_data/', "dialog-12-01-01.tsv", isTest=True)
# testText = "dobrze dokonano rezerwacji na film transformer numer twojej rezeracji to 123890"
# print(dummyTextAnnotation(testText, sampelValuesList=titles, slotName=slots[0]))