Hallo, ich habe ein Array aus etwa 100 Zahlen. Zu jedem Datensatz habe ich einen Wert ja/nein. Aktuell habe ich 10.000 solcher Datensätze, wobei nur etwa 500 den Fall nein liefern, 9500 den Fall ja. Ich möchte nun mit einem Classifier lernen und versuchen, bei einem neuen Datensatz ja/nein "vorauszusagen". Hat jemand so etwas schon mal gemacht? Ich habe C/C++ zur Verfügung, aber mittlerweile auch mal Python installiert. Betriebssystem ist mir egal, Windows oder Linux. Erste Schritte mit pyTorch/scikit-learn, bin mir aber aktuell weder sicher, ob ich in die richtige Richtung forsche, noch ob mein obiges Problem eine Chance hat, damit (oder überhaupt) gelöst zu werden... Freue mich auf Feedback! Schöne Grüße, Marie
:
Verschoben durch Admin
Beispiel, was vielleicht als Start passen könnte: https://pythonbasics.org/machine-learning-classifier/
:
Bearbeitet durch User
Für Ja/nein würde ich mit einer SVM oder einem decision tree anfangen. Das reicht für sowas üblicherweise und man kann auch noch gut nachvollziehen, was da passiert. Dafür gibt es auch genug Tutorials...
Ich kann Deep Learning Studio empfehlen um sowas schnell mal auszuprobieren. Einfach mal 200 Samples aus beiden Kategorien gegen ein 1-3 FC-Layer tiefes NN werfen und schauen ob was sinnvolles dabei rauskommt.
Ich hänge leider immer noch fest und weiß noch nicht so genau, wo ich anfangen soll... Ich hab es mittlerweile geschafft, dass ich eine *.csv Datei einlesen kann. Ich habe außerdem ein Beispiel gefunden, welches SGD (=Stochastic Gradient Descent) verwendet. Zum einen hab ich die Funktionsweise des Beispiels noch nicht verstanden, zum anderen weiß ich nicht, wie ich meine eingelesenen Dateien so umwandeln kann, dass diese für SGD verwendet werden können. Meine CSV haben folgenden Aufbau: Comment,yes-144/no-144,...100 Zahlen... als z.B. PartialSolution-0,yes-144,211,1652,1861,... Ich kann die Eingangsdaten beliebig umformatieren. Comment kann man ignorieren. yes-144 oder no-144 ist das Ergebnis des Classifiers. Ich möchte dieses aus den 100 gegebenen Zahlen herausfinden. Was ist X und Y im Beispiel genau? X meine Eingabe-Daten? Y meine Ausgabe-Daten? Ich kann yes-144/no-144 ohne Probleme auf 0/1 umformatieren, wenn es etwas hilft. Wie findet die Zuordnung von den Eingabedaten auf die Ausgabedaten statt? Brauche ich randperm und perm, weil ich ja eigentlich keinen Zufall haben will, sondern ganz gezielt auf meinen Eingabedaten arbeiten will?
1 | # -*- coding: utf-8 -*- |
2 | |
3 | import argparse |
4 | |
5 | import numpy as np |
6 | import torch |
7 | import torch.nn as nn |
8 | import torch.optim as optim |
9 | |
10 | from numpy import genfromtxt |
11 | |
12 | # https://numpy.org/doc/stable/reference/generated/numpy.loadtxt.html |
13 | # https://stackoverflow.com/questions/3518778/how-do-i-read-csv-data-into-a-record-array-in-numpy |
14 | # https://gist.github.com/blaylockbk/55b5b98269a4f1a413f6b4e676261fa6 |
15 | # https://pytorch.org/docs/stable/optim.html |
16 | # https://pytorch.org/docs/stable/nn.html |
17 | |
18 | # print(my_data2[0][1]) |
19 | |
20 | if __name__ == "__main__": |
21 | parser = argparse.ArgumentParser() |
22 | # parser.add_argument("--c", type=float, default=0.01) |
23 | parser.add_argument("--lr", type=float, default=0.1) |
24 | # parser.add_argument("--batchsize", type=int, default=5) |
25 | parser.add_argument("--epoch", type=int, default=10) |
26 | parser.add_argument("--device", default="cuda", choices=["cpu", "cuda"]) |
27 | args = parser.parse_args() |
28 | args.device = torch.device(args.device if torch.cuda.is_available() else "cpu") |
29 | |
30 | print(args) |
31 | |
32 | my_data2 = genfromtxt('test.csv',delimiter=',', dtype=None, encoding='UTF-8') |
33 | |
34 | // Hier fehlt noch etwas!!! |
35 | |
36 | X = [2,4,7,9,11] |
37 | Y = [0,1] |
38 | |
39 | batchsize = 5 |
40 | c = 0.01 |
41 | |
42 | # X = (X - X.mean()) / X.std() |
43 | # Y[np.where(Y == 0)] = -1 |
44 | |
45 | # 2 scheint die Groesse des Output-Vektors zu sein |
46 | # 2 muss mit Groesse Y uebereinstimmen |
47 | model = nn.Linear(2, 1) |
48 | # model = nn.Linear(3, 1) |
49 | model.to(args.device) |
50 | |
51 | # train(X, Y, model, args) |
52 | # visualize(X, Y, model) |
53 | |
54 | X = torch.FloatTensor(X) |
55 | Y = torch.FloatTensor(Y) |
56 | N = len(Y) |
57 | |
58 | # SGD = Stochastic Gradient Descent |
59 | optimizer = optim.SGD(model.parameters(), lr=args.lr) |
60 | |
61 | model.train() |
62 | for epoch in range(args.epoch): |
63 | perm = torch.randperm(N) |
64 | sum_loss = 0 |
65 | |
66 | for i in range(0, N, batchsize): |
67 | x = X[perm[i : i + batchsize]].to(args.device) |
68 | y = Y[perm[i : i + batchsize]].to(args.device) |
69 | |
70 | optimizer.zero_grad() |
71 | output = model(x).squeeze() |
72 | weight = model.weight.squeeze() |
73 | |
74 | loss = torch.mean(torch.clamp(1 - y * output, min=0)) |
75 | loss += c * (weight.t() @ weight) / 2.0 |
76 | |
77 | loss.backward() |
78 | optimizer.step() |
79 | |
80 | sum_loss += float(loss) |
81 | |
82 | print("Epoch: {:4d}\tloss: {}".format(epoch, sum_loss / N)) |
:
Bearbeitet durch User
was schrieb: > Ich kann Deep Learning Studio empfehlen um sowas schnell mal > auszuprobieren. Deep Learning Studio hat mir leider nicht geholfen. Scheinbar gehen Bilder als Eingabedaten, der Support konnte mir aber auch nach Wochen des Wartens nicht so richtig erklären, wie man Zahlen einfüttern kann.
Marie M. schrieb: > der Support konnte mir aber auch nach Wochen > des Wartens nicht so richtig erklären, wie man Zahlen einfüttern kann. Na, bei Freeware kann man keinen guten Support erwarten. Braucht man aber auch nicht. Dein Problem verstehe ich aber nicht. Marie M. schrieb: > Deep Learning Studio hat mir leider nicht geholfen. Scheinbar gehen > Bilder als Eingabedaten, Schau dir ein(e) Tutorial(-reihe) dazu an, neben "Image" gibt es als Data Type da natürlich auch z.B. "numeric" oder "categorical"
Die Aufggabe läßt sich am Einfachsten mit python, pandas und scikit-learn oder, falls Du es grafisch haben möchtest, mit KNIME (oder RapidMiner, den kenne ich aber nicht) lösen. Damit wir Dir hier weiter helfen können, solltest Du uns zuerst mal Deine Eingabedaten genauer beschreiben. Am Besten, falls das möglich ist, eine csv Datei mal an einen Post anhängen. Wie von Vorpostern schon gesagt, ist Logistische Regression oder ein Entscheidungsbaum/Random Forest, ein guter Start. Neuronale Netze und svc würde ich erst mal außen vor lassen. Dazu sind Deine Klassen zu ungleichmäßig verteilt und Du müsstest mehr Aufwand in die Datenaufbereitung stecken, damit das gut funktioniert. Torch und Keras sind für Dein Problem overkill. Du musst erst mal vernünftig aufbereitete Daten für einen Test/Trainingsdatensatz bekommen.
Ingo E. schrieb: > Damit wir Dir hier weiter helfen können, solltest Du uns zuerst mal > Deine Eingabedaten genauer beschreiben. Ich denke auch, man muß wissen, was an den Zahlen das Kriterium ist. Software ist nämlich strunzdumm. Z.B. sollte mal ein Algorithmus auf Fotos erkennen, was ein Schiff ist. Die Ergebnisse waren sehr ungenau. Eine Analyse ergab dann, der Algorithmus hatte danach gefiltert, ob das Objekt sich auf Wasser befindet.
Testdaten können hier abgerufen werden: http://guest.engelschall.com/~martin/e2_partial_field_100_and_3_fields_filled.html Wenn das Format der Testdaten so nicht passend ist, kann ich diese auch in einem beliebig anderen Format zur Verfügung stellen. Ich hab bisher keine Ahnung, ob man aus den Zahlen etwas herauslesen kann. Ich kann es aktuell nicht und möchte daher einen Versuch starten.
:
Bearbeitet durch User
Peter D. schrieb: > Eine Analyse ergab dann, der Algorithmus hatte > danach gefiltert, ob das Objekt sich auf Wasser befindet. Angeblich wollte mal jemand eine Bilderkennung trainieren, russische Panzer von Panzern der USA zu unterscheiden. Das Ergebnis war eine Bilderkennung, die dreckige von sauberen Panzern unterscheiden konnte, weil in den USA darauf geachtet wurde, dass die Panzer sauber sind, während das den Russen egal war. Nachgeprüft habe ich die Geschichte aber nicht. Kurz: Es kommt auf die Trainingsdaten an. Die müssen passen. Deshalb nimmt man oft einen Teil der Daten für das Training und einen anderen Teil zur Überprüfung. Das kommt aber erst, wenn man es erstmal geschafft hat, ein trainingsfähiges System aufzubauen
Marie M. schrieb: > Testdaten können hier abgerufen werden: > > http://guest.engelschall.com/~martin/e2_partial_field_100_and_3_fields_filled.html > > Wenn das Format der Testdaten so nicht passend ist, > kann ich diese auch in einem beliebig anderen Format zur Verfügung > stellen. > > Ich hab bisher keine Ahnung, ob man aus den Zahlen etwas herauslesen > kann. Ich kann es aktuell nicht und möchte daher einen Versuch starten. Um was für Daten handelt es sich denn fachlich? Also woraus bestehen die 100 Dimensionen, sind das Messwerte, oder ... ?
Ingo E. schrieb: > Um was für Daten handelt es sich denn fachlich? Also woraus bestehen die > 100 Dimensionen, sind das Messwerte, oder ... ? Ich lass einen Backtracker laufen. Dieser geht mal mehr, mal weniger weit in die Tiefe. Bei diesen Daten max. bis 144. Der Vorgang/jeder Versuch dauert recht lange. Ich ermittle, welche Tiefe maximal erreicht wird. In meinem Fall prüfe ich nur 100 und 144. Die 100 Dimensionen sind die ersten 100 Wege, die der Backtracker auswählt. Ziel wäre es, die 144 möglichst schnell und oft zu erreichen. Ich würde gerne bei gefundenem Start (100 Wege dann festgelegt) entscheiden, ob es sich rentieren könnte, zu versuchen, auf 144 zu kommen oder ob es eher unwahrscheinlich ist. Ich kann beliebig viele Trainings- und Testdaten erzeugen, dauert bloss jeder Eintrag seine Zeit. Wenn 100 viel zu viel sind, kann ich auch weiter reduzieren oder auch erhöhen. Es geht mir aktuell mehr um das Prinzip, wie so etwas gehen würde und ob überhaupt Erfolgsaussichten bestehen.
:
Bearbeitet durch User
Bedeutet > Ich lass einen Backtracker laufen. Dieser geht mal mehr, mal weniger > weit in die Tiefe. Bei diesen Daten max. bis 144. Der Vorgang/jeder > Versuch dauert recht lange. Ich ermittle, welche Tiefe maximal erreicht > wird. In meinem Fall prüfe ich nur 100 und 144. Die 100 Dimensionen sind > die ersten 100 Wege, die der Backtracker auswählt. und das, > PartialSolution-0,yes-144,211,1652,1861,... dass die Werte x_0, ..., x_99 jeweils die Bewertungen eines Zustandes sind? Also z.B. wie ein Backtracker beim Schach, der jeweils eine Position bewertet und dann den jeweils besten Zug aus dem Zugbaum auswertet? Was ist dann das Kriterium für ja/nein. Ist das eine Funktion der Werte oder wie ergibt sich das?
Ja, ich glaube, der Vergleich mit Schach ist gut. Oder vielleicht auch Sudoku? x_0=211 x_1=1652 usw. 211 gibt an, das ich eine bestimmte Figur (Schach) oder Zahl (Sudoku) auf ein bestimmtes Feld setze. Beim Sudoku gibt es Kombinationen, die vielleicht nicht mehr weitergehen, nicht zu einem kompletten Feld führen, weil ich davor schon eine Kombination an Zahlen gesetzt habe, die zum Ausschluss führen. Das yes-144 oder no-144 bedeutet, dass ich eine bestimmte Tiefe erreiche, also z.B. beim Sudoku es schaffe 70 bestimmte vorgegebene Felder zu füllen. Wenn ich 81 Felder füllen würde, und alle Sudoku Regeln eingehalten werden würden, wäre das Sudoku gelöst. Ich möchte versuchen, feststellen, ob es überhaupt möglich ist, dass ich z.B. 35 Felder fülle und dann anhand der Zahlen irgendwie erkennen kann, ob ich bis auf 70 hochkomme. Ich habe so meine Zweifel, dass es geht, würde aber das Prinzip gerne ausprobieren. (d.h. bei diesem Beispiel Dimension 35, yes-70 und no-70) -> Wenn bei 35 zu testenden Feldern no-70 rauskommt, dann kann ich damit auch kein volles Sudoku-Feld füllen. D.h. ich kann dem Backtracker mitteilen, er soll sich 35 andere Felder suchen.
:
Bearbeitet durch User
Wenn man seine eigene Aufgabe nicht im Griff hat, ist es nicht zielführend zu versuchen diese für andere weiter zu abstrahieren. Erklär doch einfach, was du machst. Nein, "Ich habe einen Backtracker" erklärt es nicht.
Qwertz: Welche Details kann ich dir zusätzlich geben, dass du (und auch andere) es besser verstehen können? Wenn man immer wieder über einem Problem grübelt, dann kommen einem bestimmte Sachen als selbstverständlich vor. Jemand anders braucht aber trotzdem diese Info. Stell dir ein Sudoku vor. Dies mal als Beispiel oberste linke Ecke. (Ein Neuntel des gesamten Feldes eines "normalen" Sudokus dargestellt) F11 F12 F13 ... F14 F15 F16 ... F17 F18 F19 ... . . . Backtracker: Beginnt mit Feld F11. Setz dort z.B. die Zahl 1 rein. Geht dann weiter auf F12. Setz dort wieder die Zahl 1 rein. Merkt, dass die Zahl 1 schon benutzt wurde, nimmt die 1 wieder raus und setzt nächste Möglichkeit rein. Es ist die Zahl 2. Die Zahl 2 passt, also weiter auf Feld F13. usw. usf. Ich weiß, dass es Optimierungen gibt und auch andere Methoden, Sudoku zu lösen, aber hier geht es nur um das Prinzip, um die Ausgangsdaten und das Umfeld meiner Frage zu verstehen. Ich würde mir vorstellen, dass die Aufgabe des Classifier wäre, dem Backtracker zu helfen, früher die gerade laufende Tiefensuche abzubrechen. Er bekommt als Eingabedaten 1,2,3,4,5,6,7,8,9 und soll dann entscheiden, ob es Sinn macht, mit dieser Belegung tiefer zu suchen. Ich vermute, dass diese Belegung mit nur 9 Zahlen die Suche zu wenig einschränkt, aber vielleicht reichen z.B. 4x4=16 oder 5x5=25 Zahlen? Es gibt dann mehr Regeln, die gebrochen werden können und eine Lösung verhindern. Die Regeln legen aber das Problem "Sudoku" fest. D.h. der Classifier muss sich mindestens erst einmal diese Regeln einverleiben. Und dann ein paar interessante Regeln mehr (auf die ich scharf wäre). Ob dies geht?
:
Bearbeitet durch User
Marie M. schrieb: > Stell dir ein Sudoku vor. Geht es denn nun wirklich um ein Sudoku, oder ist das nur eine Analogie, die du für sinnvoll hältst?
Es ist eine Analogie, weil Sudoku einfach zu verstehen ist und viele Sudoku kennen. Wenn ich mein Problem erklären würde, wäre die Erklärung viel länger, aber das Prinzip ist das Gleiche dahinter. Selbst für mich selbst ist Sudoku einfacher zu verstehen, da etwas kleiner und übersichtlicher.
Marie M. schrieb: > Wenn ich mein Problem erklären würde, > wäre die Erklärung viel länger, aber das Prinzip ist das Gleiche > dahinter. Da liegt der Hase im Pfeffer. Du verstehst deine eigentliche Aufgabe nicht, meinst aber einschätzen zu können, was eine ähnliche Aufgabe sein könnte. Das geht grundsätzlich schief. Also entweder du rückst mit dem eigentlichen Problem raus und zwar ohne gutgemeinte Vereinfachungen, Analogien, Abstraktionen und sonstigem Blödsinn, oder wir können nur weiter an einem fiktivem Problem rumraten, das überhaupt nichts zur Sache tut. - Was ist dein Anwendungsfall - Was sind deine Werkzeuge - Was ist dein Ziel - Wie sehen deine Daten aus
was schrieb: > - Was ist dein Anwendungsfall https://en.wikipedia.org/wiki/Eternity_II_puzzle > - Was sind deine Werkzeuge Ein Backtracker > - Was ist dein Ziel Ein Lösung (schneller) zu finden, als es derzeit braucht. > - Wie sehen deine Daten aus Siehe Link auf Datei weiter oben
Du willst also eine AI, die du zeilenweise mit Puzzlestücken fütterst und die dir sagt, ob es mit der bisher geprüften Reihenfolge noch möglich ist das Puzzle zu lösen, oder nicht. Korrekt? Was ist denn überhaupt die Bedeutung der Zahlen in den Testdaten und was ist die Bedeutung des Ergebnisses yes/no in diesen?
was schrieb: > Du willst also eine AI, die du zeilenweise mit Puzzlestücken fütterst > und die dir sagt, ob es mit der bisher geprüften Reihenfolge noch > möglich ist das Puzzle zu lösen, oder nicht. > > Korrekt? Ja, ich denke, dies ist korrekt!
Zu den Zahlen: Ich habe mir vor langer Zeit eine Codierung überlegt und benutze diese fix in allen von mir entwickelten Programmen: Zahl 1 bedeutet Karte 1 auf Feld 1 setzen. Es gibt hier keine Rotation. Zahl 2 bedeutet Karte 2 auf Feld 1 setzen. Es gibt hier keine Rotation. Zahl 3 bedeutet Karte 3 auf Feld 1 setzen. Es gibt hier keine Rotation. Zahl 4 bedeutet Karte 4 auf Feld 1 setzen. Es gibt hier keine Rotation. (Karte 1 bis 4 sind Ecken. Feld 1 ist die Ecke oben links. Der Rand ist grau, drum kann ich Karten auf Ecken und Kanten nicht rotieren.) usw. Meine Zahlen (die auch in den Daten enthalten sind, die ich dem Classifier geben würde) gehen bis 130180. Es kann nur eine Zahl zwischen 1 und 4 in der Lösung vorkommen, weil ich nicht 2 Karten auf 1 Feld setzen kann. Um es noch kurz fortzusetzen: Zahl 5 bedeutet, Karte 5 auf Feld 2 zu setzen. Dies ist das Feld rechts neben der Ecke. Karte 1 bis 4 sind Ecken, passen nur auf Ecken. Karten 5 bis 60 sind Randteile, passen nur auf den Rand. Auch bei Randteilen gibt es keine Rotation. Ab Zahl 38 beginnt das Feld 3. (Anmerkung: Warum kommen nicht alle Karten vor, also warum ist Zahl 38 und nicht irgendwo bei 60? Weil es noch bis zu 5 vorgegebene/fest verbaute Karten gibt. Und einige Möglichkeiten schon als nicht möglich ermittelt wurden.) Die Zahlen 130177,130178,130179,130180 sind für die Ecke unten rechts. Jeweils dort sind wieder Karten 1 bis 4 möglich, die wir oben schon gesehen haben. Wenn der Classifier jetzt mit diesen Zahlen nichts anfangen kann, kann ich auch ohne Problem F1C1R0 (Feld 1, Card 1, Rotation 0) als Input generieren. Da fehlt mir aber aktuell die Info, was ein guter Input ist. Ebenso interessant: Wenn ich zu wenig Zahlen/gefüllte Felder einfüttere, vermute ich, dass der Classifier nichts klassifizieren kann. Vermute, dass er dann nur schlechte Ergebnisse liefert, nicht lernt. Wenn ich dann mehr Zahlen (Dimensionen) einfüttere stelle ich mir vor, dass der Classifier besser lernen kann. Aber der Aufwand wächst, weil er mehr Dimensionen verarbeiten muss.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.