TypeError mit Array

mit matplotlib, NumPy, pandas, SciPy, SymPy und weiteren mathematischen Programmbibliotheken.
Antworten
doerflia
User
Beiträge: 20
Registriert: Freitag 3. Mai 2019, 14:49

Hi,

ich bin gerade am Schreiben meiner Master-Arbeit und befasse mich das erste Mal mit Neuronalen Netzen und Python.
Das ganze Konzept steht, Daten sind außerdem selbst aufbereitet und selbst gelabelt.
Im Code habe ich aber ein paar Fehler drin...

Aus einer DB werden die Daten in das Projekt geladen (in Liste "data_storage" gespeichert) und
der Datensatz anschließend in eine Liste "Input" (eine Liste mit allen Datensätzen für die Trainingsmerkmale)
und eine Liste "Output" (eine Liste mit allen Datensätzen für die Klasse) getrennt.

Diese Liste soll nun mit der Kreuzvalidierung gesplittet und sortiert werden.

Code: Alles auswählen

# for seperation of data_storage
Input, Output = list(), list()

# list all results of k-fold cross-validation
scores, members, matrix = list(), list(), list()

# seperate data_storage in Input and Output data
for items in data_storage:
    # Link_ID = items[0] # identifier not needed
    Input.append([items[1], items[2], items[3], items[4], items[5], items[6], items[7], items[8], items[9]]) # Input: all characteristics
    Output.append(items[10]) # Output: scenario_class 1 to 8

# normalize Data
Input = normalize(Input)
# Output = normalize(Output) not needed; categorical number

# prepare k-fold cross-validation
kfold = StratifiedKFold(n_splits=15, random_state=1, shuffle=True)

for train_ix, test_ix in kfold.split(Input, Output):
    # select samples
[b] Train, Target_Train = Input[train_ix], Output[train_ix]
    Test, Target_Test = Input[test_ix], Output[test_ix][/b]
Der Fehler tritt in den fettgedruckten Zeilen auf:

Code: Alles auswählen

TypeError: only integer scalar arrays can be converted to a scalar index
Fehlermeldung habe ich verstanden, aber eine Lösung für mein Problem habe ich nicht.
Die Fehlermeldung würde bedeuten, dass ich nur ein Merkmal in die Liste Input packe darf,
z. B. durch

Code: Alles auswählen

for items in data_storage:
    # Link_ID = items[0] # identifier not needed
    Input.append(items[1])
Ich will pro Listeneintrag aber alle Merkmale, also bei i Datensätzen i Zeilen in folgender Darstellung haben:

Code: Alles auswählen

Input(i)                    |   Output(i)
---------------------------------------------
(item[1] ... item[9])   |   item[10]
(item[1] ... item[9])   |   item[10]
(item[1] ... item[9])   |   item[10]
Lasse ich die geschweiften Klammern im input.append()-Methode weg, also
for items in data_storage:

Code: Alles auswählen

    # Link_ID = items[0] # identifier not needed
    Input.append(items[1], items[2], items[3], items[4], items[5], items[6], items[7], items[8], items[9]) # Input: all characteristics
erhalte ich ebenfalls einen Fehler:

Code: Alles auswählen

TypeError: append() takes exactly one argument (9 given)
Hat jemand eine Idee, wie ich die Einteilung Training:Testdaten für die Kreuzvalidierung hinbekomme?
Also wie ich die Listen/Arrays "Input" und "Output" richtig erzeugen kann?


Vielen Dank!
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@doerflia: Das tritt nicht in *den* fettgedrückten Zeilen auf, sondern sicher nur in einer von den beiden – in welcher? In solchen fällen am besten immer einfach den gesamten Traceback zeigen und nicht nur die letzte Zeile.

Hast Du die Fehlermeldung tatsächlich verstanden? Zeig doch mal `Input` und `train_ix` und `test_ix`, je nach dem in welcher der beiden Zeilen die Ausnahme tatsächlich auftritt, und erkläre mal was Du da statt der Ausnahme als Ergebnis erwartet hättest, und warum.

Geschweifte Klammern sind übrigens die hier: ``{`` und ``}``. Du meinst eckige Klammern ``[`` und ``]``. Und natürlich bekommst Du eine Ausnahme wenn Du `append()` mit mehr als einem Argument aufrufst. Das sollte aus der Dokumentation eigentlich klar sein, dass `append()` nur ein Argument erwartet. Wenn Du eine Liste um mehrere Elemente aus einem iterierbaren Objekt erweitern willst, dann nimm die `extend()`-Methode. Und bitte nicht eine Liste erstellen in dem Du Elemente einer anderen Sequenz da explizit mit aufsteigenden, zusammenhängenden Indizes hin schreibst. Dafür gibt es „slicing“:

Code: Alles auswählen

    inputs.append(items[1:10])
Oder `extend()`, je nach dem ob das als 1 Element oder als 9 Elemente hinzugefügt werden soll.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
doerflia
User
Beiträge: 20
Registriert: Freitag 3. Mai 2019, 14:49

Dann in der oberen. Klammere ich diese aus, in der unteren :D

Der Komplette Traceback:

Code: Alles auswählen

 File "C:/Workspace/Master-Thesis/Programm/MapValidationML/ml_neuronal_network_1.py", line 56, in <module>
    Input.append(items[1], items[2], items[3], items[4], items[5], items[6], items[7], items[8], items[9]) # Input: all characteristics

TypeError: append() takes exactly one argument (9 given)
doerflia
User
Beiträge: 20
Registriert: Freitag 3. Mai 2019, 14:49

Oder diese Meldung, wenn ich mit [ ] arbeite

Code: Alles auswählen


  File "C:/Workspace/Master-Thesis/Programm/MapValidationML/ml_neuronal_network_1.py", line 68, in <module>
    Train, Target_Train = Input[train_ix], Output[train_ix]

TypeError: only integer scalar arrays can be converted to a scalar index
Benutzeravatar
__blackjack__
User
Beiträge: 13004
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@doerflia: Wie gesagt, ich denke Du hast die Fehlermeldung nicht verstanden. Also noch mal: wie sieht `Input`/`Output` aus, wie `train_ix`, und was hättest Du da als Ergebnis erwartet. Und Du hättest das Problem auch selbst noch ein kleines bisschen enger fassen können, denn in der Zeile sind *zwei* Indexzugriffe. Welcher davon löst denn die Ausnahme aus? Der erste, der zweite, oder würden es gar beide tun?

Der komplette Traceback fängt übrigens beim Wort „Traceback“ an.
“Most people find the concept of programming obvious, but the doing impossible.” — Alan J. Perlis
doerflia
User
Beiträge: 20
Registriert: Freitag 3. Mai 2019, 14:49

Naja ich habe die Fehlermeldung schon verstanden, aber keine Lösung für mein Problem.

Erwartet wird, dass ich eine Menge von Zahlen z. B. [0, 0.2, 0.7, 0.9] übergebe und nicht ein Array dieser Mengen z. B. ([0, 0.2, 0.7, 0.9] , [0, 0.2, 0.7, 0.9] , [0, 0.2, 0.7, 0.9] ).
Aber genau das möchte ich machen.

Jede dieser Menge ist ein Datensatz und hat in meinem Fall dann 8 (in das gerade gezeigte Beispiel 4) Merkmale.
Die Datensätze möchte ich durchsortieren, nicht die Menge von Zahlen.

Die Idee war daher mit Listen zu arbeiten und jeden Datensatz dieser Liste hinzufügen.
Die Kreuzvalidierung "splittet" alle Datensätze in Trainings- bzw. Testdatensätze und speichert diese in dementsprechender Liste.
Besser die Kreuzvalidierung "sortiert" dann alle Datensätze mehrfach durch, damit nicht immer dieselbe Datenlage dem Training vorliegt.

Problem: das Array ist nicht indiziert.
In C würde ich bei so etwas mit Zeigern arbeiten, d. h. jede Menge bekommt einen ID-Zeiger und ich "sortiere" bzw. "teile" die Zeiger ein.
In Python habe ich dafür aber bisher keine Lösung...

Und etwas wie (0, 0.2, 0.7, 0.9, 0, 0.2, 0.7, 0.9, 0, 0.2, 0.7, 0.9) funktioniert nicht, da ich ja so Merkmale mit Datensätze mische und
möglicherweise alles über einen Haufen schweise...

Vielleicht ist ja einfach hier die k_fold_crossvalidation einfach falsch, da diese nur ein Merkmal unterstützt und meine ganze Idee schwachsinnig ist.
Aber wie soll man sonst eine Kreuzvalidierung mit Neuronalen Netzen mit mehreren Eingangsneuronen/-informationen/-merkmalen nutzen?
Daher meine Vermutung: das mit Liste/Array etc. muss anders strukturiert werden. In C hätte ich mit Zeiger eine Lösung, in Python bin ich zu neu.
Ich sage ja, eigentlich einfach, aber ich weiß gerade nicht, wie die Problematik zu lösen.
Benutzeravatar
ThomasL
User
Beiträge: 1366
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Das Problem liegt daran, dass du mit falschen Datentypen arbeitest.
Die Variablen Input und Output ( bitte beachte PEP8 ) sind vom Typ list() und damit funktioniert die Selektion von Elementen über eine Indexliste nicht.
Dazu benötigt man Numpy https://www.numpy.org

Code: Alles auswählen

import numpy as np

liste = [10,20,30,40,50,60,70,80,90]
index = np.array([1,2,3,4])
liste[index]
'''
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-10-e2c15db71a79> in <module>
      4 index = np.array([1,2,3,4])
      5 
----> 6 liste[index]

TypeError: only integer scalar arrays can be converted to a scalar index'''

np_liste = np.array(liste)
np_liste[index]

'''array([20, 30, 40, 50])'''
In deinem Fall einfach nach dem Erstellen der Listen Input und Output in Numpy ndarrays wandeln
und der Rest des Codes sollte funktionieren.

Code: Alles auswählen

Input = np.array(Input)
Output = np.array(Output)
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
https://projecteuler.net/profile/Brotherluii.png
doerflia
User
Beiträge: 20
Registriert: Freitag 3. Mai 2019, 14:49

Genau das habe ich gesucht.
Vielen Dank!
Antworten