Bernd Thomas
Beck et al.
Published in
8 min readJul 5, 2019

--

2.3 Unabhängigkeit und Robustheit — Erweiterte Anwendung des Chi-Square Verfahrens

pixabay.com

Wir untersuchen noch einige Eigenschaften des chi-square Lernverfahrens aus 2.2.

Andere Teiler

  • Für die Problemstellung “Vielfache von 5” ist lediglich die Erzeugung von Training- und Test-Set und die passenden Klassifizierung in “teilbar” (y=0) und “nicht teilbar” (y=1) notwendig. Am Verfahren (Algorithmus) ändert sich nichts.
  • Dass das so geht, ist natürlich für den gebildeten Mathematiker [ ;-) ] nicht verwunderlich: Schließlich kann man Teilbarkeit durch 5 ebenfalls einfach an der “Einer-Stelle” erkennen.
  • Bei der Problemstellung “Vielfache von 4” ist das z.B. nicht der Fall. Hier müsste man eine algorithmische Erweiterung einführen, die bei mehrschichtigen NN’s etwa Convolutional Models entspricht.

Fehlerhafte Daten

  • Die Trainingsdaten können bis zu einem gewissen Anteil Fehlklassifikationen enthalten. Beispiel: im Data Set wird der Zahl (Ziffernfolge) 2356 die Klasse y=1 zugeordnet, was definitiv falsch ist. Interessant ist zu sehen, wie hoch die Fehlerquote sein kann, bis das Verfahren versagt.
  • Testergebnisse (gerade/ungerade): Bei Fehlerquoten von bis zu 35% bei der Vorgabe-Klassifikation der Trainingsdaten lernt das Verfahren noch fehlerfrei. Bei 40% wurde das Signifikanz-Niveau von 0.05 überschritten, die Testergebnisse waren dennoch alle ok. Bei 50% Fehlerrate ergab das Test Set nur noch 68% korrekte Antworten. (Die genauen Zahlen variieren natürlich immer abhängig von der Zufallsauswahl der Trainings- und Testdaten.) Alles in allem scheint das Verfahren die Unterscheidung von gerade/ungerade bis etwa 1/3 Fehlerrate robust zu lernen.

Größere Zahlen

  • Die Erweiterung auf Zahlen mit mehr als 4 Dezimalstellen ist trivial.
  • Im Code sind dazu nur die Anzahl der Stellen n_pos zu verändern und die obere Grenze für die Zahlenwerte zu setzen: nmax = 10**n_pos.

2.3.1 Unabhängigkeit des Verfahrens vom Lernziel

Das Chi-Square Verfahren kann allein durch Änderung der Trainingsdaten auf Vielfache von N=5 trainiert werden. Auch der Ablauf ist der gleiche:

  • Erzeugen der Trainingsdaten
  • Erstellen des Classifiers (Chi_Square Test)
  • Trainieren (fit)
  • Testen (predict)

Es wird lediglich das N von 2 auf 5 gesetzt. (Als Folge gehören nur 1/5 der Trainingsdaten zur Klasse 0 (teilbar), was sich aber hier als unerheblich erweist.)

'''Wir beginnen wieder mit der Erzeugung der Datasets als numpy arrays: 
Ein 1-dimensionales Z mit Zufallszahlen zwischen 0 und 9999.
Die Kategorisierung y ist 0 für "teilbar durch N", 1 für "nicht teilbar". '''
def pad_zeros(k,s): # Funktion zum Auffüllen mit Nullen auf Länge k
t = str(s)
while len(t) < k:
t = '0' + t
return t # A string of length k
import numpy as np
import random as rd
# Problem-Paramter
nmin,nmax = 0,10000 # Größenordnung der Zahlen (als numerische Werte)
n_cases = 200 # Größe des Data Set
N = 5 # Teiler. Dient zur Erzeugung der Klassifizierung im Trainings Data Sets.n_pos = 4 # Anzahl Stellen (s. Größenordnung der Zahlen)
q_err = 0.00 # Quote der Fehlklassifikationen im Training Set
Z = np.random.randint(nmin,nmax,size=(n_cases,1))# Hier erzeugen wir die Klasse N (z.B. N=2 für gerade/ungerade) bzw. 0 für teilbar, 1 sonst
y = Z[:] % N
y = (y > 0).astype(int) # Alles, was nicht 0 ist, wird auf 1 gesetzt.
print('Ein Beispiel: Zahl: ',Z[10,0],' Kategorie: ',y[10,0])'''Und wandeln die Zahlen in 4-stellige Zeichenketten
Die Nummerierung der Stellen geht von 0 (hoch) bis 3 (Einer-Stelle) '''
# ... (wie oben)Ein Beispiel: Zahl: 4600 Kategorie: 0
Fälle gesamt: 200 y=0: 40 y=1: 160
Rate Fehlklassifikationen: 0.0

Die Häufigkeitsverteilungen (absolut und relativ) der Dezimalziffern je Position für die Klassen-Samples und die Gesamtheit werden berechnet. Man sieht, dass die Verteilung für die Gesamtheit in allen Positionen etwa gleichverteilt ist. Die Wahrscheinlichkeiten p0[i,j] und p1[i,j] werden bestimmt.

'''Verteilung der absoluten Häufigkeiten über die Ziffern 0...9 an den String-Positionen 0...3
bei Klassifizierung y=0 bzw. y=1'''
chain = list(zip(D,y)) # Using zip()freq0 = np.zeros([n_pos,10]) # 10 fest für die Ziffern des Dezimalsystems
freq1 = np.zeros([n_pos,10])
for d,cat in chain:
for pos in range(n_pos):
if cat[0] == 0:
freq0[pos,int(d[0][pos])] +=1
elif cat[0] == 1:
freq1[pos,int(d[0][pos])] +=1
# Erwartungswerte bei Gleichverteilung innerhalb der Samples
exp0 = [count0/10 for i in range(10)]
exp1 = [count1/10 for i in range(10)]
# Output ...
'''Relative Häufigkeiten'''print('Berechnung der entsprechenden relativen Häufigkeiten')
sum0 = np.sum(freq0,axis=1)[0]
sum1 = np.sum(freq1,axis=1)[0]
rfreq0 = freq0 / sum0
rfreq1 = freq1 / sum1
rfreq = (freq0 + freq1) / (sum0 + sum1) # Relative Häufigkeiten über alle Trainingsdaten
rf_exp0 = exp0 / np.sum(exp0)
rf_exp1 = exp1 / np.sum(exp1)
# Output ...
'''Wahrscheinlichkeiten p0[i,j] (aus rel. Häufigkeiten) dafür, dass Ziffer i an Position j
die Klasse y=0 bestimmt. Bzw. p1 = 1-p0 für Klasse y=1'''
P0 = rfreq0 / (rfreq0 + rfreq1) # Elementweise Division mit Ergebnis-Array P0# Output ...Ergebnisse:Auswertung der absoluten Häufigkeiten
je Ziffer i and Position j falls y=0, y=1
und über alle Fälle
==================================================
y= 0 Digit Pos0 Pos1 Pos2 Pos3 Exp
==================================================
0 4.00 4.00 3.00 21.00 4.00
1 4.00 2.00 3.00 0.00 4.00
2 6.00 3.00 3.00 0.00 4.00
3 4.00 2.00 5.00 0.00 4.00
4 5.00 8.00 3.00 0.00 4.00
5 2.00 1.00 8.00 19.00 4.00
6 3.00 7.00 6.00 0.00 4.00
7 3.00 6.00 5.00 0.00 4.00
8 3.00 2.00 4.00 0.00 4.00
9 6.00 5.00 0.00 0.00 4.00
==================================================
y= 1 Digit Pos0 Pos1 Pos2 Pos3 Exp
==================================================
0 14.00 19.00 14.00 0.00 16.00
1 19.00 17.00 15.00 16.00 16.00
2 16.00 9.00 16.00 21.00 16.00
3 17.00 18.00 13.00 20.00 16.00
4 12.00 18.00 17.00 17.00 16.00
5 18.00 16.00 15.00 0.00 16.00
6 20.00 14.00 18.00 24.00 16.00
7 16.00 21.00 22.00 21.00 16.00
8 14.00 15.00 14.00 17.00 16.00
9 14.00 13.00 16.00 24.00 16.00
==================================================
All Digit Pos0 Pos1 Pos2 Pos3 Exp
==================================================
0 18.00 23.00 17.00 21.00 20.00
1 23.00 19.00 18.00 16.00 20.00
2 22.00 12.00 19.00 21.00 20.00
3 21.00 20.00 18.00 20.00 20.00
4 17.00 26.00 20.00 17.00 20.00
5 20.00 17.00 23.00 19.00 20.00
6 23.00 21.00 24.00 24.00 20.00
7 19.00 27.00 27.00 21.00 20.00
8 17.00 17.00 18.00 17.00 20.00
9 20.00 18.00 16.00 24.00 20.00
==================================================
Berechnung der entsprechenden relativen Häufigkeiten
==================================================
y= 0 Digit Pos0 Pos1 Pos2 Pos3 Exp
==================================================
0 0.10 0.10 0.07 0.53 0.10
1 0.10 0.05 0.07 0.00 0.10
2 0.15 0.07 0.07 0.00 0.10
3 0.10 0.05 0.12 0.00 0.10
4 0.12 0.20 0.07 0.00 0.10
5 0.05 0.03 0.20 0.47 0.10
6 0.07 0.17 0.15 0.00 0.10
7 0.07 0.15 0.12 0.00 0.10
8 0.07 0.05 0.10 0.00 0.10
9 0.15 0.12 0.00 0.00 0.10
==================================================
y= 1 Digit Pos0 Pos1 Pos2 Pos3 Exp
==================================================
0 0.09 0.12 0.09 0.00 0.10
1 0.12 0.11 0.09 0.10 0.10
2 0.10 0.06 0.10 0.13 0.10
3 0.11 0.11 0.08 0.12 0.10
4 0.07 0.11 0.11 0.11 0.10
5 0.11 0.10 0.09 0.00 0.10
6 0.12 0.09 0.11 0.15 0.10
7 0.10 0.13 0.14 0.13 0.10
8 0.09 0.09 0.09 0.11 0.10
9 0.09 0.08 0.10 0.15 0.10
==================================================
All Digit Pos0 Pos1 Pos2 Pos3 Exp
==================================================
0 0.09 0.12 0.09 0.10 0.10
1 0.12 0.10 0.09 0.08 0.10
2 0.11 0.06 0.10 0.10 0.10
3 0.10 0.10 0.09 0.10 0.10
4 0.09 0.13 0.10 0.09 0.10
5 0.10 0.09 0.12 0.10 0.10
6 0.12 0.10 0.12 0.12 0.10
7 0.10 0.14 0.14 0.10 0.10
8 0.09 0.09 0.09 0.09 0.10
9 0.10 0.09 0.08 0.12 0.10
==================================================
Wahrscheinlichkeit p0, dass Ziffer i
an Position j mit y=0 vorkommt
==================================================
P0 Digit Pos0 Pos1 Pos2 Pos3
==================================================
0 0.53 0.46 0.46 1.00
1 0.46 0.32 0.44 0.00
2 0.60 0.57 0.43 0.00
3 0.48 0.31 0.61 0.00
4 0.62 0.64 0.41 0.00
5 0.31 0.20 0.68 1.00
6 0.37 0.67 0.57 0.00
7 0.43 0.53 0.48 0.00
8 0.46 0.35 0.53 0.00
9 0.63 0.61 0.00 0.00
==================================================

ChiQuadrat Test für die Ziffern-Häufigkeiten je Position gegen Erwartung (H0: Gleichverteilung)

# Chi_Quadrat Test gegen Null-Hypotese H0: Gleichverteilung
# Version für absolute Häufigkeiten
from scipy.stats import chisquareChi-Quadrat und p für die Ziffernhäufigkeit an jeder Dezimal-Position
Signifikanz Niveau: p<0.05 zur Ablehnung von H0
y=0: Chi^2 p
==================================================
0 : 4.00 0.91
1 : 13.00 0.16
2 : 10.50 0.31
3 : 160.50 5.8e-30
y=1: Chi^2 p
==================================================
0 : 3.62 0.93
1 : 6.62 0.68
2 : 3.75 0.93
3 : 44.25 1.3e-06

Predict mit Testdaten-Set: Alle Klassifikationen sind korrekt

'''Predict Methode - Anwendung auf Testdaten Set '''# ... Code wie oben ...Z_test = [185,3456,9728,6470,99]
y_test = [0,1,1,0,1]
test_chain = list(zip(Z_test,y_test))
score = 0.0
# Predict and Score für die Testdaten
for z,y in test_chain:
score += chi_predict(z,y,n_pos)

print('Score:',score/n_cases)
185 >> Predicted Class: 0 Target Class: 0
3456 >> Predicted Class: 1 Target Class: 1
9728 >> Predicted Class: 1 Target Class: 1
6470 >> Predicted Class: 0 Target Class: 0
99 >> Predicted Class: 1 Target Class: 1
Score: 0.1

2.3.2 Fehler in den Trainingsdaten.

Hier ist nur die Fehlerquote q_err z.B. auf 0.4 zu setzen, um 40% der Klassifikationen zu verfälschen. Der weitere Ablauf ist wie zuvor durchzuführen.

# ... Code wie oben ...import numpy as np
import random as rd
# Problem-Paramter
nmin,nmax = 0,10000 # Größenordnung der Zahlen (als numerische Werte)
n_cases = 200 # Größe des Data Set
N = 2 # Teiler. Dient zur Erzeugung der Klassifizierung im Trainings Data Sets.
n_pos = 4 # Anzahl Stellen (s. Größenordnung der Zahlen)
q_err = 0.4 # Quote der Fehlklassifikationen im Training Set# ...# Einfügen von Klassifikationsfehlern für Robustheits-Testssel = np.random.choice(n_cases,int(n_cases*q_err))
y[sel,0] = 1 - y[sel,0] # Switch randomly selected elements in array y
# Output ...
Fälle gesamt: 200 y=0: 93 y=1: 107
Rate Fehlklassifikationen: 0.4
# Nach Häufigkeitsverteilungen und Wahrscheinlichkeiten
# erfolgt der Chi-Quadrat Test.
# Ergebnis:
Chi-Quadrat und p für die Ziffernhäufigkeit an jeder Dezimal-Position
Signifikanz Niveau: p<0.05 zur Ablehnung von H0
y=0: Chi^2 p
==================================================
0 : 14.29 0.11
1 : 7.00 0.64
2 : 12.42 0.19
3 : 24.76 0.0033
y=1: Chi^2 p
==================================================
0 : 9.13 0.43
1 : 18.38 0.031
2 : 13.43 0.14
3 : 16.87 0.051

Das Beispiel hat eine Fehlerrate von 40% in der Trainingsklassifikation und überschreitet das geforderte Signifikanz-Niveau von 0.05. Die konkreten Werte variieren mit den Trainingsdaten.

Ein Auszug aus den Predict-Ergebnissen, darin 2 Fehlklassifizierungen:

901  >> Predicted Class: 1 Target Class: 1
6385 >> Predicted Class: 1 Target Class: 1
3824 >> Predicted Class: 1 Target Class: 0
734 >> Predicted Class: 1 Target Class: 0
7115 >> Predicted Class: 1 Target Class: 1
3191 >> Predicted Class: 1 Target Class: 1
....
Score: 0.96

Der Prediction-Score bei den Testdaten fällt unter 1.0.

Nachdem es uns in diesem Teil gelungen ist, ein ML Verfahren auf Basis statistischer Datenanalyse (Chi-Squared Test) zu entwickeln, das tatsächlich die Unterscheidung von geraden und ungeraden Zahlen lernen kann, stellen wir uns in Teil 3 die Frage, ob man das hier beschriebene Lernverfahren auch in einem (mehrschichtigen) Neuronalen Netz realisieren kann.

Da mehrschichtige NN-Modelle (Deep Learning) sehr gut darauf trainiert werden können, Muster in großen Datensätzen zu entdecken, wäre zu erwarten, dass auch “außergewöhnliche Häufigkeitsverteilungen” in den Ziffernpositionen durch NNs zu erkennen und zu interpretieren sind.

Weiter lesen: 3 Gerade / Ungerade Klassifikation Lernen mit Neuronalen Netzen

Zurück auf Anfang

bernhard.thomas@becketal.com
www.becketal.com

--

--

Bernd Thomas
Beck et al.

Dr. Bernhard Thomas — Mathematics, Theor. Biology, Computational Sciences, AI and advanced Technologies for the Enterprise. Beck et al. Consultant