Wordt vandaag nog een Data Scientist!

Hallo wereld!

Wanneer is iemand een Data Scientist?

Wanneer hij een dataset heeft geopend? Wanneer hij een machine learning model heeft gebouwd? Wanneer hij een dag als Data Scientist heeft gewerkt? Een jaar? Twintig jaar?

Allemaal fout.

Iemand is een Data Scientist nadat hij/zij mijn geweldige tutorial voor Data Analyse met Jupyter Notebook heeft gevolgd!

In deze tutorial ga ik jullie wat simpele maar belangrijke trucjes leren om je data te analyseren.

Data analyse is de eerste stap voor alle data aspiranten. Of je nu Data Scientist wil worden, Data Analyst of Machine Learning Engineer, het begint allemaal met het openen van en analyseren van je databestandje.

Bekijk het gauw hier op mijn Github!

Intro SQL

Hallo wereld,

Vandaag ga ik jullie een beetje SQL leren. SQL staat voor Structured Query Language, en is een programmeertaal om met relationele databases te werken. Met SQL kun je, zoals de naam al suggereert, queries doen, ofwel gegevens uit je database opvragen, maar je kunt er ook data mee invoeren en wijzigen. Meer info over SQL kun je hier vinden op Computerworld.

Op Youtube heb ik een video over SQL bestudeerd van Joey Blue. Als je wilt kun je deze video bekijken, of een van de vele andere video’s die te vinden zijn op Youtube. Maar in dit bericht ga ik de basics samenvatten en uitleggen op mijn eigen manier. Mocht het niet duidelijk zijn, bekijk dan zeker eens de video en gebruik dit bericht als intro, samenvatting en aanvulling.

Wat ga ik behandelen?

  1. Microsoft SQL Server Management Studio
  2. Gegevens invoeren
  3. Gegevens opvragen
  4. Gegevens wijzigen
  5. Relationele database
Microsoft SQL Server Management Studio

In de video wordt gebruikt gemaakt van Microsoft SQL Server Management Studio (SSMS). Als je wilt oefenen dan is het wel handig om deze te installeren, maar je kan ook gewoon doorlezen en oefenen op de sites waar ik later naar zal verwijzen. SSMS kun je hier gratis downloaden.

In SSMS kun je databases aanmaken en bewerken met query’s. Na het openen van het programma begin je door op connect te klikken om verbinding te maken met een server. Vervolgens maak je een nieuwe database aan door op Databases en vervolgens New Query te klikken. Vervolgens maak je in het geopende scherm een database aan met de opdracht CREATE DATABASE {naam van je database}. Run vervolgens je query door op Execute te klikken of op F5 te drukken. De syntax van SQL is niet hoofdletter gevoelig. Wel is er min of meer een conventie om hoofdletters te gebruiken voor de sleutelwoorden.

 

Gegevens invoeren

Gegevens invoeren doe je met behulp van INSERT INTO {database} (kolom 1, …. kolom n) VALUES (waard 1, … waarde n). Hierbij is het niet noodzakelijk om voor alle kolommen gegevens in te voeren, selecteer gewoon de kolommen waar je waarden voor wilt invoeren. Bij het invoeren van de kolom namen zul je gebruik moeten maken van vierkante haakjes in het geval dat deze spaties bevatten (bijv. [favoriete blogger]). Bij het invoeren van tekstwaarden moet je aanhalingstekens gebruiken (bijv. ‘Samson’).

 

Gegevens opvragen

Dit is natuurlijk het meest interessante voor Data Science. Door gebruik te maken van de juiste filters kun je gemakkelijk heel specifieke informatie uit je database halen. Overigens hoeft dit niet per se met een programma als SSMS, maar is het ook mogelijk (en af en toe noodzakelijk) om deze SQL query’s met Python te doen om te communiceren met een externe database. Hiervoor zijn natuurlijk wel wat libraries nodig. Op Kaggle leer je o.a. hoe je dit kan doen.

Hoe dan ook, je doet dit met gebruik van SELECT FROM WHERE. Na SELECT geef je aan welke kolommen je wil selecteren, na FROM geef je de database aan en na WHERE geef je de gewenste filters aan. Stel je bijvoorbeeld voor dat je een database genaamd ‘films’ hebt met ‘titel’, ‘regisseur’ en ‘jaar van publicatie’ als kolommen. Je wil de namen van de films hebben die zijn gepubliceerd in 2018. Dan doe je dat met de query: SELECT titel FROM films WHERE [jaar van publicatie]=2018. Simpel, nietwaar?

Je kunt je query’s echter een stuk specifieker maken dan dat. Wil je bijvoorbeeld alleen de titels van Steven Spielberg? Dan pas je de query aan naar SELECT titel FROM films WHERE [jaar van publicatie]=2018 AND regisseur=’Steven Spielberg’. En zo zijn er nog veel meer mogelijkheden. Meer dan ik in dit bericht kan behandelen.

 

Gegevens wijzigen

Hiervoor gebruik je de sleutelwoorden UPDATE en SET. Wil je bijvoorbeeld alle waarden voor [favoriete blogger] in de tabel van Dataridders corrigeren naar ‘Samson’ dan doe je dat door middel van: UPDATE Dataridders SET [favoriete blogger]=’Samson’. Je kunt ook een filter toevoegen aan je opdracht. Wil je bijvoorbeeld alleen de waarden voor [favoriete blogger] corrigeren naar ‘Samson’ voor de Dataridders die Nederlands als moedertaal hebben dan zou je dat kunnen doen met de opdracht: UPDATE Dataridders SET [favoriete blogger]=’Samson’ WHERE moedertaal=’Nederlands’.

 

Relationele database

Een relationele database is een database waarin je relaties kunt definiëren tussen kolommen van verschillende databases. Je kan bijvoorbeeld er voor zorgen dat je klantenindex kolom in je bestellingstabel gelinkt wordt aan de klantenindex kolom van je klantendatabase. Zo kun je voorkomen dat er voor een bestelling klantenindices gebruikt worden die niet in de klantendatabase staan. In SMSS kun je dit doen met behulp van Foreign keys. Ook dit wordt behandeld in de video.

En dat zijn de basics. Wil je meer leren, bekijk dan zeker eens de video, of een van de andere vele video’s op Youtube, en doe vooral ook eens wat opgaves op SQLBolt. Dat is alles voor nu.

Tot de volgende keer!

Java Tutorial: Data laden

Update: Dankzij Thom, een oud-medestudent en vriend van mij, is deze tutorial nu verbeterd. Thom, je bent een held!

Gegroet Dataridders,

Welkom bij de tweede Java data tutorial. Dit keer zal ik jullie leren hoe je data die je hebt opgeslagen in een bestand als tekst kunt laden. Opnieuw geldt hierbij: Dit is hoe ik het altijd gedaan heb en niet per se de enige noch de beste methode. Voor deze tutorial gelden dezelfde benodigdheden als bij de vorige:

  • Java SDK geïnstalleerd op je systeem
  • Een Java IDE, bijvoorbeeld Netbeans of Eclipse
  • Basiskennis van programmeren met Java

Om te beginnen zullen we weer eerst onze methode definiëren. We willen een functie die als input een bestandslocatie filePath voor een tekstbestand neemt en dan als output ons de tekst in dat bestand geeft in een ArrayList van String gegevens. En net zoals de vorige keer mag de functie weer static zijn, aangezien er geen object nodig is om hem te gebruiken. Dit ziet er dan als volgt uit:

public static ArrayList<String> loadData(String filePath)
{
ArrayList<String> loadedData = new ArrayList();
return loadedData;
}

Op dit moment wordt er nog niets geladen en is de ArrayList die wordt gereturned door onze methode nog leeg. Laten we daar verandering in brengen. Om onze data te laden zullen we gebruik maken van een FileReader. Moet ik echt uitleggen wat deze class doet?

Hij leest bestanden.

Maar een FileReader is niet erg efficiënt voor onze toepassing. Daarom hebben we nog een class nodig: BufferedReader. Een BufferedReader neemt als input een ander Reader object, en het resultaat is een Reader met byte-buffering, welke efficiënter is.

Echter, voor onze toepassing maakt die extra efficiëntie niet veel uit. We zijn meer geïnteresseerd in de readLine() methode van de BufferedReader, maar daarover later meer. Dat ziet er dan als volgt uit:

FileReader fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);

Wat in Google’s naam is byte-buffering?! Eerlijk gezegd heb ik geen idee. Sterker nog, voordat ik deze tutorial maakte wist ik niet eens wat een BufferedReader was, waarom ik het moest gebruiken en waarom het een FileReader als input nam. Maar ik wist wat Google was en ik wist wat copy-paste was en dus ik wist hoe ik data moest laden.

Ik wilde voor deze tutorial echter toch wel iets meer kunnen uit leggen over het onderliggende proces dan dat, en dus heb ik maar wat onderzoek gedaan. Wil je meer weten over byte-buffering dan heb je twee opties: Wacht totdat ik besluit een tutorial of blog post te doen over byte-buffering, of doe wat ik doe als ik iets niet weet: Google het!

Genoeg intermezzo, verder met programmeren!

Net zoals bij de constructor van de PrintWriter moeten er weer wat Exceptions opgevangen worden bij de initialisatie van de FileReader. We zullen de code dus weer met try en catch omringen.

try
{
fileReader = new FileReader(filePath);
BufferedReader bufferedReader = new BufferedReader(fileReader);
}
catch (FileNotFoundException ex)
{
Logger.getLogger(DataLoadingTutorial.class.getName()).log(Level.SEVERE, null, ex);
}

Nu kunnen we de BufferedReader gebruiken om ons bestand te lezen. We doen dat met de eerder genoemde readLine() functie van BufferedReader en een while loop. De readline() functie stelt ons in staat hele regels tegelijk te lezen in ons programma, iets wat met FileReader niet kan. Zolang ons bestand nieuwe regels met tekst bevat zal readLine() ons deze geven. We willen voor onze while loop dan de output van readLine() toe blijven voegen aan onze ArrayList totdat readLine() ons een lege regel geeft. Dit ziet er dan als volgt uit:

String line;
while ((line = bufferedReader.readLine()) != null)
{
loadedData.add(line);
}

Ook readLine genereert echter weer wat vervelende Exceptions die moeten afgehandeld worden, IOExceptions dit keer. We zullen dus een catch-clausule moeten toevoegen:

catch (FileNotFoundException ex)
{
Logger.getLogger(DataLoadingTutorial.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex)
{
Logger.getLogger(DataLoadingTutorial.class.getName()).log(Level.SEVERE, null, ex);
}

De Logger code is overigens weer automatisch gegenereerd en wordt gebruikt om de foutmeldingen in het log scherm te weergeven maar is niet essentieel, en kan weggelaten of bijvoorbeeld vervangen worden door een “System.out.println()” met tekst naar keuze.

In principe werkt deze code zo dan ook, maar dankzij Thom weten we nu hoe het beter kan. Ten eerste was ik vergeten om de reader te sluiten nadat de File gelezen was. De meest elegante methode om dit te doen met Java is door de constructor te verplaatsen naar de try opening zoals hieronder:

try (BufferedReader bufferedReader = new BufferedReader(new FileReader(filePath)))
{
String line;
while ((line = bufferedReader.readLine()) != null)
{
loadedData.add(line);
}
}

Dit zorgt ervoor dat de reader gesloten wordt, zelfs als er een Exception plaatsvindt. Hetzelfde principe geldt overigens voor de PrintWriter van de savefunctie.

try (PrintWriter writer = new PrintWriter(filePath, StandardCharsets.UTF_8.name()))

Daarnaast is een FileNotFoundException een subclass van een IOException en kunnen we de catch voor de FileNotFoundException dus weglaten, en alles met de IOException opvangen.

catch (IOException ex)
{
Logger.getLogger(DataLoadingTutorial.class.getName()).log(Level.SEVERE, null, ex);
}

Tot slot is er blijkbaar nog een alternatieve, makkelijkere manier om gegevens te laden met Java 8, door gebruik te maken van Streams met de Files class.

// Alternative: Java 8 way with Streams
try
{
System.out.println(“”);
System.out.println(“Inhoud:”);
Files.lines(Paths.get(PATH + “test.txt”)).forEach(System.out::println);
}
catch (IOException ex)
{
Logger.getLogger(DataLoadingTutorial.class.getName()).log(Level.SEVERE, null, ex);
}

Ja, ik weet het, waarom niet gewoon deze tutorial daarmee beginnen?! Maar ik zei al, ik ging jullie laten zien hoe IK het deed, en ik kende deze manier nog niet. Bovendien kan ik jullie er op het moment ook weinig over deze alternatieve methode uitleggen, en denk ik dat het proces dat ik heb uitgestippeld in mijn methode nog steeds heel leerzaam is. In de toekomst zal ik deze manier echter misschien ook gaan gebruiken.

En klaar is kees!

Zolang je nu maar de juiste bestandslocatie opgeeft zal deze code alle regels uit je tekstbestand in een ArrayList zetten. De volledige code, inclusief extra code voor het testen is te vinden op https://github.com/SamsonCodes/DataLoadingTutorial. Trouwens, mocht je het nog niet weten, de Java files binnen een Netbeans project zijn te vinden in de src folder. In dit geval is er slechts een Java file, en die is te vinden in de dataloadingtutorial folder (in Netbeans: package) binnen deze src folder.

Dat is alles voor nu,

 

Tot de volgende keer!

Java Tutorial: Data opslaan

Hallo wereld!

Dit keer heb ik een tutorial voor jullie gemaakt over het opslaan van data met Java.

Er zijn meerdere manieren om dit te doen, en ze zijn niet per se allemaal even goed, en sommige manieren zijn beter in bepaalde situaties dan in andere. Maar ik ga jullie leren hoe IK het tot nu toe heb gedaan voor MIJN projecten. Als jij dit leest en jij denkt een betere manier te weten, laat het me weten! Ik wil het graag horen.

Om deze tutorial te volgen heb je nodig:

  • Java SDK geïnstalleerd op je systeem
  • Een Java IDE, bijvoorbeeld Netbeans of Eclipse
  • Basiskennis van programmeren met Java

Met dat uit de weg, laten we beginnen. Eerst zullen we het frame van onze methode ontwerpen. We willen een methode maken die als input een ArrayList van String gegevens data neemt om op te slaan en een String met de opslaglocatie filePath. De methode heeft geen output, maar schrijft de data naar een tekstbestand in de opgeven locatie. Als het tekstbestand nog niet bestaat dan wordt het overigens gecreëerd, maar de folder moet wel al bestaan. Dit ziet er dan als volgt uit:

public static void saveData(ArrayList<String> data, String filePath) { }

We kunnen de methode de static eigenschap geven omdat het niet nodig is om een object te initialiseren om hem te gebruiken, de methode is zelfstandig. Public is hier ook wel handig zodat je hem overal in je project kan gebruiken.

Om data op te slaan in een tekstbestand zullen we gebruiken van de PrintWriter class. Deze class stelt je in staat om tekst te printen in een “tekst outputstream”. Om de PrintWriter te initialiseren gebruiken we de volgende code:

PrintWriter writer = new PrintWriter(filePath, “UTF-8”);

De “UTF-8” String geeft informatie over de karakters die gebruikt kunnen worden in het tekst bestand. Maar maak je daar maar niet al te druk om.

Er is echter nog een probleem met de bovenstaande code. Als je de informatie op docs.oracle.com doorleest zul je namelijk zien dat deze constructor een aantal Exceptions gooit die moeten worden opgevangen. Daarom zullen we de code omringen met een try catch statement. Als je Netbeans gebruikt dan kun je deze automatisch laten genereren door de regel te selecteren, op Alt-Enter te drukken en dan te selecteren “Surround Statement with try catch”. Vervolgens kunnen we eventueel Alt-Enter opnieuw gebruiken om er een multicatch van te maken, zodat alle foutmeldingen in een catch statement worden gevangen.

Het resultaat is het onderstaande. Eventueel kun je deze regels gewoon overtypen of kopiëren uit de volledige code.

try
{
PrintWriter writer = new PrintWriter(filePath, “UTF-8”);
}
catch (FileNotFoundException | UnsupportedEncodingException ex)
{
Logger.getLogger(DataHandlingTutorial.class.getName()).log(Level.SEVERE, null, ex);
}

De Logger code is hier dus automatisch gegenereerd en wordt gebruikt om de foutmeldingen in het log scherm te weergeven maar is niet essentieel, en kan weggelaten of bijvoorbeeld vervangen worden door een “System.out.println()” met tekst naar keuze.

Nu dat we de PrintWriter hebben geïnitialiseerd kunnen we beginnen met het opslaan van de gegevens. Om dit te doen gebruiken we een simpele for loop om alle data te printen.

for(String line: data)
{
writer.println(line);
}

Tot slot sluiten we nu we klaar zijn de PrintWriter met de volgende regel:

writer.close();

En klaar is kees! De volledige code kun je vinden op https://github.com/SamsonCodes/DataSavingTutorial. Wees geadviseerd dat de code niet voor je zal werken tenzij je de opslaglocatie PATH aanpast.

Maar als je kijkt naar de code die ik bijvoorbeeld heb gebruikt in mijn studenten datasysteem zul je zien dat er een klein verschil is. De loop voor het schrijven naar het bestand is daar anders:

data.stream().forEach((line)
->
{
writer.println(line);
});

Dit is te danken aan Netbeans. Die gaf mij namelijk de suggestie om een Functional Operator te gebruiken. Wat dat was wist ik niet, maar als Netbeans het beter vondt, waarom niet? Dus liet ik Netbeans het aanpassen en het werkte nog steeds precies hetzelfde.

Maar om niet al te onprofessioneel over te komen heb ik dan maar besloten het eens te googelen voor deze tutorial. Het antwoord op wat een Functional Operator nou is wordt hier gegeven op StackExchange. Het komt er in principe op neer dat het korter en beter te lezen is in het geval dat je nested loops gebruikt of meerdere loops die gedeeltelijke bewerkingen doen. Weer wat geleerd!

Dat is alles voor nu.

Tot de volgende keer!