pjn-2024-cw/examples.ipynb
2024-11-13 13:27:23 +01:00

14 KiB

nie robimy 2 nowych linii w bloku funkcji. sentences[::2] oraz sentences[1::2] powinny być przypisane do osobnych zmiennych

import re
tekst =  "Pies ten pochodzi z południowych Chin, z terenów prowincji Guangdong! Został rozpropagowany i hodowany w celach wystawowych przez hodowców w USA. Nazwa psa, pochodząca z chińskiego, oznacza dosłownie piaszczysta skóra. Chart polski  polska rasa psa myśliwskiego, znana prawdopodobnie od czasów Galla Anonima, zaliczana do grupy chartów."
def split_sentences(text):
    sentences = re.split(r'([.!?]\s+)(?=[A-Z])', text)


    full_sentences = [''.join(pair) for pair in zip(sentences[::2], sentences[1::2])]


    for sentence in full_sentences:
        print(sentence)
    print(full_sentences)
split_sentences(tekst)
Pies ten pochodzi z południowych Chin, z terenów prowincji Guangdong! 
Został rozpropagowany i hodowany w celach wystawowych przez hodowców w USA. 
Nazwa psa, pochodząca z chińskiego, oznacza dosłownie piaszczysta skóra. 
['Pies ten pochodzi z południowych Chin, z terenów prowincji Guangdong! ', 'Został rozpropagowany i hodowany w celach wystawowych przez hodowców w USA. ', 'Nazwa psa, pochodząca z chińskiego, oznacza dosłownie piaszczysta skóra. ']

Niewłaściwa nazwa funkcji switch_letter (robi coś innego, niż nazwa na to wskazuje). Linijka z sum jest nieczytelna.

text = "kurde faja."

vulgar_words_base = ["kurd", "choler"]

def switch_letter(word, vulgar_word_list):
    word = word.lower()
    for bad_word in vulgar_word_list:
        switched_letters = sum(1 for a, b in zip(word, bad_word) if a != b)
        if switched_letters == 1:
            return True
    return False

def censor_text(text):
    pattern = re.compile(r'[^\s]*(' + '|'.join([f'{word}' for word in vulgar_words_base]) + r')[^\s]*', re.IGNORECASE)
    censored_text = pattern.sub("---", text)

    censored_text_list = censored_text.split()
    
    for i, word in enumerate(censored_text_list):
        if switch_letter(word, vulgar_words_base):
            censored_text_list[i] = "---"
    final_censored_text = " ".join(censored_text_list)

    return final_censored_text

print(censor_text(text))
--- faja.
switch_letter("kurcze", ["kurzce"])
False

Jeżeli nie ma takiej konieczności nie iterujemy po rozdzielonym na słowa tekście, tylko na całym tekście.

# Solution 2
text = 'Siała baba mak. Czy wiedziała jak? Dziadek wiedział, nie powiedział, a to było tak!'
sentences = []

def split_sentences(text):
    sentence = ''
    for word in text.split():
        x = re.search(r'[a-zA-Z0-9]+[.?!]', word)
        if x is None:
            sentence += f'{word} '
        else:
            sentence += word
            sentences.append(sentence)
            sentence = ''
    for result in sentences:
        print(result)


split_sentences(text)
Siała baba mak.
Czy wiedziała jak?
Dziadek wiedział, nie powiedział, a to było tak!

Nie stosujemy zapisu if {zmienna}, tylko if {zmienna} is True/False. Kod dla danego warunku przenosimy do nowej linii

import re

def validate_name(name):
    valid = re.match(r'^[A-Z][a-z]{1,}',name)
    if valid: return True
    else:  return False

Przykład właściwego zastosowania komentarza

def censor_text(text):
    prefixes = r'(do|na|o|od|pod|po|prze|przy|roz|s|u|w|y|za|z|u)*'

    # profanities according to prof. Jerzy Bralczyk
    profanities = [ 
        rf'\b{prefixes}(pierd\w*)\b',
    ]

    profanity_pattern = re.compile('|'.join(profanities), re.IGNORECASE)

    return profanity_pattern.sub('---', text)
# jeżeli ten if określa 3 warianty na tym samym poziomie, to nie stosujemy zagnieżdżenia warunków
if [ "$positive_count" -gt "$negative_count" ]; then
    echo "wydzwiek pozytywny"
else
    if [ "$negative_count" -gt "$positive_count" ]; then
        echo "wydzwiek: negatywny"
    else
        echo "wydzwiek: neutralny"
    fi
fi


# ten else nigdy się nie wywoła - nie powinno go być
if [ $positive_count -gt $negative_count ]
        then echo "Positive"
elif [ $positive_count -lt $negative_count ]
        then echo "Negative"
elif [ $positive_count -eq $negative_count ]
        then echo "Neutral"
else
        echo "Error" # to nie istnieje
fi


# positive - taki błąd mocno rzuca się w oczy (mimo że program działa)
POZITIVE="positive-words.txt"

Notebook 05

# algorytm wzięty z pseudokodu z prezentacji profesora Jassema
def maxmatch_text_split(text, vocabulary):
    if text == "":
        return []
    for i in range(len(text)-1, -1, -1):
        firstword = text[0:i+1] # nie piszemy [0:x] tylko [:x]
        reminder = text[i+1:]
        if firstword in vocabulary:
            return [firstword] + maxmatch_text_split(reminder, vocabulary)
    firstword = text[0]
    reminder = text[1]
    return [firstword] + maxmatch_text_split(reminder, vocabulary)
def create_bpe_tokenizer(text, max_vocab_length):
    nfoiwanfoiwa
    
    for x in range(10):
        nfwoiaf
        
    awfnoia
    if noiawniofa:
        iognioe
    else:
        nawoinoigagna
    fniaw..

    return 0
import string
from collections import Counter
import re


def create_bpe_tokenizer(text, max_vocab_length):
    text  = ("".join(x for x in text if x not in string.punctuation)).lower()
    vocabulary = list(set([x for x in text]))
    while len(vocabulary)<max_vocab_length:
        text = re.findall("|".join(vocabulary), "".join(text))
        list_bigrams = []
        for i in range(0, len(text)-1):
            list_bigrams.append("".join(text[i:i+2]))
        bi_freq = Counter(list_bigrams)
        if all(i == 1 for i in bi_freq.values()):
            break
        sorted_bigram_list = sorted(bi_freq.items(), key = lambda x: list_bigrams.index(x[0]))
        sorted_bigram_dict={}
        for key, value in sorted_bigram_list:
            sorted_bigram_dict[key] = value
        vocabulary.append(max(sorted_bigram_dict, key=sorted_bigram_dict.get))
        vocabulary = sorted(vocabulary, key = len, reverse=True)
    vocabulary = sorted(vocabulary, key = len, reverse=True)
    text = re.findall("|".join(vocabulary), "".join(text))
    # print( len(vocabulary), sorted(vocabulary, key = len))
    return vocabulary

Próba "uratowania" powyższego kodu

def all_frequencies_are_ones(bigram_freqs):
    return all(i == 1 for i in bigram_freqs.values())


def create_bpe_tokenizer2(text, max_vocab_length):
    text  = ("".join(x for x in text if x not in string.punctuation)).lower()
    vocabulary = list(set(text))

    while len(vocabulary) < max_vocab_length:
        text = re.findall("|".join(vocabulary), "".join(text))
        bigrams = []

        for i in range(0, len(text)-1):
            bigrams.append("".join(text[i:i+2]))

        bigram_freq = Counter(bigrams)
        if all_frequencies_are_ones(bigram_freq):
            break

        most_common_bigram = bigram_freq.most_common(1)[0][0]
        vocabulary.append(most_common_bigram)
        vocabulary = sorted(vocabulary, key = len, reverse=True)
    
    vocabulary = sorted(vocabulary, key = len, reverse=True)

    return vocabulary

Warto zapoznać się z obiektami z paczki collections

from collections import defaultdict

pairs = {}
for sequence in vocab:
    symbols = sequence.split()
    for i in range(len(symbols) - 1):
        pair = (symbols[i], symbols[i + 1])
        if pair in pairs:
            pairs[pair] += vocab[sequence]
        else:
            pairs[pair] = vocab[sequence]

# to samo co
pairs = defaultdict(int)
for sequence in vocab:
    symbols = sequence.split()
    for i in range(len(symbols) - 1):
        pair = (symbols[i], symbols[i + 1])
        pairs[pair] += vocab[sequence]

Nie uzywamy dlugich slow na iteratory

def maxmatch_text_split(text, vocabulary):
    words_list = []
    iterator = 0
    
    while iterator < len(text):
        
        for backwards_iterator in range(len(text), iterator, -1):
            # if text[iterator : backwards_iterator] in vocabulary: 
            if text[iterator : backwards_iterator].lower() in vocabulary: #.lower() because every token is lower case in vocab
                words_list.append(text[iterator : backwards_iterator]) #.lower() if want to have exact same tokens as in vocab
                break
            elif backwards_iterator == iterator + 1:
                words_list.append(text[iterator : backwards_iterator])
                
        iterator += len(words_list[-1])
    return words_list

Niedopuszczalne są takie nazwy zmiennych (z błędami!)

dictinary_of_pairs_occurance = {}