maandag 26 december 2016

06 Fish - Verbeteren en verbeteren

Yes, yes yes!

Mijn laatste verbeteringen geven in ieder geval een aardig geloofwaardige verdeling:


0 18
1 2
2 14
3 43
4 36
5 30
6 149
7 708

Dit was de trainingset verdeling:

0 200
1 117
2 67
3 465
4 299
5 176
6 734
7 1719

Onderzoek van eerdere oplossingen van winnaars van andere competities geeft altijd weer aanvullende ideeën. Bijvoorbeeld bij het identificeren van walvissen heeft men ze eerst vergelijkbaar geplaatst (van links naar rechts). Dat kan ik ook gaan doen (er zijn een aantal deelnemers die kop staart informatie al beschikbaar hebben gemaakt) maar eerst wil ik wat andere suggesties proberen. Zo-ie-zo lijkt het verstandig om dergelijke uitdagingen vergelijkbaar op te pakken als je het zelf zou leren. Bijvoorbeeld eens goed 'inzoomen' op de vinvorm of andere identificerende details.
Ik begin maar eens met het verwijderen van de ingezoomde afbeeldingen uit de validatieset. Die komt tenslotte ook niet voor in de uiteindelijke testset.
Ik laat daarnaast steeds alleen de beste oplossingen opslaan in plaats van gewoon de laatste.

Verder hebben ze in de winnende 'walvissen-oplossing' gespeeld met variatie in de training parameters. Met name een sterke aanpassing van de learning rate ergens halverwege. Ik besluit iets dergelijks te doen maar dan met de 'optimizer'. De eerste 17 rondes werk ik met 'rmsprop' om daarna over te schakelen op 'Adam'. Dat lijkt een aardig succesvolle methode:


Later nog eens kijken of ander variaties de curve opnieuw kan laten zakken. Nu eerst maar eens verder werken aan een submission file.

Spannend ....


Hmmm :-( valt vies tegen. Ook nog een flink stuk van het 'sample submission' niveau.
Toch lijkt die regelmatig behoorlijk zeker van zijn zaak. Hieronder voor de eerste dertig de hoogste waarschijnlijkheid:

0 0.394905
1 0.865984
2 0.893556
3 0.514651
4 0.455819
5 0.587176
6 0.693616
7 0.505812
8 0.952622
9 0.476833
10 0.862486
11 0.556331
12 0.993129
13 0.649682
14 0.366256
15 0.766741
16 0.835264
17 0.552001
18 0.463462
19 0.758394
20 0.624866
21 0.503535
22 0.64195
23 0.653738
24 0.713803
25 0.846063
26 0.897888
27 0.718468
28 0.859618
29 0.86105  

woensdag 21 december 2016

05 Fish - En nu een submission maken.

Ik heb mij nog niet zo bezig gehouden met het voorbereiden van de werkelijke submission. Zelfs de testdata bleek ik nog niet op mijn pc te hebben geladen. Snel een download en een programma om de data in he juiste formaat om te zetten. Tevens 'sorteer' ik ook deze afbeeldingen op 'overeenkomstigheid' omdat ik vermoed dat er regelmatig, kort op elkaar volgende afbeeldingen zijn gebruikt waar dus dezelfde soort vis op te zien moet zijn. Bij twijfel kan dat dus een doorslag geven.



De gewenste output ziet er zo uit: (meegeleverd voorbeeld)

image,ALB,BET,DOL,LAG,NoF,OTHER,SHARK,YFT
img_00005.jpg,0.45500264690312336,0.05293806246691371,0.03096876654314452,0.017734250926416093,0.12308099523557438,0.07914240338803599,0.046585494970884066,0.1942826892535733
img_00007.jpg,0.45500264690312336,0.05293806246691371,0.03096876654314452,0.017734250926416093,0.12308099523557438,0.07914240338803599,0.046585494970884066,0.1942826892535733
img_00009.jpg,0.45500264690312336,0.05293806246691371,0.03096876654314452,0.017734250926416093,0.12308099523557438,0.07914240338803599,0.046585494970884066,0.1942826892535733
img_00018.jpg,0.45500264690312336,0.05293806246691371,0.03096876654314452,0.017734250926416093,0.12308099523557438,0.07914240338803599,0.046585494970884066,0.1942826892535733
img_00027.jpg,0.45500264690312336,0.05293806246691371,0.03096876654314452,0.017734250926416093,0.12308099523557438,0.07914240338803599,0.046585494970884066,0.1942826892535733

Een waarschijnlijkheid dus per vissoort. Mooi dat regelt mijn gebruikte model ook als output alleen besef ik mij nu dat ik de 'vis volgorde' heb aangepast:


fishtypes = ['BET','DOL','LAG','NoF','OTHER','SHARK','YFT','ALB']

Hierdoor kwam de grootste groep aan het einde. Ik geloof dat dit vooral was om snel te kunnen testen.

Mijn tussenuitkomsten zien er zo uit:


[  5.55696040e-02   3.63390967e-02   3.35246362e-02   2.71632709e-02
   1.92823112e-01   1.01814854e-04   5.17386533e-02   6.02739811e-01]
[ 0.07084329  0.01330838  0.01655073  0.02492231  0.05961363  0.00400923
  0.10697447  0.70377797]
[  3.16158533e-02   5.14484383e-02   8.70272238e-03   1.64415389e-02
   3.37270200e-01   9.72153975e-06   2.47996226e-02   5.29711902e-01]
[ 0.09419882  0.01306145  0.04260941  0.01321667  0.08773319  0.00299926
  0.10487828  0.64130288]
[ 0.02304434  0.00076831  0.00147995  0.00258547  0.18335994  0.06462369

  0.31772998  0.40640843]

Opvallend is dat meestal de laatste groep de hoogste kans heeft. Gelukkig zijn er wat uitzonderingen : (Aantal hoogste kans per vissoort)


0 0
1 0
2 0
3 21
4 2
5 3
6 47

7 927

Ligt een beetje in lijn met het aantal vissen per vissoort in de traindataset:


0 200
1 117
2 67
3 465
4 299
5 176
6 734
7 1719

Maar ja, gevoelsmatig valt het nog een beetje tegen. Was leuk geweest als die van alle types wat meer had herkent. Maar goed, we zullen eens kijken wat dit oplevert.






zaterdag 17 december 2016

04 Fish - ook eerst de visjes herkennen

De vorige resultaten vielen nogal tegen. Door de data 'te verrijken' met draaien, spiegelen, schuiven, zoomen, voorkom je dat een NN 'overfit'. Oftewel de foto's zo goed kent dat alleen die betreffende foto's de juiste resultaten weergeven en niet bij een nieuwe, onbekende foto.


Doordat de fotos vaak vanuit dezelfde hoek zijn genomen en ook vaak kort achter elkaar loop je hier het risico dat eerder een voorspelling wordt gedaan op basis van de boot en 'omstandigheden' (aantal / positie mensen etc) dan op basis van de vissen zelf. Ik heb daarom nu, op basis van eerder, handmatig verkregen, positiedata, uitsneden toegevoegd van de vissen zelf. De resultaten zijn veelbelovend. Veel minder variatie in de resultaten:


Waarom mijn testdata het nu structureel beter doet dan mijn traindata, iig in de 'loss', snap ik niet. Wel zou ik eigenlijk mijn testdata zonder de uitsnedes moeten doen.

Feitelijk zou ik daarnaast voor een juiste validatie de bootcamerabeelden per boot moeten scheiden. Helaas zijn er m.i. daarvoor te weinig boten. Een stuk of 8-10 geloof ik ergens gezien te hebben.
Wellicht is het wel zinvol om te kijken of ik de 'vaste boot beelddelen' kan onderdrukken. Daar zit veel informatie in die buiten beschouwing zou moeten blijven. Ik heb al eerder een subroutine gemaakt om de beelden in volgorde van de minste verschillen te plaatsen. Misschien moet ik daar nogeens verder mee experimenteren.


woensdag 14 december 2016

03 Fish - Natural stupidity


Tja, beter kan ik het niet maken. Alle combinatie testen van gisteren zijn zinloos geweest. Ik heb de eerste versie van mijn programma 'classifier_from_little_data_script_2.py' genoemd en de combinatie opvolger nr 3. Ik ben echter het eerste programma steeds blijven aanroepen. Duh!!! Geen wonder dat het weinig leek te reageren op mijn aanpassingen. Maar wle voldoende om geen alarmbellen te laten rinkelen.

Nu dus aangepast en opnieuw opgestart. In lijn met de verwachtingen duurt elke epoch nu veel langer. 69 seconden zonder rotatie. Zo'n 72 tot 127 seconden met rotatie (veel variatie hier?!)
Duurt dus even tot we resultaat hebben. Had ik nou maar zo'n mooie nvidea supercomputer :-(
    

Dit zijn de resultaten: 



Erg veel variatie in de test 'loss'. Bovendien komt deze uiteindelijk op zo'n 1.17 uit. Veel hoger dan de eerste meting zonder de data-augmentation die richting de 0.5 aan het lopen was. Ook grote verschillen in de acccuracy. Natuurlijk kan het zo zijn dat bij deze waarneming de herkenning van de omgeving minder een rol gaat spelen. (En dus in het eerste model teveel). Of er zit gewoon nog ergens een stomme fout in.  
Misschien moet ik zo-ie-zo het systeem even wat beter de 'visvorm' gaan laten herkennen. Ik heb al eerder handmatig de vis-locaties vastgelegd. (rsi gevoelig klusje). Maar daar kan ik nu misschien fijn gebruik van gaan maken.   

dinsdag 13 december 2016

03 Fish - De combi


Wow! In 1 keer lukt het om de data augmentation en het VGG16 netwerk gebruik te combineren. Hier de resultaten:


De variatie in de loss bij de testdata fluctueert nu nog meer! Maar het gaat wel supersnel en ik zie een accuracy van wel 89%. Dat geeft wel hoop. Misschien maar eens over een submission na gaan denken!
De fluctuatie blijkt voor een belangrijk in de gekozen dropout te zitten (.5). Hier bijvoorbeeld een dropout van 0.2:

 

02 Fish - Bouwen op bestaande NN's kennis

Bij het vorige algoritme, waar ik voor het eerst met Keras ImageDataGenerator heb gewerkt op basis van deze blog, staat ook een mooi voorbeeld van he gebruik van een al eerder getraind NN.  In dit geval een 'VGG16 architecture, pre-trained on the ImageNet dataset'.  ImageNet bestaat uit een geclassificeerde dataset van miljoenen afbeeldingen. Daardoor heeft het model al de features in zich van foto's van allerlei dieren en objecten. Daar bovenop is dan alleen nog maar een relatief eenvoudig model nodig om de vissoorten te herkennen uit al die features.


Voorbeelden uit ImagNet
 Het lukt al vrij snel om het voorbeeld model om te bouwen voor de visjes. Hier zijn de resultaten:


Op zich ziet het er netjes uit behalve dat de test data erg 'springerig' is. Ik weet niet zeker wat de oorzaak zou kunnen zijn. De testset is in principe een random subset van het totaal. In deze competitie speelt wel het probleem dat er dus veel vergelijkbare afbeeldingen kunnen zijn en dat een deel van de 'kennis' wellicht afgeleid wordt van de boot informatie ipv de werkelijke vis. Daarnaast bevatten sommige afbeeldingen meerdere vissen.    

In deze 'oplossing' is nog niet gebruik gemaakt van 'data augmentation' (draaien / flippen / schuiven / zoomen) zoals in het vorige blogbericht. Dit zou zijn omdat de VGG16 anders veel te veel processingtijd zou nemen. 
Ik ga eens proberen of we dat met Keras 'trainable=False' parameter kunnen ondervangen.  








zondag 11 december 2016

01 Fish - Nieuwe Kaggle competitie

Het is helaas geen medische competitie maar wel een grafische. Misschien hier wat meer succes dan bij de EEGs. Het gaat in deze competitie (the-nature-conservancy-fisheries-monitoring) om het herkennen van bijvangst bij vissers. Men heeft camera's op de schepen geplaatst om daar de bijvangst (dolfijnen / haaien etc) automatisch te identificeren.
Helaas zijn er maar relatief weinig foto's en ze overlappen elkaar ook behoorlijk.

plenty of fish in the sea
Bij Keras, mijn favorite ML omgeving, zit ook een module bij om afbeeldingen te draaien / schuiven zoomen etc zodat er met minder afbeeldingen toch betere resultaten bereikt kunnen worden. Hier wordt daar een voorbeeld van uitgewerkt. Het moet met name 'overfitting' voorkomen bij gebruik van kleine datasets.
Ik heb zelf al eerder dergelijke functies gemaakt en gebruikt maar deze doet het allemaal 'on-the-fly' en automatisch. Wel even wennen aan de syntax:

# this is the augmentation configuration we will use for training
train_datagen = ImageDataGenerator(rotation_range=20,
                                   rescale=1./255,
                                   shear_range=0.2,
                                   zoom_range=0.2,
                                   horizontal_flip=True)

# this is the augmentation configuration we will use for testing:
# only rescaling
test_datagen = ImageDataGenerator(rescale=1./255)

train_generator = train_datagen.flow(X_train,y_train, batch_size=32)

validation_generator = test_datagen.flow(X_test,y_test, batch_size = 32)

history = model.fit_generator(
                    train_generator,
                    samples_per_epoch=nb_train_samples,
                    nb_epoch=nb_epoch,
                    validation_data=validation_generator,

                    nb_val_samples=nb_validation_samples)

Zie hier de resultaten van 50 epochs trainen:




       

CuDNN eindelijk eens actief!!!

Na veel zoeken en testen is het gelukt om CuDNN, de speciale NVDEA software accelerator voor NN's aan de praat te krijgen.


>>> import theano
Using gpu device 0: GeForce GTX 980 (CNMeM is disabled, cuDNN 5105)
/usr/local/lib/python2.7/site-packages/theano/sandbox/cuda/__init__.py:600: UserWarning: Your cuDNN version is more recent than the one Theano officially supports. If you see any problems, try updating Theano or downgrading cuDNN to version 5.
  warnings.warn(warn)

Oke met een warning omdat ik al op een heel nieuwe versie zit maar toch.

Even vastleggen hoe mij dat gelukt is.
Ik heb de nieuwste Xcode software geladen. Dat is goed maar de developer tools zijn van een te nieuwe versie:


nvcc fatal   : The version ('80000') of the host compiler ('Apple clang') is not supported

Dus weer terugzetten naar versie 7.3. Hier vind ik hoe dat moet. 
Met name ook het terugzetten naar de juiste versie is belangrijk.

sudo xcode-select --switch /Library/Developer/CommandLineTools

Voor CuDNN heb ik de handmatige installatie gedaan. Eerst versie 8.0 gedownload van de NVIDEA site. Daarna de bestanden naar de actieve cuda directory gekopieerd. Het gaat om deze bestanden:


Het eerste bestand gaat naar de

/Developer/NVIDIA/CUDA-8.0/include

de andere naar de /Developer/NVIDIA/CUDA-8.0/lib

et voila. Het werkt!

Nu kijken of we er iets interessants op kunnen laten draaien. Een Keras autoencoder voorbeeld lijkt al prima te werken.





zaterdag 5 november 2016

17 - EEGs - Meeeer features ... meeer !!!! Hongerrrrrr !!!!

Voorlopig heb ik mij beperkt tot mij bekende meetkundige begrippen als gemiddelde, standaard deviatie variatie , maxima etc. Uit dit voorbeeld komen echter ook wat minder bekende mogelijke features bovendrijven. Hoewel ik ze (nog?) niet allemaal begrijp kan ik sommigen wel eenvoudig toepassen in mijn algoritme. Ik voeg toe:

  • Mobility
  • Skew
  • Kurtosis
 Met deze resultaten:


/Volumes/Slot 4 2tB/EEG recordings/base_data_train_1.npy
0 mobility 0.0523353 skew -0.0200588 kurtosis -0.0631648 max150 -0.242883982577 std50 -0.260966676004
1 mobility 0.27188 skew -0.00617675 kurtosis -0.0652061 max150 -0.335989628134 std50 -0.294928975495
2 mobility 0.285167 skew 0.00104097 kurtosis -0.05857 max150 -0.330593024561 std50 -0.316744934306
3 mobility 0.366227 skew -0.0143969 kurtosis -0.0134535 max150 -0.373199745072 std50 -0.352717356564
4 mobility 0.307609 skew -0.0345025 kurtosis 0.0539059 max150 -0.298854600393 std50 -0.285660933307
5 mobility 0.353854 skew 0.0284561 kurtosis -0.0543017 max150 -0.365825532027 std50 -0.329818414897
6 mobility 0.304553 skew -0.0346076 kurtosis 0.0413215 max150 -0.286225112757 std50 -0.31308744867
7 mobility 0.301008 skew -0.0124692 kurtosis -0.00856104 max150 -0.307331973759 std50 -0.288222778178
8 mobility 0.267957 skew -0.0262571 kurtosis 0.0268127 max150 -0.289512624077 std50 -0.243221100591
9 mobility 0.270148 skew -0.0329627 kurtosis 0.0254555 max150 -0.311388776993 std50 -0.248309716943

/Volumes/Slot 4 2tB/EEG recordings/base_data_train_2.npy
0 mobility -0.150931 skew -0.146515 kurtosis -0.0353059 max -0.15774 std -0.143356 var -0.182106
1 mobility -0.129593 skew -0.136441 kurtosis -0.0742252 max -0.180184 std -0.130419 var -0.176175
2 mobility -0.153917 skew -0.136542 kurtosis -0.0710757 max -0.173871 std -0.11737 var -0.152299
3 mobility -0.14907 skew -0.150621 kurtosis -0.0176674 max -0.180999 std -0.15774 var -0.191165
4 mobility -0.150428 skew -0.156201 kurtosis -0.00552943 max -0.162947 std -0.160257 var -0.193626
5 mobility -0.151242 skew -0.179715 kurtosis 0.00935185 max -0.0760022 std -0.0996672 var -0.132624
6 mobility -0.147582 skew -0.1663 kurtosis 0.0068302 max -0.173156 std -0.175677 var -0.204756
7 mobility -0.147695 skew -0.158236 kurtosis 0.00842871 max -0.146987 std -0.134018 var -0.156448
8 mobility -0.14914 skew -0.16273 kurtosis -0.00343621 max -0.150193 std -0.147082 var -0.185152
9 mobility -0.148844 skew -0.168124 kurtosis 0.0150697 max -0.128591 std -0.115792 var -0.139928

/Volumes/Slot 4 2tB/EEG recordings/base_data_train_3.npy
0 mobility 0.37712 skew -0.00947632 kurtosis 0.0379376 max -0.27445 std -0.415572 var -0.388982
1 mobility 0.341428 skew -0.0333562 kurtosis 0.0842102 max -0.228343 std -0.381748 var -0.359042
2 mobility 0.299282 skew -0.0549255 kurtosis 0.0599769 max -0.209765 std -0.32824 var -0.298396
3 mobility 0.304547 skew -0.0128211 kurtosis 0.0725289 max -0.214312 std -0.355743 var -0.341279
4 mobility 0.307507 skew -0.0118719 kurtosis 0.0291579 max -0.232577 std -0.349437 var -0.332958
5 mobility 0.321745 skew -0.00989002 kurtosis -0.0112829 max -0.241705 std -0.329389 var -0.283258
6 mobility 0.277108 skew 0.0347802 kurtosis 0.0380326 max -0.181071 std -0.322692 var -0.30548
7 mobility 0.281636 skew 0.0492457 kurtosis 0.0330193 max -0.161524 std -0.308305 var -0.28655
8 mobility 0.29753 skew -0.0429441 kurtosis 0.0224731 max -0.242076 std -0.339596 var -0.316196

9 mobility 0.326863 skew -0.0270964 kurtosis 0.0405491 max -0.265741 std -0.377276 var -0.357412

De 'kurtosis' lijkt weinig bij te dragen (hoef ik mij dus niet in te verdiepen :-) maar de skew is met name voor patient 2 wellicht ook interessant. Zeker omdat deze in het algemeen de slechtste correlatie features lijkt te hebben.
De 'mobility' lijkt bij alle 3 wel een interessante toevoeging. Toch eens uitzoeken wat dat nou precies moet betekenen.



vrijdag 4 november 2016

16 - EEGs - Features per patient

De aard van de competitie heeft het al wat laten blijken. Er moet een beoordeling per patient worden gemaakt. Men is er dus al een beetje vanuit gegaan dat er aparte algoritmen per patient nodig zijn. Dat is jammer. Je hoopt toch het ei van columbus te vinden en met 1 slim programma alle patienten van dienst te zijn.
Voorlopige uitkomst:

/Volumes/Slot 4 2tB/EEG recordings/base_data_train_1.npy
0 max150 -0.242883982577 std50 -0.260966676004
1 max150 -0.335989628134 std50 -0.294928975495
2 max150 -0.330593024561 std50 -0.316744934306
3 max150 -0.373199745072 std50 -0.352717356564
4 max150 -0.298854600393 std50 -0.285660933307
5 max150 -0.365825532027 std50 -0.329818414897
6 max150 -0.286225112757 std50 -0.31308744867
7 max150 -0.307331973759 std50 -0.288222778178
8 max150 -0.289512624077 std50 -0.243221100591
9 max150 -0.311388776993 std50 -0.248309716943
/Volumes/Slot 4 2tB/EEG recordings/base_data_train_2.npy
0 max -0.15774 std -0.143356 var -0.182106
1 max -0.180184 std -0.130419 var -0.176175
2 max -0.173871 std -0.11737 var -0.152299
3 max -0.180999 std -0.15774 var -0.191165
4 max -0.162947 std -0.160257 var -0.193626
5 max -0.0760022 std -0.0996672 var -0.132624
6 max -0.173156 std -0.175677 var -0.204756
7 max -0.146987 std -0.134018 var -0.156448
8 max -0.150193 std -0.147082 var -0.185152
9 max -0.128591 std -0.115792 var -0.139928
/Volumes/Slot 4 2tB/EEG recordings/base_data_train_3.npy
0 max -0.27445 std -0.415572
1 max -0.228343 std -0.381748
2 max -0.209765 std -0.32824
3 max -0.214312 std -0.355743
4 max -0.232577 std -0.349437
5 max -0.241705 std -0.329389
6 max -0.181071 std -0.322692
7 max -0.161524 std -0.308305
8 max -0.242076 std -0.339596

9 max -0.265741 std -0.377276

Per patient dus andere features. Bij patient 2 kan zelfs de std vermoedelijk achterwege blijven. De variatie doet het daar beter. Bij patient 3 blijkt het andersom.


15 - EEGs - On track! Of toch niet? ...

Een 2e serie meetresultaten van 'patient 1' lijkt nog betere resultaten te geven. Hier en daar al over de -0.5 (even in herinnering waarde tussen -1 en + 1):

0 max150 (-0.41194723992175802, 6.4307532561886419e-42) std50 (-0.43304379501542439, 1.3214398909113476e-46)
1 max150 (-0.48596710493646184, 6.3249130187555734e-60) std50 (-0.4334835522710116, 1.0465520423535658e-46)
2 max150 (-0.38712509961437946, 8.1284564387807416e-37) std50 (-0.41005723450378079, 1.6296940049387049e-41)
3 max150 (-0.31347052201956449, 4.6585385828558043e-24) std50 (-0.37891558163834688, 3.1886871059606937e-35)
4 max150 (-0.50810169324387311, 3.1496400833880827e-66) std50 (-0.48680453919838323, 3.7232202707862507e-60)
5 max150 (-0.50374007897117778, 5.9855889089138001e-65) std50 (-0.46434283643301089, 3.3712379129179665e-54)
6 max150 (-0.38604296629277873, 1.3264016738422933e-36) std50 (-0.41664613998117733, 6.2079414676572266e-43)
7 max150 (-0.42672438803953633, 3.632274538404576e-45) std50 (-0.40562005739655771, 1.4128080318195218e-40)
8 max150 (-0.44155469389755642, 1.361648207219794e-48) std50 (-0.40218135406263578, 7.3672385515236656e-40)

9 max150 (-0.36901236598909753, 2.3238389835137084e-33) std50 (-0.40252748348132128, 6.2444146827444672e-40)

Dat ziet er veelbelovend uit eens kijken of we bij patient 2 een vergelijkbare correlatie vinden:

0 max150 (-0.02060457055488684, 0.51684732569352621) std50 (-0.015136891675287435, 0.63394742710094798)
1 max150 (-0.020360584046250341, 0.52182454096207387) std50 (-0.059256619832695874, 0.06209247849948879)
2 max150 (-0.018204588157154863, 0.56684998761611238) std50 (-0.041269189197066423, 0.19403654879636154)
3 max150 (-0.0045193845378886828, 0.88695051699119309) std50 (-0.0076395587227884405, 0.81008535601819365)
4 max150 (0.073351291316438236, 0.020861885444262176) std50 (0.015196883655175707, 0.63260347583788157)
5 max150 (0.041058667608851934, 0.196322689397739) std50 (-0.010483467660498184, 0.74156590937677591)
6 max150 (0.0022728740281126227, 0.94300273163066195) std50 (-0.020356785689197503, 0.52190221985714214)
7 max150 (0.01156345260123072, 0.71604034331374677) std50 (-0.059832736921967715, 0.059591266860954409)
8 max150 (0.00228939672832075, 0.94258910106909666) std50 (-0.096075175630787407, 0.0024521753406124155)

9 max150 (-0.0046814919783101771, 0.88292418236201475) std50 (-0.049803520983771242, 0.116972551521023)

Wow, dat valt tegen! Totaal niet blijkbaar. En patient 3 ?

0 max150 (-0.14644731274910988, 3.6269879573262225e-06) std50 (-0.26141036355375996, 5.8132273417628722e-17)
1 max150 (-0.12001542679703069, 0.00015128753924536806) std50 (-0.2556799345258296, 2.860320511618802e-16)
2 max150 (-0.18647547671201301, 3.2624918323603128e-09) std50 (-0.27465510857809178, 1.2558939065168329e-18)
3 max150 (-0.13060960674568933, 3.6883129806916829e-05) std50 (-0.26350801267712604, 3.2123337712342012e-17)
4 max150 (-0.081552575690427148, 0.01018085956117081) std50 (-0.21968285964068615, 2.632797845577492e-12)
5 max150 (-0.16821967356823259, 9.8431876307007162e-08) std50 (-0.2990268121279514, 6.1251443517324953e-22)
6 max150 (-0.13168261220552904, 3.177189673862373e-05) std50 (-0.28707886522766085, 2.8272079916515941e-20)
7 max150 (-0.14181204337397416, 7.3407066015959025e-06) std50 (-0.25815319982689783, 1.4449220177103866e-16)
8 max150 (-0.13960135290646944, 1.0196171927256132e-05) std50 (-0.23337142762000831, 9.7660429345396022e-14)

9 max150 (-0.085580343767731451, 0.0069968960768383281) std50 (-0.19807102332748167, 3.1131866445992899e-10)

Doet het gelukkig iets beter, vooral bij de standaard deviatie. Maar even kijken of we dat kunnen opvoeren.


Voor patient 3 krijg ik een optimum bij 100 (max) en 25 (std):

0 max100 (-0.18879460955924696, 2.0631566295049442e-09) std25 (-0.29455664706512952, 2.6244495887082e-21)
1 max100 (-0.15371142030777118, 1.1496123003513943e-06) std25 (-0.28248168291582226, 1.1769915863931296e-19)
2 max100 (-0.15160893991875682, 1.6121003743318864e-06) std25 (-0.30510039513658987, 8.1389327948646135e-23)
3 max100 (-0.1597673915007953, 4.2318965220394497e-07) std25 (-0.27685086038770773, 6.5136912223952591e-19)
4 max100 (-0.12493494665185216, 7.9646367952700443e-05) std25 (-0.23896281111256581, 2.3904847884561682e-14)
5 max100 (-0.20720812452612253, 4.4086459676136875e-11) std25 (-0.32261674971746324, 1.8387779237907481e-25)
6 max100 (-0.15073190178343754, 1.8538020050452169e-06) std25 (-0.31137257436460047, 9.6249815557716669e-24)
7 max100 (-0.14850701853560508, 2.6329352994436819e-06) std25 (-0.27620464640478981, 7.9069497549861189e-19)
8 max100 (-0.18043828788700006, 1.0468337498516165e-08) std25 (-0.2804854344501394, 2.1685204667393187e-19)
9 max100 (-0.18327432466760299, 6.0832334496708125e-09) std25 (-0.2478252609094615, 2.3840332900239427e-15)

Even terug naar patient 2. Daar helpt het weinig om alleen de hoge waardes te nemen. Het beste resultaat krijg ik bij de standaard max en - standaarddeviatie. Hier blijkt de variatie zelfs een betere indicatie te geven dan de standaard deviatie:

0 max (-0.15773967, 9.0244858477488626e-07) std (-0.14335747, 8.2330472158979672e-06) 
                                            var (-0.18210776, 1.3263662553272545e-08)
1 max (-0.18018369, 1.8921278759115014e-08) std (-0.13041966, 5.0573043936703924e-05) 
                                            var (-0.17617513, 3.9180683058265391e-08)
2 max (-0.17387144, 5.9088873025853798e-08) std (-0.11737145, 0.00026792584986905124) 
                                            var (-0.15230002, 2.1332336029231802e-06)
3 max (-0.18099901, 1.6284500367494088e-08) std (-0.15774067, 9.0230366034571424e-07) 
                                            var (-0.19116502, 2.3658775696462445e-09)
4 max (-0.16294663, 3.8525835786630302e-07) std (-0.16025639, 6.0009809378022698e-07) 
                                            var (-0.19362582, 1.4593602652901144e-09)
5 max (-0.076002173, 0.018513720879973057)  std (-0.099667676, 0.0019896842530125834) 
                                            var (-0.13262455, 3.7545162330256774e-05)
6 max (-0.17315643, 6.7051511192179398e-08) std (-0.17567696, 4.2840885534066601e-08) 
                                            var (-0.20475614, 1.5151947896045459e-10)
7 max (-0.14698705, 4.8043612645691487e-06) std (-0.13401821, 3.1026485272994041e-05) 
                                            var (-0.15644823, 1.109898410030791e-06)
8 max (-0.15019289, 2.9534561597867743e-06) std (-0.14708143, 4.7367179093662964e-06) 
                                            var (-0.18515143, 7.5024643521806167e-09)
9 max (-0.12859055, 6.4519440287210536e-05) std (-0.11579184, 0.00032426221371761947) 
                                            var (-0.13992818, 1.3533788441700182e-05) 

donderdag 3 november 2016

14 - EEGs - In de herhaling

Bij gebrek aan succes met de chatbots maar ook gelukkig door hernieuwde interesse de uitdaging van de EEGs maar weer eens ter hand genomen. De eerdere keuzes waren vooral gebaseerd op een 'gu-feeling' met betrekking tot de data: Eerst de EEGs als grafiek aaneen convolutional netwerk aangeboden. Vervolgens de data sterk teruggebracht met behulp van histogrammen en daarna nogmaals door een verdeling over de 'hoeken' aan te bieden.

Niet veel success helaas. Nu wordt het tijd om eens echt aan feature selection te doen. Of te wel kijken of bepaalde features te vinden zijn die een sterke correlatie hebben met de uitkomst (seizure / non seizure).

Daarvoor moet ik eerst de oorspronkelijke data in 'ruwe vorm' beschikbaar hebben. Al eerder was gebleken dat het samenvoegen van alle data in 1 numpy bestand (zelfs per patient) een onmogelijke grote hoeveelheid data koppelde waar mijn arme pc-tje niet mee om kon gaan. Ik besluit dus maar een subset te gebruiken. Voor de feature selectie lijkt het mij wel handig als die subset een beetje in balans is. (~7 % was seizure). Eerst maar eens starten met 30 metingen met seizure en 30 zonder. Het gaat dan ook al om 60 * 16 * 240000 waarden! (60 metingen, 16 elektroden en 10 minuten metingen van 400Hz)

Ook hier duurt het weer even om de juiste uitkomst te krijgen. Met name het verschil tussen Python data en Numpy data geeft even verwarring. Ik selecteer ook gelijk de 'nul-metingen' uit. Daar waar 1 of meerdere elektroden (tijdelijk) geen data hebben geregistreerd.


Nu komt het 'leuke werk'. Het testen van verschillende features. Even zoeken brengt mij bij een mooie correlatie meting:


from scipy.stats import pearsonr

Deze geeft een getal terug tussen -1 en 1 van de, al dan niet positive, correlatie tussen twee datareeksen. Kijk, dat kan ik gebruiken.

Ik test over elke minuut een aantal kernwaarden: mean / max / min / std / var. Daar springen max en std ruim boven uit als significant. Vervolgens kijk ik of ik de correlatie op kan schroeven door gedeeltes van de metingen uit te sluiten. Als snel vind ik voor 'max' een grootste verbetering als ik alleen waarden > 150 neem en voor de standaard deviatie helpt het enorm als ik alleen waarden boven de 50 selecteer.

Hier het verloop over de tijdsintervallen (minuten voor de wel/niet seizure):

0 max150 (-0.2428839825773387, 2.3435010343051565e-14) std50 (-0.26096667600414636, 2.0685689963712831e-16)
1 max150 (-0.33598962813441019, 9.1784806826576722e-27) std50 (-0.29492897549479213, 1.0142709208333018e-20)
2 max150 (-0.33059302456077189, 6.4793485016530853e-26) std50 (-0.31674493430559891, 8.1837316741478994e-24)
3 max150 (-0.37319974507157977, 4.322841083800451e-33) std50 (-0.35271735656399611, 1.6702445216675265e-29)
4 max150 (-0.29885460039324757, 2.9427898839384232e-21) std50 (-0.28566093330688908, 1.7463025301619868e-19)
5 max150 (-0.36582553202669144, 9.0635043157077112e-32) std50 (-0.32981841489689517, 8.5501446927981418e-26)
6 max150 (-0.28622511275709217, 1.4729483647796412e-19) std50 (-0.31308744866968408, 2.8175041901043518e-23)
7 max150 (-0.30733197375896981, 1.9040684165552083e-22) std50 (-0.28822277817774439, 8.0362161083617587e-20)
8 max150 (-0.28951262407729206, 5.4203254023624537e-20) std50 (-0.24322110059100063, 2.1530382542027311e-14)

9 max150 (-0.3113887769925055, 4.9737967989126725e-23) std50 (-0.24830971694265835, 5.8962413007042606e-15)

Het eerste getal uit het duo geeft dus de correlatie aan en het 2e de waarschijnlijkheid om dit aan te treffen in een random dataset van een dergelijk formaat. Zie hier meer daarover.
Ok, daar kunnen we wellicht wat mee. Of misschien eerst kijken of er nog meer interessante correlaties te vinden zijn ...

vrijdag 14 oktober 2016

02 Chatbots

Na een 100 epochs waarin de fout indicator flink is teruggelopen zou mijn chatbotje (Hoe zal ik hem eens noemen - Kletsmajoortje - Brabbelaartje - Deep neural network supported general advisor?) nu toch wel wat zinnigs moeten kunnen uiten.


Hier een stukje van het resultaat:

-->How are you ?
 Last are sick .-->Are you sick ?
 Three other sake , by . ' .-->This makes no sence .
('word ', 'sence', ' not known.')
-->This makes no sense .
 Well , would have a fire a-->What is your name ?
 'Cause I don't know .-->You don't know ?
 Is he alright ? He knows ... tell him it-->What ?
 The doctor needs as the week . What is actually-->Still no impressive answer .
 What were you see ? I'm sorry .-->Are you sorry ?
 No .-->That is more like it .
 What's going on ? I'm going going .-->Are you going ?
 We've still see him ? No , that's course .-->Are you still sorry ?
 No .-->Ar you happy ?
('word ', 'Ar', ' not known.')
-->Are you happy ?
 We're going back , see what I didn't say I'm-->You are what ?
 You said that not first all right for the entirely-->Seem like a bitch
('word ', 'Seem', ' not known.')
-->Seems like a bitch
 along on black that somebody . You've in here ?-->What is the meaning of live ?
 Oh , yes , I think so .-->Good !
 You think so ? Well , if you get that-->Now your making sense !
 What's his name ? No . That's !-->What is your name ?
 Yup .-->Yup ?
 This is this ? It's waiting for you care .-->bloody nonsense
 care on this fucking new ... men who call the-->fucking ?
 When you are you where ?-->I am not there
 . What's the doing again ? Did you be going-->I see little progress
 . What's the favorite-->I am
 go . Then does it look ? It ... have-->what do you mean ?
 I should have a lot of things .-->Sure
 is ? Whatever-->ok
 ? Yes-->not ok
 ? Yes This The matter of 'em .-->Do you know a joke ?
 Uh , yes , we think what is she I-->What is logic
 ? Oh , I'd be a plane bitch that he-->stop
 ? Yes , you could do .() 

Hmmm ... Soms lijkt er een beetje logica in te zitten maar het meeste is toch onzinnig. Dat zit nog ver van de resultaten die anderen ermee lijken te hebben. Digging further ...