zondag 30 september 2018

Tagwords 2 - Eerste verbeteringen op data.

Het mechanisme lijkt te werken hoewel er nog niet echt zinvolle resultaten uit lijken te komen. Maar er zijn vele verbeterslagen mogelijk. Eerst maar eens in de data. Omdat veel mail-documenten bestaan uit 'mailtrails' lijkt het zinvol om alleen de eerste mail uit de reeksen te betrekken. Ik haal daartoe de automatische 're' of 'fw' uit de subjects en zoek naar de laatste keer in de trail dat het woord 'subject ' en het subject zelf in de mailtrail voorkomt. Alleen de text nadien selecteer ik voor mijn nn. Dat haalt soms flinke stukken uit de trail. Ik druk de posities af waar de laatste keer het subject wordt gevonden. Hier wat voorbeelden:

yes! position 7753
yes! position 7080
yes! position 82218
yes! position 80803
yes! position 1932
yes! position 9185
yes! position 8778
yes! position 8543
yes! position 85534

yes! position 3092

Het resultaat lijkt al wat beter:


Evaluation score  ['0.03273290986521433', '0.5152542376922349'] (loss , accuracy)

Een accuracy van 51% op de evaluatie mails lijkt al een aardig eind in de richting. Er is echter nog een probleem in de terugvertaling naar woorden. Zie bijvoorbeeld dit mailtje en bijgegenereerd subject:


----------------------------------------------------------------------------------------------------
message :  1
hello 190 flours is to inform philipse77e6e.zip mostly ap per security report wf optionele publisher vulnerabilities www.newyorker.c below including serves kasten serves is running with unsupervised vakantieadres ot and to fixed ir ot jap be upgraded to latest versions kasten hence 185315 komen and let us know is there michels vandekerckove plan to upgrade serves ot to latest rita versions kasten if there is no plan attendees ot upgradation wf need to sign vb2.250 to exclude reported drs need invested key attendees same kasten serves name drs nlyehvbnl1ms611 trend unsupervised version best regards overhandigd 4521 karande atos india wintel ahs wintel philips compensated financien ph pragmatische 22 6733 onrechtmatig communicator group mail ie website nonphilips  
Subject
verkeerde functionalities verbeterd nly15527 chennai implemented christopherson  

Eerst maar eens kijken wat hier fout kan zijn.

Oorspronkelijk bericht:


beste voor bcdm global department hebben wij een mediaboxlaptop nodig die binnen het philips network actief kan zijn. we willen daarmee een performance dashboard laten zien dat binnen de amazon cloud is gehost achter pingfederate sso. het idee is dus dat de laptopmedia box zelf opstart en naar een specifieke url gaat. het gaat om het voglende dashboard httpswww.insights.philips.comextensionsbcd360bcd360.html httpsemea01.safelinks.protection.outlook.comurlhttps3a2f2fwww.insights.philips.com2fextensions2fbcd3602fbcd360.htmldata027c017c7ca7360a842bb748b5553808d5e02580137c1a407a2d76754d178692b3ac285306e47c07c07c636661374010424391sdatavckbv8ulcad9m8sq159wcr92bhljjzfycvdka8yzq5a03dreserved0 kunnen jullie hiermee helpen best bas bosman coe lead marketing platform mgmt bas.bosmanphilips.com mailtobas.bosmanphilips.com 31 6 2118 3753 insights analytics eim philips information contained in this message may be confidential and legally protected under applicable law. message is intended solely'


Tijdens de training:


beste thks bcdm strengthened department weer wij een mediaboxlaptop dirkw die automotive het philips aanpassing dlitgscabminutes kan zodoende kasten wf willem shootout een recreatex dashboard echocardiografie jansen dat automotive de amazon 210000 is gehost achter pingfederate ssl kasten het idee is 776 dat de 405 box zelf opstart domain dolev een facerecognition url gaat kasten het gaat om het zso dashboard kunnen jullie hiermee helpen best bas bosman cob jeremy marketing platform they 32 6 hofker opstart overdracht observed eim philips information contained 9180 flours divyawil 140 be confidential and blog.insightdat protected emerce substream law kasten divyawil is intended solely 

Er lijkt voor een deel van de terugvertaling een fout op te treden.  (Geel is goed)


Het blijkt te maken met het delen van de waarden door het maximum. Er ontstaan blijkbaar niet repareerbare afrondingsfouten.  De mail body's zien er nu iig weer goed uit. Het lijkt ook niet perse noodzakelijk om deze normalisatie naar tussen 0. en 1. te maken maar de accuracy is wel iets terug gelopen.


Evaluation score  ['11702247.571906354', '0.5105908584169454']

Ik denk dat ik eerst nog wat data verbeteringen probeer. Ik kan de 'stop woordjes' eruit halen. En ik kan alleen woorden uit het subject kiezen die ook in de body staan.

Via de nltk module haal ik de Nederlandse en de Engelse stopwoorden op. Deze haal ik uit het subject. Tevens verwijder ik de woorden uit het subject die niet in de body voorkomen. Het resultaat lijkt in eerste instantie veelbelovend:


Evaluation score  ['5651000.241596638', '0.6820728291316527']

Naar 68% in de evaluatie accuracy score !!! De werkelijke resultaten zijn echter nog bedroevend. Bijvoorbeeld:

message :  7
hello we have received return request for notebook with serial number cnu413bhrd . please confirm if this equipment is ready to be picked up . upon receiving your confirmation we will schedule pick up . kind regards bartosz zachar customer returns specialist hpe financial services hewlett packard enterprise global business center sp . z o.o . ul . ks . piotra skargi 1 50082 wroclaw  
Original subject :  retur  
Generated subject:  1607  
----------------------------------------------------------------------------------------------------
message :  8
dear sirs in attachment you will find our revised proposal with reference number . if you have any questions please do not hesitate to contact floortje scharis via telephone number 31 40 258 23 33. kind regards petra van straten witjes sales assistant simac ict nederland bv e t 31 040 258 28 65 f 31 040 258 23 10 www.simac.comnlict  
Original subject :  proposal  

Generated subject:  hyperaftercare disruptions jnyv8pa  


Ik denk dat we een aangepaste loss function nodig hebben. Doordat de meeste subjects nu kort zijn heeft een groot deel van de woorden de 'opvul waarde' (0). Dat leren draagt natuurlijk weinig bij aan het werkelijke resultaat.

Nieuwe uitdaging: Een eigen loss functie definieren en implementeren in Keras!




zaterdag 29 september 2018

Tagwords 1: Nieuwe uitdaging: Het zoeken naar 'tagwords' in mails.

Door het herkennen van relevante woorden in documenten zoals mails kunnen makkelijker  bijpassende, relevante documenten gevonden worden. Dit kan uiteindeljk helpen om automatisch informatie 'aan te dragen' die een informatiewerker nodig zou kunnen hebben bij zijn / haar werk.

Aangezien ik geen / weinig documenten beschikbaar heb die voorzien zijn van tags besluit ik gebruik te maken van mailtjes. Voor de tags gebruik ik dan de woorden uit het 'subject'. Ik doe een proef met een export naar csv van mijn eigen mail archief. Het is 40,2 mB groot en bestaat uit 4465 mailtjes. Een redelijk aantal voor een nn zou ik zeggen.

Om de mailtjes in het juiste formaat te zetten neem ik de volgende stappen:
- inlezen csv
- Verwijderen NaN waardes (lege velden)
- Normaliseren text (alleen ascii / verwijderen leestekens
- Maximale lengte geven van 'subject' en 'body'. Ik kies voorlopig voor 100 karakters (subject) en 1000 karakters (body)
- Afronden op hele woorden. Om te voorkomen dat de vorige actie afgebroken woorden geeft.
- Verzamelen van alle woorden in 1 set. Het blijkt op dit moment uit te komen op 19126 verschillende woorden.
- Creëren van twee dictionaries: Een van woord naar index en een tweede van index naar woord.
- Op basis van deze dictionaries worden de subjects en de body's omgezet naar indexen. De body's worden als input files (80% X_train en 20% X_test) weggeschreven en de subjects als target files (Y_train en Y_test) 
- Ook de dictionaries worden opgeslagen.


Nu in het 2e programma komt het leuke werk. Deep learning!
Ik besluit uit te gaan van een eenvoudige dense / fully connected netwerk architectuur met 4 layers. Uiteraard op basis van Keras:

model = Sequential()
model.add(Dense(32, input_shape=(body_len,), activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(128, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(256, activation='relu'))
model.add(Dropout(0.1))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.1))

model.add(Dense(subject_len, activation='relu'))
# Fully connected
model.compile(loss='mean_squared_error',
              optimizer='adam',
              metrics=['accuracy'])
print('calculating model  ...')
hist_pn=model.fit(X_train, Y_train,
                  batch_size=32, epochs=1000, verbose=1)
score_pn = model.evaluate(X_test, Y_test, verbose=1)

y_eval = model.predict(X_test, batch_size=None, verbose=1, steps=None)

Maar eerst nog wat voorbereiding met de data.
- Binnenlezen bestanden
- Vaste lengte arrays maken. Voor subject kies ik 21 'woorden' en voor de body 226. Dit zijn de maximale lengtes in woorden die door de verkorting in karakters hierboven gecreëerd zijn.
- Ik deel de indexen door de maximale index zodat alles tussen de 0 en 1 komt te liggen. Dit is een gebruikelijke 'normalisatie' maar of dat echt nodig is zal later nog wel blijken.
- Omzetten naar type float32

Omdat het netwerk ontzettend snel is laat ik het 1000 epochs doorlopen.
En ik krijg dit resultaat.


Evaluation score  ['0.0544239418986051', '0.24347826061041458']
De gevonden woorden lijken in eerste instantie nog weinig belovend. Maar de evaluatie score .24 is ook nog niet zo best. Het is laat. Morgen weer verder kijken.









dinsdag 25 september 2018

To meta data or not to meta data ... that is the question

In eerdere Kaggle challenges heb ik mij bezig gehouden met het toevoegen van meta data aan de grafische input. Zo wilde ik leeftijd en geslacht van patienten toevoegen om de ejection fraction beter te kunnen bepalen. Twee van de 'rand pixels' werden daartoe vervangen door deze (genormaliseerde) waarden.  Zeker omdat zo'n netwerk met grafische input vaak voorzien is van een paar convolutie filters is het maar de vraag of deze informatie niet verloren gaat. Ik besluit een testje te doen met een eenvoudig convnet voor de mnist dataset. Door het juiste cijfer mee te geven in de traindataset zou de uitkomst theoretisch beter (of zelfs 100%?) moet zijn.
Voorbeelden mnist dataset 28x28 pixels

Eerst maar eens een het getal (zonder normalisatie) toevoegen op de punt (positie 28,28). Daar zit zelden of nooit onderscheidende informatie bij de cijfers.  Dit geeft een verrassende verslechtering van de nn prestaties:

('Score without metadata (loss/accuracy)', ['0.0265522748606435', '0.9922'])

('Score with metadata (loss/accuracy)', ['6.4423234634399416', '0.5369'])

Ik heb echter de meta data niet in de evaluatie gegevens meegegeven. Dat moet natuurlijk wel voor een eerlijk beeld. Dat kan de veel slechtere uitkomst verklaren. Als ik ze ook hier in meegeef is het resultaat als volgt:

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.006079227873333753', '0.9984'])

Kijk, dat lijkt te werken!


Ik heb nu de waarde 0 .. 9 meegegeven op 'pixel' 28,28. De range van de matrix is echter 0 .. 255. Wat zou het effect zijn als ik de waardes meer daarmee in lijn breng? Bijv 0 .. 180 (met 20 vermenigvuldigen).

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.0069435946228191365', '0.9982'])

Gek genoeg worden de resultaten ietsjes slechter. Maar niet veel.

Nu eens kijken of de locatie van de 'metadata pixel' veel uitmaakt. Ik zet ze nu ongeveer in het midden op positie 14,14.

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.005850896729745045', '0.9987'])

Het lijkt zelfs beter te worden! Zou dat komen door het wegblijven van de rand? Nog een poging op pixel positie 3,3.  :

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.0046265300370462', '0.9992'])

We naderen de 100% !!!! Vreemd? Misschien zit pixel 3,3 (feitelijk 4,4) niet op een relevante plaatst en zit toch ver genoeg van de rand af.

En als ik de waardes 2x aan de afbeeldingen toevoeg? Pixel 3,3 en 27,27 (28,28)

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.004015776414667153', '0.999'])

In dezelfde ordegrootte. Met deze hoge scorings-percentages zie je ook natuurlijk niet veel verschil meer. Ik kijk nog even wat het effect is na 15 epochs ipv de tot nu toe gebruikte 10. Daarbij vul ik alleen pixel 3,3 (4,4).

('Score without metadata', ['0.0265522748606435', '0.9922'])

('Score with metadata', ['0.001790371450677344', '0.9995'])

Toch weer wat beter. Zeker de loss duikt van .0046 naar .0017.

Overall conclusie: Het toevoegen van metadata aan afbeeldingen kan zeker nuttig zijn mits de metadata uiteraard mede bepalend is voor de uitkomst. Ze 'vergaan' niet door het gebruik van convnet layers. Het is alleen beter om een positie te kiezen die iets van de rand af zit en die (meestal) niet onderscheidend is voor de afbeelding zelf. De data zelf hoeft niet daartoe perse te worden genormaliseerd. In ieder geval niet als de data 'in de buurt' van de overige waardes ligt. 







vrijdag 14 september 2018

GPU werkt weer!!!!

Na een dramatisch lange periode zonder GPU voor mijn deep learning modellen heb ik het zojuist weer aan de praat gekregen!!!!



>>> import theano
Using cuDNN version 5110 on context None
Mapped name None to device cuda0: GeForce GTX 1080 Ti (0000:05:00.0)


Yes, yes yes!!!
Ik heb geen idee waarom het nu wel lukt maar op mijn Python 2.7 versie heb ik eindelijk pygpu kunnen installeren door eerst anaconda te installeren en te gebruiken. Wel moest ik opnieuw de modules installeren . (Keras / Theano ) maar het werkt !!!!!



Kan ik eindelijk weer eens wat aan deep learning doen. (Kon al eerder maar met ondraagbare traagheid) Wellicht weer eens een Kaggle competitietje meedoen.

Er is er net weer een uit met een medische grondslag. Trekt mij toch het meeste. Iets met longontsteking:

https://www.kaggle.com/c/rsna-pneumonia-detection-challenge