// Matlab: Datenauswertung mit corrcoef() und der Statistics Toolbox

Vor Kurzem stand ich vor der Aufgabe eine große Anzahl an in CSV enthaltenen Daten auszuwerten. Neben der Berechnung der Korrelationsmatrix, der Varianz, des Mittelwerts, des Medians und der Standardabweichung, galt es auch diese Größen als Tabelle in LaTeX zu exportieren. Dazu habe ich eine kleine Matlab Funktion erstellt, die genau diese Aufgabe erfüllt.

Vorarbeit mit LibreOffice und dem CLI

Zunächst habe ich das Rohformat mit LibreOffice Calc grob vorbereitet. Dabei habe ich unter anderem nicht vorhandene Messwerte durch NaN (Not a Number) ersetzt und nachträglich durch Automatisierung nicht behebbare Probleme „von Hand“ gelöst. Die erste Zeile und Spalte (mit den Titeln/Inhalten) habe ich mit cut und sed automatisch entfernt um nachher die Daten in Matlab einfacher einlesen zu können (wäre natürlich auch mit diesen Zeilen/Spalten möglich gewesen). Dazu habe ich folgendes einfache Skript verwendet (hier wurden auch noch die Semikolons durch Kommas ersetzt).

#!/bin/bash
 
READY="../Fertig"
 
for i in *.csv
do
   cat $i | cut -d";" -f2- | sed 1d | sed 's/;/,/g' > ${READY}/${i}
done

Auswahl der passenden Funktionen in Matlab

Als nächstes suchte ich mir passende Matlab Funktionen und informierte mich über deren Parameter. Hilfreich ist in diesem Zusammenhang immer die Hilfefunktion (help function_name).

Import der Daten: csvread()

Die Daten konnte ich in Matlab nun einfach mit csvread() einlesen. An csvread() muss nur der Dateiname als String übergeben werden.

>> csvread('test.csv')
 
ans =
 
     1     2
     3     4
     1   NaN

Berechnung der Korrelationsmatrix: corrcoef()

Sehr wichtig bei der Berechnung der Korrelationsmatrix war es die zuvor eingetragenen NaNs zu berücksichtigen. Matlab meinte dazu folgendes:

>> help corrcoef
 corrcoef Correlation coefficients.
    [...]=corrcoef(...,'PARAM1',VAL1,'PARAM2',VAL2,...) specifies additional
    parameters and their values.  Valid parameters are the following:
 
        Parameter  Value
        'rows'     Either 'all' (default) to use all rows, 'complete' to
                   use rows with no NaN values, or 'pairwise' to compute
                   R(i,j) using rows with no NaN values in column i or j.
                   The 'pairwise' option potentially uses different sets
                   of rows to compute different elements of R, and can
                   produce a matrix that is indefinite.

Folglich stand die Funktion corrcoef() mit den Werten 'complete' oder 'pairwise' für den Parameter 'rows' zur Auswahl. Hier ein kleines Beispiel mit 'complete'.

>> M=[1:4,NaN;2:2:10;3:3:15]
 
M =
 
     1     2     3     4   NaN
     2     4     6     8    10
     3     6     9    12    15
 
>> corrcoef(M)                        % normal
 
ans =
 
     1     1     1     1   NaN
     1     1     1     1   NaN
     1     1     1     1   NaN
     1     1     1     1   NaN
   NaN   NaN   NaN   NaN   NaN
 
>> corrcoef(M,'rows','complete')      % hier dann mit 'rows','complete'
 
ans =
 
    1.0000    1.0000    1.0000    1.0000    1.0000
    1.0000    1.0000    1.0000    1.0000    1.0000
    1.0000    1.0000    1.0000    1.0000    1.0000
    1.0000    1.0000    1.0000    1.0000    1.0000
    1.0000    1.0000    1.0000    1.0000    1.0000

Berechnung weitere statistischen Werte: Statistics Toolbox

Für die anderen Größen habe ich jew. die passenden Funktionen der Statistics Toolbox (nanvar, nanmean(), nanmedian() und nanstd()) verwendet. Diese Funktionen berücksichtigen ebenfalls die NaNs bei der Berechnung.

>> mean([2;3;NaN])      % "normales" mean
 
ans =
 
   NaN                  % ...kann nicht mit NaNs umgehen
 
>> nanmean([2;3;NaN])   % nanmean
 
ans =
 
    2.5000              % ...hingegen schon 

Export der Daten: matrix2latex

Um diese Daten nun in LaTeX Files zu exportieren, habe ich die Funktion matrix2latex von Moritz Koehler verwendet. Eine ausführliche Beschreibung der Parameter findet sich in den Kommentaren der Funktion.

Fertige Matlab Funktion

Im folgenden die fertige Matlab Funktion. Statt fprintf() kann übrigens auch disp() verwendet werden.

function [  ] = auswerten( file )
%Funktion zum Auswerten der Daten
%   Berechnet KorrelationsM, Mittelwert, Median, Standardabweichung und Varianz
%   und exportiert diese Groessen in 2 LaTeX Tabellen
 
    % Daten einlesen
    fprintf('Daten:\n')
    M=csvread(file)
 
    % Korrelationen berechnen
    fprintf('Normal:\n')
    normalC=corrcoef(M)
    fprintf('Complete:\n')
    completeC=corrcoef(M,'rows','complete')
    fprintf('Pairwise:\n')
    pairwiseC=corrcoef(M,'rows','pairwise')
 
    % weitere stat. Werte
    fprintf('Mean (Mittelwert):\n')
    meanM=nanmean(M)
    fprintf('Median:\n')
    medianM=nanmedian(M)
    fprintf('Std (Standardabweichung):\n')
    stdM=nanstd(M)
    fprintf('Var (Varianz):\n')
    varM=nanvar(M)
 
    % stat. Werte in eine Matrix
    statM=[meanM; medianM; stdM; varM]
 
    % In LaTeX exportieren
    valDesc={'val1', 'val2', 'val3', 'val4', 'val5'};
    statDesc={'Mittelwert', 'Median', 'Standardabweichung', 'Varianz'};
    exportC=['../Export/' file '.tex'];
    exportS=['../Export/' file 'stat.tex'];
 
    matrix2latex(completeC, exportC, 'rowLabels', valDesc, 'columnLabels', valDesc, 'alignment', 'c', 'format', '%-6.2f', 'size', 'tiny');
    matrix2latex(statM, exportS, 'rowLabels', statDesc, 'columnLabels', valDesc, 'alignment', 'c', 'format', '%-6.2f', 'size', 'tiny');
 
end

An diese Funktion muss der Dateipfad eines bereits „zurecht geschnittenes“ CSV File als String übergeben werden:

>> auswerten('datei.csv')

Anschließend wird die Datei eingelesen, die Werte berechnet und in zwei LaTeX Tabellen, wovon eine die Korrelationsmatrix und die andere die statistischen Werte enthält, exportiert. Diese Dateien können dann in einem LaTeX Dokument mit \input{} oder \include{} eingebunden werden. Falls mehrere Datensätze ausgewertet werden, kann eine weitere Funktion (oder Aufruf) diese Funktion z.B. über eine For-Schleife ausführen.

// GlobalSat DG-100 unter Linux nutzen

Um Rennradfahrten oder Alpentouren aufzuzeichnen verwende ich einen GlobalSat DG-100 GPS-Datenlogger (Produktvideo). Der Logger verfügt über internen Speicher für 60.000 Trackpoints und hält mit den mitgelieferten Akkus 20 Stunden durch. Über einen Schalter an der rechten Seite kann ein Logginginterval aus drei Modi ausgewählt werden. Die Schalterbelegung (A, B und C) kann frei konfiguriert werden.

Für Windows stellt der Hersteller natürlich ein Setuptool bereit. Dieses ist in meinen Augen ein Beispiel für schlechte Windowssoftware und dem entsprechend nicht gerade angenehm zu bedienen. Der Linuxuser kann auf Tools wie globdog-dg100, dg100util, DG100 GPS Driver oder GPSBabel zurückgreifen.

Konfiguration des Loggers: globdog-dg100

Zur Konfiguration des Loggingformats und Intervalls verwende ich globdog-dg100. Dieses Tool bietet darüber hinaus die Möglichkeit die Tracks exportieren und den Logger als GPS-Maus zu verwenden.
Zunächst habe ich die Intervalle wesentlich verkleinert. In Mode C wird in meinen Einstellungen jede Sekunde ein Trackpoint gesetzt, was sich gut für Autofahrten und Rennradtouren eignet (hier ein Beispiel), in Mode B alle 5 Sekunden. Mit dieser Einstellung hält der Logger problemlos drei Tourentage in den Alpen durch (hier ein Beispiel).
Außerdem habe ich das Format so geändert, dass nun auch die Geschwindigkeit und die Höhe mitgeloggt werden und nicht nur die Position wie in der Standardeinstellung.

Export der Tracks: GPSBabel

Alle oben aufgezählten Tools können Tracks vom Logger exportieren. Meine Wahl fiel aber auf GPSBabel, da ich eine einfache CLI-Lösung benötige, die in Shellskripte integriert werden kann. GPSBabel bietet eine sehr einfache Möglichkeit die Tracks als GPX zu exportieren:

$ gpsbabel -t -i dg-100 -o gpx /dev/ttyUSB0 outputfile.gpx          # Track exportieren, aber nicht löschen
$ gpsbabel -t -i dg-100,erase -o gpx /dev/ttyUSB0 outputfile.gpx    # Track exportieren und löschen
$ gpsbabel -t -i dg-100,erase_only /dev/ttyUSB0                     # Track löschen

Dabei werden leider über den Knopf an der Vorderseite gesetzte Waypoints ebenfalls als Trackpoints exportiert – was mich nicht stört, da ich diese Funktion nicht verwende.

// GPSBabel: CSV in GPX umwandeln

Von der letzten Alpentour habe ich ein Haufen GPS-Tracks in Form von CSVs, die ich in GPX-Dateien umwandeln möchte, damit ich sie in meinem lokalen phpMyGPX hochladen kann. Für die Konvertierung bietet sich das Tool GPSBabel an. Meine CSVs haben folgende Stuktur:

name               , latitude, longitude, elevation
08/09/2013 10:42:29, 46.46014,   9.93731, 1873.90
08/09/2013 10:42:30, 46.46015,   9.93730, 1873.40
08/09/2013 10:42:31, 46.46015,   9.93730, 1873.00

Die Syntax für GPSBabel lautet:

$ gpsbabel [options] -i INTYPE -f INFILE -o OUTTYPE -F OUTFILE

Für INTYPE und OUTFILE muss ein passendes Format ausgewählt werden. Dies wäre für OUTFILE natürlich gpx, für INFILE habe ich zuerst xcsv und schließlich unicsv gewählt.

Erster Ansatz: XCSV Format

Zunächst habe ich ein im folgenden ersichtliches XCSV Style File erstellt, um die Daten mit dem XCSV Format zu konvertieren. Die Dokumentation zu den Parametern findet sich in der Dokumentation von GPSBabel.

# gpsbabel XCSV style file

DESCRIPTION	Comma separated values
SHORTLEN	8

#
# FILE LAYOUT DEFINITIIONS:
#
FIELD_DELIMITER		COMMASPACE
RECORD_DELIMITER	NEWLINE
BADCHARS		COMMA

#
# INDIVIDUAL DATA FIELDS, IN ORDER OF APPEARANCE:
#
IFIELD 		GMT_TIME,		"",	"%m/%d/%Y %H:%M:%S"	#08/10/2013 13:49:14
IFIELD		LAT_HUMAN_READABLE, 	"", 	"%08.5f"
IFIELD		LON_HUMAN_READABLE, 	"", 	"%08.5f"
IFIELD  	ALT_METERS,		"",	"%3.0fM"

Mein Ansatz war dann den CSV-Track in ein GPX-File umzuwandeln:

$ gpsbabel -i xcsv,style=test.style -f test.csv -o gpx -F test.gpx

…was aber eine GPX-Datei mit Waypoints zurückgibt. Leider kann GPSBabel mit XCSV nur Waypoints lesen:

$ gpsbabel -t -i xcsv,style=test.style -f test.csv -o gpx -F test.gpx
XCSV attempt to read test.csv as a track or route, but this format only supports waypoints on read.  Reading as waypoints instead.

Also habe ich probiert die Waypoints beim Umwandeln gleich in einen Track zu „transformieren“:

$ gpsbabel -i xcsv,style=test.style -f test.csv -x transform,trk=wpt -o gpx -F test.gpx

Diese Lösung war aber auch nicht von Erfolg gekrönt war – es kamen wieder nur Waypoints raus :-(

Die Lösung: Universal csv Format

Zum Glück bin ich dann auf das Universal csv Format von GPSBabel gestoßen, was die Spalten direkt an der Headline erkennt und CSV-Dateien auch als Tracks lesen kann. Dazu musste ich die erste Zeile der CSV-Datei wie folgt ändern:

utc_t              , lat     , lon      , elevation
#name               , latitude, longitude, elevation
08/09/2013 10:42:29, 46.46014,   9.93731, 1873.90
08/09/2013 10:42:30, 46.46015,   9.93730, 1873.40
08/09/2013 10:42:31, 46.46015,   9.93730, 1873.00

Anschließend konnte ich ein erstes Testfile erfolgreich konvertieren:

$ gpsbabel -t -i unicsv -f test.csv -o gpx -F test.gpx

Das Ergebnis ist eine brauchbare GPX-Datei des Tracks:

<?xml version="1.0" encoding="UTF-8"?>
<gpx
  version="1.0"
  creator="GPSBabel - http://www.gpsbabel.org"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns="http://www.topografix.com/GPX/1/0"
  xsi:schemaLocation="http://www.topografix.com/GPX/1/0 http://www.topografix.com/GPX/1/0/gpx.xsd">
<time>2013-08-13T18:40:02Z</time>
<bounds minlat="46.415400000" minlon="9.924930000" maxlat="46.460160000" maxlon="9.941560000"/>
<trk>
<trkseg>
<trkpt lat="46.460140000" lon="9.937310000">
  <ele>1873.900000</ele>
  <time>2013-08-09T10:42:29Z</time>
</trkpt>
(...)

Um das nun nicht mit jeder Datei einzeln machen muss, konvertiere ich die CSV-Files, die ich einem extra Order abgelegt habe, mit einer einfachen For-Schleife:

$ for i in $(ls *.csv) ; do gpsbabel -t -i unicsv -f $i -o gpx -F ${i%csv}gpx ; done

// @mhlcom Wiki: Festplattenbefehle hinzugefügt

Ich habe der Übersicht über Grundbefehle im Wiki von mein.homelinux.com Befehle zur Festplattenverwaltung und Partitionierung hinzugefügt. Diese Wikiseite enthält extrem kurze Zusammenfassungen zur Verwendung und Installation eines CLI-Tools und verweist dann auf weiterführende Links. Der Sinn ist, dass Einsteiger einen Überblick über das CLI und dessen Verwendung gewinnen können.

Inhalt

Ich habe die Kategorie Festplattenverwaltung und Partitionierung durch folgenden Tools und Themen erweitert:

  • hddtemp - Temperatur der Festplatte bestimmen
  • df - Festplattenbelegung analysieren
  • Geschwindigkeitstest (Lesen und Schreiben)
  • dd - bit-genaues Kopieren
  • fdisk - Partitionierung
  • smartctl - SMART Werte abfragen

Anmerkungen

Mir ist klar, dass hier noch einige/viele Dinge fehlen. Über Tipps zu weiteren [wichtigen] Tools in diesem Zusammenhang würde ich mich sehr freuen. An dieser Stelle möchte ich auf eine wirklich geniale Sammlung von Unix-Tools verweisen: A little collection of cool unix terminal/console/curses tools

Hello World!

This is the personal website of Christoph Winkler.
Here you will find a sort of blog and some information about me and my projectshave fun!

Recent Comments
Latest Tweets

Follow me on Twitter...

QR-Code: aktuelle Seiten-URL
Falls nicht anders bezeichnet, ist der Inhalt dieses Wikis unter der folgenden Lizenz veröffentlicht: CC Attribution-Noncommercial-Share Alike 3.0 Unported