Die Version 2020 von 100 Klopfen der Sprachverarbeitung, die als Sammlung von Problemen der Verarbeitung natürlicher Sprache bekannt ist, wurde veröffentlicht. Dieser Artikel fasst die Ergebnisse der Lösung von Kapitel 5: Abhängigkeitsanalyse aus den folgenden Kapiteln 1 bis 10 zusammen. Ich werde.
Wir verwenden Google Colaboratory für Antworten. Ausführliche Informationen zum Einrichten und Verwenden von Google Colaboratory finden Sie in diesem Artikel. Das Notizbuch mit den Ausführungsergebnissen der folgenden Antworten ist unter [github] verfügbar (https://github.com/hana-mame/nlp100/blob/master/chapter05.ipynb).
Verwenden Sie CaboCha, um eine Abhängigkeitsanalyse für den Text (neko.txt) von Natsume Sosekis Roman "Ich bin eine Katze" durchzuführen und das Ergebnis in einer Datei namens neko.txt.cabocha zu speichern. Verwenden Sie diese Datei, um ein Programm zu implementieren, das die folgenden Fragen beantwortet.
Laden Sie zunächst die angegebenen Daten herunter. Wenn Sie den folgenden Befehl in der Zelle von Google Colaboratory ausführen, wird die Zieldatei in das aktuelle Verzeichnis heruntergeladen.
!wget https://nlp100.github.io/data/neko.txt
Installieren Sie als Nächstes CaboCha und MeCab sowie CRF ++, die zum Ausführen von CaboCha erforderlich sind.
#Installieren Sie MeCab
!apt install mecab libmecab-dev mecab-ipadic-utf8
# CRF++Laden Sie die Quelldatei von herunter / dekomprimieren / installieren Sie sie
FILE_ID = "0B4y35FiV1wh7QVR6VXJ5dWExSTQ"
FILE_NAME = "crfpp.tar.gz"
!wget 'https://docs.google.com/uc?export=download&id=$FILE_ID' -O $FILE_NAME
!tar xvf crfpp.tar.gz
%cd CRF++-0.58
!./configure && make && make install && ldconfig
%cd ..
#Herunterladen / Entpacken / Installieren von CaboCha-Quelldateien
FILE_ID = "0B4y35FiV1wh7SDd1Q1dUQkZQaUU"
FILE_NAME = "cabocha-0.69.tar.bz2"
!wget --load-cookies /tmp/cookies.txt "https://docs.google.com/uc?export=download&confirm=$(wget --quiet --save-cookies /tmp/cookies.txt --keep-session-cookies --no-check-certificate 'https://docs.google.com/uc?export=download&id=$FILE_ID' -O- | sed -rn 's/.*confirm=([0-9A-Za-z_]+).*/\1\n/p')&id=$FILE_ID" -O $FILE_NAME && rm -rf /tmp/cookies.txt
!tar -xvf cabocha-0.69.tar.bz2
%cd cabocha-0.69
!./configure -with-charset=utf-8 && make && make check && make install && ldconfig
%cd ..
Nach Abschluss der Installation führen wir sofort die Abhängigkeitsanalyse durch.
Durch Ausführen des folgenden Befehls wird das Ergebnis der Abhängigkeitsanalyse von `neko.txt``` als`
neko.txt.cabocba``` ausgegeben.
!cabocha -f1 -o neko.txt.cabocha neko.txt
Überprüfen Sie das Ausgabeergebnis.
#Überprüfen Sie die Anzahl der Zeilen
!wc -l ./neko.txt.cabocha
Ausgabe
297283 ./neko.txt.cabocha
#Überprüfen Sie die ersten 15 Zeilen
!head -15 ./neko.txt.cabocha
Ausgabe
* 0 -1D 0/0 0.000000
Ein Substantiv,Nummer,*,*,*,*,einer,Ichi,Ichi
EOS
EOS
* 0 2D 0/0 -0.764522
Symbol,Leer,*,*,*,*, , ,
* 1 2D 0/1 -0.764522
Mein Substantiv,Gleichbedeutend,Allgemeines,*,*,*,ich,Wagahai,Wagahai
Ist ein Assistent,Hilfe,*,*,*,*,Ist,C.,Beeindruckend
* 2 -1D 0/2 0.000000
Cat Nomen,Allgemeines,*,*,*,*,Katze,Katze,Katze
Mit Hilfsverb,*,*,*,Besondere,Kontinuierlicher Typ,Ist,De,De
Ein Hilfsverb,*,*,*,Fünf Schritte, La Linie Al,Grundform,Gibt es,Al,Al
.. Symbol,Phrase,*,*,*,*,。,。,。
EOS
Implementieren Sie die Klasse Morph, die die Morphologie darstellt. Diese Klasse hat eine Oberflächenform (Oberfläche), eine Basisform (Basis), ein Teilwort (pos) und eine Teilwortunterklassifikation 1 (pos1) als Elementvariablen. Lesen Sie außerdem das Analyseergebnis von CaboCha (neko.txt.cabocha), drücken Sie jeden Satz als Liste von Morph-Objekten aus und zeigen Sie die morphologische Elementzeichenfolge des dritten Satzes an.
class Morph:
def __init__(self, morph):
surface, attr = morph.split('\t')
attr = attr.split(',')
self.surface = surface
self.base = attr[6]
self.pos = attr[0]
self.pos1 = attr[1]
filename = './neko.txt.cabocha'
sentences = []
morphs = []
with open(filename, mode='r') as f:
for line in f:
if line[0] == '*': #Linien, die Abhängigkeitsbeziehungen darstellen: Überspringen
continue
elif line != 'EOS\n': #Außer am Ende des Satzes: Morph anwenden und zur Morphologieliste hinzufügen
morphs.append(Morph(line))
else: #Satzende: Morphologische Elementliste zur Satzliste hinzufügen
sentences.append(morphs)
morphs = []
#Bestätigung
for m in sentences[2]:
print(vars(m))
Ausgabe
{'surface': '\u3000', 'base': '\u3000', 'pos': 'Symbol', 'pos1': 'Leer'}
{'surface': 'ich', 'base': 'ich', 'pos': 'Substantiv', 'pos1': '代Substantiv'}
{'surface': 'Ist', 'base': 'Ist', 'pos': 'Partikel', 'pos1': '係Partikel'}
{'surface': 'Katze', 'base': 'Katze', 'pos': 'Substantiv', 'pos1': 'Allgemeines'}
{'surface': 'damit', 'base': 'Ist', 'pos': 'Hilfsverb', 'pos1': '*'}
{'surface': 'Gibt es', 'base': 'Gibt es', 'pos': 'Hilfsverb', 'pos1': '*'}
{'surface': '。', 'base': '。', 'pos': 'Symbol', 'pos1': 'Phrase'}
Implementieren Sie zusätzlich zu> 40 die Klauselklasse Chunk. Diese Klasse enthält eine Liste von Morph-Elementen (Morph-Objekten) (Morphs), eine Liste verwandter Klauselindexnummern (dst) und eine Liste verwandter ursprünglicher Klauselindexnummern (srcs) als Mitgliedsvariablen. Lesen Sie außerdem das Analyseergebnis von CaboCha des Eingabetextes, drücken Sie einen Satz als Liste von Chunk-Objekten aus und zeigen Sie die Zeichenfolge und den Kontakt der Phrase des achten Satzes an. Verwenden Sie für die restlichen Probleme in Kapitel 5 das hier erstellte Programm.
Ein Satz wird durch eine Liste von Satzobjekten dargestellt, ein Satzobjekt enthält eine Liste von Blockobjekten als Elemente und ein Klauselobjekt enthält eine Liste von Morphobjekten als Elemente. Zusätzlich zu der Klasse `Chunk``` von wird`
Satz implementiert. Beachten Sie, dass zum Erstellen einer Liste verwandter ursprünglicher Klauselindexnummern (`` `srcs
), die ein Element des`` Chunk```-Objekts ist, alle Klauselinformationen eines Satzes erforderlich sind, also ``
Satz``` Wird erstellt, wenn das Objekt initialisiert wird.
class Chunk():
def __init__(self, morphs, dst):
self.morphs = morphs
self.dst = dst
self.srcs = []
class Sentence():
def __init__(self, chunks):
self.chunks = chunks
for i, chunk in enumerate(self.chunks):
if chunk.dst != -1:
self.chunks[chunk.dst].srcs.append(i)
filename = './neko.txt.cabocha'
sentences = []
chunks = []
morphs = []
with open(filename, mode='r') as f:
for line in f:
if line[0] == '*': #Linien, die Abhängigkeitsbeziehungen darstellen: Wenden Sie Chunk auf die Informationen der vorherigen Phrase an und fügen Sie sie der Phrasenliste hinzu+Holen Sie sich den Kontakt der Phrase sofort danach
if len(morphs) > 0:
chunks.append(Chunk(morphs, dst))
morphs = []
dst = int(line.split(' ')[2].rstrip('D'))
elif line != 'EOS\n': #Außer am Ende des Satzes: Morph anwenden und zur Morphologieliste hinzufügen
morphs.append(Morph(line))
else: #Satzende: Chunk wird auf die Informationen der vorherigen Phrase angewendet und der Phrasenliste hinzugefügt.+Wenden Sie den Satz auf die Klauselliste an und fügen Sie ihn der Klauselliste hinzu
chunks.append(Chunk(morphs, dst))
sentences.append(Sentence(chunks))
morphs = []
chunks = []
dst = None
#Bestätigung
for chunk in sentences[7].chunks:
print([morph.surface for morph in chunk.morphs], chunk.dst, chunk.srcs)
Ausgabe
['ich', 'Ist'] 5 []
['Hier', 'damit'] 2 []
['Start', 'Hand'] 3 [1]
['Mensch', 'Das'] 4 [2]
['Ding', 'Zu'] 5 [3]
['Sie sehen', 'Ta', '。'] -1 [0, 4]
Extrahieren Sie den gesamten Text der ursprünglichen Klausel und der zugehörigen Klausel in tabulatorgetrenntem Format. Geben Sie jedoch keine Symbole wie Satzzeichen aus.
Danach wird, sofern nicht anders angegeben, die Ausgabe durch den 8. Satz wie in 41 bestätigt.
sentence = sentences[7]
for chunk in sentence.chunks:
if int(chunk.dst) != -1:
modifier = ''.join([morph.surface if morph.pos != 'Symbol' else '' for morph in chunk.morphs])
modifiee = ''.join([morph.surface if morph.pos != 'Symbol' else '' for morph in sentence.chunks[int(chunk.dst)].morphs])
print(modifier, modifiee, sep='\t')
Ausgabe
ich sah
Zum ersten Mal hier
Zum ersten Mal Mensch genannt
Menschen
ich habe etwas gesehen
Wenn sich Klauseln mit Nomenklatur auf Klauseln mit Verben beziehen, extrahieren Sie sie in tabulatorgetrennten Formaten. Geben Sie jedoch keine Symbole wie Satzzeichen aus.
sentence = sentences[7]
for chunk in sentence.chunks:
if int(chunk.dst) != -1:
modifier = ''.join([morph.surface if morph.pos != 'Symbol' else '' for morph in chunk.morphs])
modifier_pos = [morph.pos for morph in chunk.morphs]
modifiee = ''.join([morph.surface if morph.pos != 'Symbol' else '' for morph in sentence.chunks[int(chunk.dst)].morphs])
modifiee_pos = [morph.pos for morph in sentence.chunks[int(chunk.dst)].morphs]
if 'Substantiv' in modifier_pos and 'Verb' in modifiee_pos:
print(modifier, modifiee, sep='\t')
Ausgabe
ich sah
Zum ersten Mal hier
ich habe etwas gesehen
Visualisieren Sie den Abhängigkeitsbaum eines bestimmten Satzes als gerichteten Graphen. Zur Visualisierung ist es ratsam, den Abhängigkeitsbaum in die DOT-Sprache zu konvertieren und Graphviz zu verwenden. Verwenden Sie pydot, um gerichtete Diagramme direkt aus Python zu visualisieren.
Ein Graph wird erstellt, indem ein Paar von Klauseln der Quelle und des Ziels erstellt und an pydots `` `graph_from_edges``` übergeben wird. Da es nicht möglich ist zu unterscheiden, wann die Phrase derselben Zeichenfolge mehrmals in einem Satz mit der Oberflächenebene angezeigt wird, wird sie am Ende mit einer ID angezeigt.
#Installation der japanischen Anzeigeschrift
!apt install fonts-ipafont-gothic
import pydot
from IPython.display import Image,display_png
from graphviz import Digraph
sentence = sentences[7]
edges = []
for id, chunk in enumerate(sentence.chunks):
if int(chunk.dst) != -1:
modifier = ''.join([morph.surface if morph.pos != 'Symbol' else '' for morph in chunk.morphs] + ['(' + str(id) + ')'])
modifiee = ''.join([morph.surface if morph.pos != 'Symbol' else '' for morph in sentence.chunks[int(chunk.dst)].morphs] + ['(' + str(chunk.dst) + ')'])
edges.append([modifier, modifiee])
n = pydot.Node('node')
n.fontname = 'IPAGothic'
g = pydot.graph_from_edges(edges, directed=True)
g.add_node(n)
g.write_png('./ans44.png')
display_png(Image('./ans44.png'))
Ich möchte den diesmal verwendeten Satz als Korpus betrachten und die möglichen Fälle japanischer Prädikate untersuchen. Stellen Sie sich das Verb als Prädikat und das Hilfsverb der Phrase, die sich auf das Verb bezieht, als Fall vor und geben Sie das Prädikat und den Fall in einem durch Tabulatoren getrennten Format aus. Stellen Sie jedoch sicher, dass die Ausgabe den folgenden Spezifikationen entspricht.
Speichern Sie die Ausgabe dieses Programms in einer Datei und überprüfen Sie die folgenden Elemente mit UNIX-Befehlen.
with open('./ans45.txt', 'w') as f:
for sentence in sentences:
for chunk in sentence.chunks:
for morph in chunk.morphs:
if morph.pos == 'Verb': # chunkの左から順番にVerbを探す
cases = []
for src in chunk.srcs: #Suchen Sie nach einem Hilfsverb aus dem ursprünglichen Teil des gefundenen Verbs
cases = cases + [morph.surface for morph in sentence.chunks[src].morphs if morph.pos == 'Partikel']
if len(cases) > 0: #Wenn ein Hilfswort gefunden wird, wird es nach Deduplizierung und Ausgabe in Wörterbuchreihenfolge sortiert.
cases = sorted(list(set(cases)))
line = '{}\t{}'.format(morph.base, ' '.join(cases))
print(line, file=f)
break
#Bestätigung
!cat ./ans45.txt | sort | uniq -c | sort -nr | head -n 10
Ausgabe
2414
1395 Tsukuka
676
608
330 greifen
319 siehe
270 Ich denke
260
238 Deshalb
237
!cat ./ans45.txt | grep 'Machen' | sort | uniq -c | sort -nr | head -n 5
Ausgabe
1151
751
308
130
109
!cat ./ans45.txt | grep 'sehen' | sort | uniq -c | sort -nr | head -n 5
Ausgabe
344 Siehe
107 Siehe
35 zu sehen
27 Sehen
22 vom Sehen
!cat ./ans45.txt | grep 'geben' | sort | uniq -c | sort -nr | head -n 5
Ausgabe
5 geben
3 zu geben
3 zu geben
2 Gib einfach
1 nur zu geben
Ändern Sie das Programm> 45 und geben Sie den Begriff (die Klausel selbst, die sich auf das Prädikat bezieht) in tabulatorgetrenntem Format nach dem Prädikat und dem Fallmuster aus. Erfüllen Sie zusätzlich zu den 45 Spezifikationen die folgenden Spezifikationen.
with open('./ans46.txt', 'w') as f:
for sentence in sentences:
for chunk in sentence.chunks:
for morph in chunk.morphs:
if morph.pos == 'Verb': # chunkの左から順番にVerbを探す
cases = []
modi_chunks = []
for src in chunk.srcs: #Suchen Sie nach einem Hilfsverb aus dem ursprünglichen Teil des gefundenen Verbs
case = [morph.surface for morph in sentence.chunks[src].morphs if morph.pos == 'Partikel']
if len(case) > 0: #Für Chunks, die Hilfswörter enthalten, erhalten Sie die Hilfswörter und -begriffe
cases = cases + case
modi_chunks.append(''.join(morph.surface for morph in sentence.chunks[src].morphs if morph.pos != 'Symbol'))
if len(cases) > 0: #Wenn ein oder mehrere Hilfswörter gefunden werden, sortieren Sie sie nach der Deduplizierung in Wörterbuchreihenfolge und geben Sie sie zusammen mit den Begriffen aus.
cases = sorted(list(set(cases)))
line = '{}\t{}\t{}'.format(morph.base, ' '.join(cases), ' '.join(modi_chunks))
print(line, file=f)
break
#Bestätigung
!cat ./ans46.txt | head -n 10
Ausgabe
Wo man geboren wird
Ich habe keine Ahnung, ob es geboren wurde
Wo man weinen kann
Das einzige was ich geweint habe
Fang hier an
Sehen Sie, was ich sehe
Hör später zu
Fang uns
Kochen und fangen
Essen und kochen
Ich möchte nur auf den Fall achten, in dem das Verb wo case eine Sa-hen-Verbindungsnomenklatur enthält. Ändern Sie 46 Programme, um die folgenden Spezifikationen zu erfüllen.
――Nur wenn der Ausdruck "Sahen-Verbindungsnomen + (Hilfsverb)" mit dem Verb zusammenhängt Das Prädikat lautet "Sahen-Verbindungsnomen + ist die Grundform von + Verb", und wenn eine Phrase mehrere Verben enthält, wird das Verb ganz links verwendet.
Speichern Sie die Ausgabe dieses Programms in einer Datei und überprüfen Sie die folgenden Elemente mit UNIX-Befehlen.
--Predikate, die häufig im Korpus vorkommen (Sahen-Verbindungsnomenklatur + + Verb) --Predikate und Verbmuster, die häufig im Korpus vorkommen
with open('./ans47.txt', 'w') as f:
for sentence in sentences:
for chunk in sentence.chunks:
for morph in chunk.morphs:
if morph.pos == 'Verb': # chunkの左から順番にVerbを探す
for i, src in enumerate(chunk.srcs): #Der ursprüngliche Teil des Verbs, das ich gefunden habe, ist "Sahen Verbindungsnomen"+Überprüfen Sie, ob es besteht
if len(sentence.chunks[src].morphs) == 2 and sentence.chunks[src].morphs[0].pos1 == 'Verbindung ändern' and sentence.chunks[src].morphs[1].surface == 'Zu':
predicate = ''.join([sentence.chunks[src].morphs[0].surface, sentence.chunks[src].morphs[1].surface, morph.base])
cases = []
modi_chunks = []
for src_r in chunk.srcs[:i] + chunk.srcs[i + 1:]: #Suchen Sie nach Hilfswörtern aus den verbleibenden Stücken
case = [morph.surface for morph in sentence.chunks[src_r].morphs if morph.pos == 'Partikel']
if len(case) > 0: #Für Chunks, die Hilfswörter enthalten, erhalten Sie die Hilfswörter und -begriffe
cases = cases + case
modi_chunks.append(''.join(morph.surface for morph in sentence.chunks[src_r].morphs if morph.pos != 'Symbol'))
if len(cases) > 0: #Wenn ein oder mehrere Hilfswörter gefunden werden, sortieren Sie sie nach der Deduplizierung in Wörterbuchreihenfolge und geben Sie sie zusammen mit den Begriffen aus.
cases = sorted(list(set(cases)))
line = '{}\t{}\t{}'.format(predicate, ' '.join(cases), ' '.join(modi_chunks))
print(line, file=f)
break
#Bestätigung
!cat ./ans47.txt | cut -f 1 | sort | uniq -c | sort -nr | head -n 10
Ausgabe
29 Antwort
21 Sag Hallo
18 reden
9 Stellen Sie eine Frage
8 Machen Sie ein Nickerchen
8 Streit
7 imitieren
7 Stellen Sie Fragen
6 Konsultieren Sie
5 Stellen Sie eine Frage
!cat ./ans47.txt | cut -f 1,2 | sort | uniq -c | sort -nr | head -n 10
Ausgabe
8 Ich werde antworten
8 Antworten
6 zu reden
6 zu reden
6 Sag Hallo
5 Ich mache ein Nickerchen
5 Ich werde Hallo sagen
5 Um Hallo zu sagen
5 In einem Streit
4 Antworten auf
Extrahieren Sie für eine Klausel, die die gesamte Nomenklatur des Satzes enthält, den Pfad von dieser Klausel zum Stamm des Syntaxbaums. Der Pfad im Syntaxbaum muss jedoch die folgenden Spezifikationen erfüllen.
sentence = sentences[7]
for chunk in sentence.chunks:
if 'Substantiv' in [morph.pos for morph in chunk.morphs]: # chunkがSubstantivを含むか確認
path = [''.join(morph.surface for morph in chunk.morphs if morph.pos != 'Symbol')]
while chunk.dst != -1: #Fügen Sie der Liste einen Block hinzu, indem Sie dst bis zur Wurzel verfolgen, beginnend mit dem Block, der die Nomenklatur enthält.
path.append(''.join(morph.surface for morph in sentence.chunks[chunk.dst].morphs if morph.pos != 'Symbol'))
chunk = sentence.chunks[chunk.dst]
print(' -> '.join(path))
Ausgabe
ich bin->sah
Hier->Beginnen mit->Mensch->Dinge->sah
Mensch->Dinge->sah
Dinge->sah
Extrahieren Sie den kürzesten Abhängigkeitspfad, der alle Nomenklaturpaare im Satz verbindet. Wenn jedoch die Klauselnummern des Nomenklaturpaars $ i $ und $ j $ ($ i $ <$ j $) sind, muss der Abhängigkeitspfad die folgenden Spezifikationen erfüllen.
Darüber hinaus kann die Form des Abhängigkeitspfads auf zwei Arten betrachtet werden.
--Wenn sich Klausel $ j $ auf dem Pfad von Klausel $ i $ zum Stamm des Syntaxbaums befindet: Zeigen Sie den Pfad von Klausel $ i $ zu Klausel $ j $ an
Zum Beispiel
-- i-> a-> b-> j-> Wenn root` ``, dann `` `i-> a-> b-> j
i -> a -> k ->Wurzel
、j -> b -> k ->Wurzel
Wenn,i -> a | j -> b | k
Dann sollte die Nomenklatur von $ i $ und $ j $ in X bzw. Y konvertiert und angezeigt werden.
from itertools import combinations
sentence = sentences[7]
nouns = []
for i, chunk in enumerate(sentence.chunks):
if 'Substantiv' in [morph.pos for morph in chunk.morphs]: # Substantivを含む文節を抽出
nouns.append(i)
for i, j in combinations(nouns, 2): #Erstellen Sie einen Pfad für jedes Klauselpaar, das die Nomenklatur enthält
path_i = []
path_j = []
while i != j: # i,Folgen Sie dst in der Reihenfolge, bis j dieselbe Klausel erreicht
if i < j:
path_i.append(i)
i = sentence.chunks[i].dst
else:
path_j.append(j)
j = sentence.chunks[j].dst
if len(path_j) == 0: #Erster Fall
chunk_X = ''.join([morph.surface if morph.pos != 'Substantiv' else 'X' for morph in sentence.chunks[path_i[0]].morphs])
chunk_Y = ''.join([morph.surface if morph.pos != 'Substantiv' else 'Y' for morph in sentence.chunks[i].morphs])
path_XtoY = [chunk_X] + [''.join(morph.surface for morph in sentence.chunks[n].morphs) for n in path_i[1:]] + [chunk_Y]
print(' -> '.join(path_XtoY))
else: #Zweiter Fall
chunk_X = ''.join([morph.surface if morph.pos != 'Substantiv' else 'X' for morph in sentence.chunks[path_i[0]].morphs])
chunk_Y = ''.join([morph.surface if morph.pos != 'Substantiv' else 'Y' for morph in sentence.chunks[path_j[0]].morphs])
chunk_k = ''.join([morph.surface for morph in sentence.chunks[i].morphs])
path_X = [chunk_X] + [''.join(morph.surface for morph in sentence.chunks[n].morphs) for n in path_i[1:]]
path_Y = [chunk_Y] + [''.join(morph.surface for morph in sentence.chunks[n].morphs) for n in path_j[1:]]
print(' | '.join([' -> '.join(path_X), ' -> '.join(path_Y), chunk_k]))
Ausgabe
X ist|In Y.->Beginnen mit->Mensch->Dinge|sah.
X ist|Genannt Y.->Dinge|sah.
X ist|Y.|sah.
In X.->Beginnen mit->Genannt Y.
In X.->Beginnen mit->Mensch->Y.
X genannt->Y.
Sprachverarbeitung 100 Klopfen sind so konzipiert, dass Sie nicht nur die Verarbeitung natürlicher Sprache selbst lernen können, sondern auch die grundlegende Datenverarbeitung und das allgemeine maschinelle Lernen. Sogar diejenigen, die maschinelles Lernen in Online-Kursen studieren, können sehr gute Ergebnisse erzielen. Probieren Sie es also bitte aus.
Recommended Posts