2022-05-14#

Dieses Notebook:

Diese Seite wie bearbeiten:

  • Download des Notebooks auf den eigenen Rechner, oder auch einfach ‘rüberkopieren des Codes.

  • Fügen Sie statt … (Ellipsis) Ihren Code ein.

  • Ideal wäre es, wenn die assert-Tests durchlaufen!

Feature Engineering: n-Gramme auf Zeichenebene#

Statt einem Bag of Words erstellen wir einen Sack aus Zeichenketten der Länge n (typischerweise n=3):

  • aus """Die "Antwort"? lautet 42! ;-)"""

  • mache für n==3 (default): ['Die', 'Ant', 'ntw', 'two', 'wor', 'ort', 'lau', 'aut', 'ute', 'tet']

n_char_substrings()#

Gegeben: ein String

  • z.B. "Hallo".

Gesucht: eine Liste aller aus n Zeichen bestehenden Teilstrings

  • z.B. für n=3 (default): [ "Hal", "all", "llo" ]

Strings mit weniger als n Zeichen erzeugen eine leere Liste.

def n_char_substrings(string, n=3):
    return ...
assert n_char_substrings("Hallo", 4) == ['Hall', 'allo']
assert n_char_substrings("Hallo", 3) == ['Hal', 'all', 'llo']
assert n_char_substrings("Hal") == ['Hal' ]
assert n_char_substrings("Ha") == []
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In [2], line 1
----> 1 assert n_char_substrings("Hallo", 4) == ['Hall', 'allo']
      2 assert n_char_substrings("Hallo", 3) == ['Hal', 'all', 'llo']
      3 assert n_char_substrings("Hal") == ['Hal' ]

AssertionError: 

n_char_bag_from_word()#

Gegeben: Eine Liste von Strings,

  • z.B. ["Hallo", "Welt"]

Gesucht: Eine Liste aller darin enthaltenen n_char_substrings jedes Strings

  • z.B. für n=3: ['Hal', 'all', 'llo', 'Wel', 'elt']

def n_char_bag_from_word(list_of_strings, n=3):
    return_list = []
    for s in ...:
        ...
    return return_list
assert n_char_bag_from_word(["Hallo", "Welt"]) == ['Hal', 'all', 'llo', 'Wel', 'elt']
assert n_char_bag_from_word(["Hallo", "Welt"], 5)  == ['Hallo']

clean_string(string)#

Gegeben: ein String, der auch Sonderzeichen enthalten kann

  • z.B. """Die "Antwort"? lautet 42! ;-)"""

Gesucht: ein String, der nur noch aus alfanumerischen Zeichen besteht. Alle anderen Zeichen wurden durch Leerzeichen ersetzt.

  • z.B. """Die  Antwort   lautet 42    """

Hilfreich ist hier die Funktion https://www.w3schools.com/python/ref_string_isalnum.asp

keep_chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZäöüÄÖÜß"
def alnum(x):
    if x in keep_chars:
        return x
    else:
        return " "
def alnum(x): return x if x.isalnum() else " "
alnum = lambda x: x if x.isalnum() else " "
text = """Die "Antwort"? lautet 42! ;-)"""
"".join( alnum(c) for c in text )
def clean_string(string):
    alnum = lambda x: x if x.isalnum() else " "
    return "".join(alnum(c) for c in string )
clean_string("""Die "Antwort"? lautet 42! ;-)""")
assert clean_string("""Die "Antwort"? lautet 42! ;-)""") == 'Die  Antwort   lautet 42     '

remove_stopwords()#

Gegeben sei eine Liste von Stop-Wörtern,

  • z.B. stopwords = [ "der", "die", "das", "ist", "hier", "da" ].

Außerdem haben wir einen String,

  • z.B. "Das ist ja nett hier!"

Gesucht: Der String ohne die Stopwörter,

  • z.B. "ja nett hier!"

Und natürlich spielt Groß-/Kleinschreibung keine Rolle.

stopwords = [ "der", "die", "das", "ist", "hier", "da" ]
def remove_stopwords(string, stopwords):
    wordlist = string.split()
    return " ".join( w for w in wordlist if not w.lower() in stopwords)
text = "Das ist ja nett hier!"
remove_stopwords(clean_string(text), stopwords)
assert remove_stopwords(clean_string(text), stopwords) == "ja nett"
assert remove_stopwords("Da Da Da", stopwords) == ""

remove_stopwords_dict()#

Gegeben sei obige Funktion remove_stopwords(), sowie ein dict von Strings, z.B.

corpus = { "doc_1": "Das ist ja nett hier!", 
           "doc_2": "Der Bach ist ausgetrocknet."
           "doc_3": "Da Da Da"}`

Gesucht: Ein dict von Strings, bei denen alle Sonderzeichen und alle Stopwörter entfernt sind, z.B.

corpus = { "doc_1": "ja nett", 
            "doc_2": "Bach ausgetrocknet",
            "doc_3": ""}

Die Stopwörter sollen unabhängig von Groß-/Kleinschreibung entfernt werden.

corpus = { "doc_1": "Das ist ja nett hier!", 
            "doc_2": "Der Bach ist ausgetrocknet.",
            "doc_3": "Da Da Da" }
def remove_stopwords_dict(dict_of_string, stopwords):
    return { k: remove_stopwords(clean_string(v), stopwords) for k, v in corpus.items()  }
corpus2 = remove_stopwords_dict(corpus, stopwords)
assert corpus2 == {'doc_1': 'ja nett',                                      
                   'doc_2': 'Bach ausgetrocknet', 
                    'doc_3': ''}

n_char_bag_from_string()#

Gegeben: Ein String mit Leerzeichen und Sonderzeichen

  • z.B. """Die "Antwort"? lautet 42! ;-)"""

gesucht: Eine Liste von n_char_substrings(), wobei die Sonderzeichen eliminiert sind, und die Wortgrenzen eingehalten werden.

  • z.B. ['Die', 'Ant', 'ntw', 'two', 'wor', 'ort', 'lau', 'aut', 'ute', 'tet']

def n_char_bag_from_string(string, n=3):
    return ...
text = """Die "Antwort"? lautet 42! ;-)"""
assert n_char_bag_from_string(text) == ['Die', 'Ant', 'ntw', 'two', 'wor', 'ort', 'lau', 'aut', 'ute', 'tet']
assert n_char_bag_from_string(text, 5) == ['Antwo', 'ntwor', 'twort', 'laute', 'autet']

flatten_nested_list(list)#

gegeben: Eine Liste von Listen,

  • z.B. [ [ 1, 2, 3],  ['a','b', 'Welt' ] ]

Gesucht: Eine flache Liste aller Elemente

  • z.B. [ 1, 2, 3, 'a','b', 'Welt' ]

# Lösung 1: konventionell und einfach mit einer for-Schleife

def flatten_nested_list(list):
    result = []
    for l in ...:
        ...
    return result

# Lösung 2: Ein Einzeiler
def flatten_nested_list2(list):
    import functools
    return ...
list_of_lists = [ [ 1, 2, 3],  ['a','b', 'Welt' ] ]
assert flatten_nested_list(list_of_lists) == [1, 2, 3, 'a', 'b', 'Welt']
assert flatten_nested_list2(list_of_lists) == [1, 2, 3, 'a', 'b', 'Welt']

Zusatzaufgabe: Was ergibt der folgende Funktionsaufruf? Warum?

  • flatten_nested_list([ "Hallo", ["schöne", "Welt"] ])

term_set_from_string()#

gegeben: Ein String mit Wörtern

  • z.B. "do hocket die die imma do hocket"

gesucht: Ein Set, welche Wörter in dieser Liste vorkommen

  • z.B. {'die', 'do', 'hocket', 'imma'}

Ein “Wort” sei eine Folge von Groß- und Kleinbuchstaben oder Ziffern, ohne Sonderzeichen. Sie dürfen annehmen, dass der String nur aus Wörtern und Leerzeichen besteht - z.B. als Ergebnis der oben von Ihnen implementierten Funktion clean_string(string) ;-)

def term_set_from_string(string):
    return ...
satz = "do hocket die die imma do hocket"
assert term_set_from_string(satz) == {'die', 'do', 'hocket', 'imma'}

term_count_from_string()#

Gegeben: Ein String mit Wörtern

  • z.B. "do hocket die die imma do hocket"

Gesucht: Ein Dict tf, das die Häufigkeit jedes einzelnen Wortes angibt.

  • z.B. {'do': 2, 'hocket': 2, 'die': 2, 'imma': 1}

def term_count_from_string(string):
    result = {}
    for t in ...:
        ...
    return result
satz = "do hocket die die imma do hocket"
assert term_count_from_string(satz) == {'do': 2, 'hocket': 2, 'die': 2, 'imma': 1}