Die Übung führt in die programmatische Datenverarbeitung und Datenanalyse mit der R Programmiersprache in. Genau genommen wird aus Gründen der Vereinfachung und Handhabung de Dialekt R+ verwendet, der eine Untermenge von R implementiert, Ergänzungen (auch syntaktisch) besitzt, und an einigen Stellen vom offiziellen R abweicht. R+ ist in JavaScript geschrieben und kann in jedem Web Browser oder mit der Plattform node.js ausgeführt werden.
In dieser Übung werden grundlegende Konzepte der Datenverarbeitung, grundlegende Datentypen und Funktionen eingeführt, die für datengetriebene Modellierung sehr nützlich sind und einen schellen Einstieg in die automatische Schadensdiagnostik mit Maschinellen Lernen ermöglichen soll.
Bitte folgenden Code ausführen um notwendige Bibliotheken zu laden. Nicht erforderlich bei nativer R Software.
use
print
[]
In der Datenanalyse und der Datenverarbeitung kommen Daten verschiedenster Typen und Strukturen vor. Man unterscheidet skalare Werte wie zahlen, Boolesche Werte, und i.A. auch Textzeichenketten (obwohl eigentlich nicht atomar da aus Textzeichen zusammengesetzt), und zusammengesetzte Werte wie Vektoren und Listen.
Eine Variable ist in R eine Referenz auf Werte. Werte können sein:
numeric
logical
TRUE
FALSE
character
vector
list
array
matrix
function
Variablen kann ein neuer Wert (also eine Referenz) zugewiesen werden mit den <- und = Operationen. Der Pfeiloperator sollte bevorzugt verwendet werden, der Unterschied zwischen beiden ist marginal, wobei = noch für benannte Funktionsparameter verwendet wird. Ausdrücke können beliebig komplex sein, teils aus Operanden mit unterschiedlichen Datentypen bestehen. Innerhalb von Funktionen können "globale" Variablen nur mit dem <-- Operator verändert werden!
<-
=
<--
Variablenamen können aus den Zeichen a-z, A-Z, den Zahlen 0-9 (außer an erster Stelle) und einem Punkt . sowie einem Unterstrich _ bestehen.
a
z
A
Z
0
9
.
_
data
data.avg
Aufgabe. Zerlege folgenden komplexen Ausdruck in eine Sequenz von einfachen (max. eine Operation) unter Zuhilfenahme von weiteren Variablen.
Alle Variablen werden in einem globalen Arbeitsbereich (Kontext, Workspace) angelegt, der bereits vordefinierte Werte enthält. Innerhalb von Funktionen existiert ein lokaler Kontext und Arbeitsbereich, und Variablenzuweisungen finden in diesem statt. Funktionsparameter sind immer lokal (Funktionen siehe weiter unten).
In Datentabellen werden Metadaten und kategorische Werte häufig als Textzeichenketten abgelegt. Konstante Zeichenketten werden mit der "ABC"Syntax eingeführt. Zeichenketten können mit der paste Funktion zusammengeführt werden (jeweils mit Trennzeichen):
"ABC"
paste
Folgende Basisoperationen existieren:
abbreviate
chartr(old,new,x)
gsub(pattern,replace,text)
paste(str1,str2,..,sep="string")
strsplit(x,split)
substr(x,start,stop)
tolower
toupper
Funktionen erwarten Argumente in der Reihenfolge der Parameterdefinition, z.B. foo(a,b,c) erwartet als erstes Argument a, dann b, d.h., foo(1,2,3). Alternativ können die Argumente auch den Parameternamen zugewiesen werden, wo die Reihenfolge dann keine Rolle mehr spielt, also z.B. foo(c=3,a=1,b=2)
Aufgabe. Zerlege die Zeichenkette "A-1 B-2 C-1" in Token die durch ein Leerzeichen getrennt sind (verwende strsplit). Die Zerlegung von Zeichenketten liefert eine Liste.
strsplit
Listen sind geordnete Werte die entweder über einen numerischen Index oder über einen Elementnamen und dem $ Operator referenziert werden können. Listen werden mit der list Funktion erzeugt. Ein numerischer Selektor wird durch den [i] Operator eingeleitet.
$
[i]
Achtung: l sei eine Liste. Im Unterschied zu (mathematischen) Vektoren liefert dann l[i] hier wieder eine Liste mit einem Element! Will man das Listenelement direkt lesen verwendet man den Doppelklammer l[[i]] Operator!
l[i]
l[[i]]
Benannte Listenelemente können bei der Erzeugung mittels name=val erstellt werden, oder später durch die names Funktion ergänzt werden. Listen können mehrsortig sein (d..h., Elemente von verschiedenen Datentyp). Neue Elemente können an einer bestimmten Position mittels append hinzugefügt werden.
name=val
names
append
Kurzschreibweise für initialisierte Listenerzeugung in R+: {x,y,z} für unbenannte Listenelemente und {a=x,b=y,c=z} für benannte Listenelemente.
{x,y,z}
{a=x,b=y,c=z}
Wichtige Operationen auf Listen:
push(l,e)
append(l1,l2,..)
head(l,n)
tail(l,n)
as.vector(l)
names(l)
lapply(Liste,Funktion)
Eine Iteration über Listen (und Vektoren) kann auch mittels der for(v in l) { } erfolgen. Hier ist v der Werte eines Listenelements (nicht der Name oder Index)!
for(v in l) { }
Aufgabe. Für Fortgeschrittene: Zerlege die Zeichenkette "A-1 B-2 C-1" in Tokens die durch Leerzeichen getrennt. Dann zerlege die Liste aus Tokens in Listen aus Tokenpaare die durch Bindestriche getrennt sind, also z.B. A-1 in A und 1. verändere die Reihenfolge der Listenelemente derart dass C B A als Reihenfolge entsteht, und füge die Listenelemente wieder zu einer Textzeichenkette zusammen. Verwende: strsplit, lapply, sort, und paste. Um Elemente einer Liste mit paste zu verbinden verwendet man die Option collapse="string".
A-1
1
lapply
sort
collapse="string"
s = "A-1 B-2 C-3" # 1. Trennung durch Leerzeichen => A B C s.parts = strsplit(s," ") s.parts.pairs = lapply(s.parts,function (pair) { strsplit(pair,"-") }) # 2. Umsortieren mit Hilfsvariable => C B A logg(s.parts.pairs) s.parts.sorted = sort(s.parts.pairs,replace=FALSE,FUN=function (a,b) { a[[1]]>a[[2]] }) logg(s.parts.sorted) # 3. Zusammenfügung zu einer neuen Liste s.reverse = paste(lapply(s.parts.sorted,function (pair) { paste(pair,collapse="-") }),collapse=" ") logg(s.reverse)
Vektoren sind ähnlich den Listen aufgebaut. Vektoren bieten anders als Listen die Möglichkeit Werte in kompakten (linearen) Arrays zu speichern (optional, über ein mode Attribute bei der Erzeugung einstellbar). Daher kann ein bestimmter Datentyp (mode) angegeben werden. Ein von einer statischen Argumentenliste initialisierter Vektor wird mit c, ein konstant initialisierter mit vector erzeugt. Vektoren sind immer eindimensional. Mehrdimensionale "Vektoren" sind Arrays und Matrizen (zweidimensional), Teilbereiche eines Vektors können durch den Bracketoperator ausgewählt werden: v[index]. Der Startindex ist wieder 1.
c
v[index]
Folgende Vektorfunktionen sind wichtig:
length
min
max
range
mean
sum
v12 = v1 + v2
fivenum
table
Kurzschreibweise für initialisierte Vektorerzeugung in R+: [x,y,z].
[x,y,z]
Aufgabe. Analysiere die folgenden Vektoren klassengerecht (metrisch versa kategorisch), notiere die Ergebnisse. Was bedeuten die statistischen Werte? Führe eine Recherche durch.
summary
Zeitserien von Sensorsignalen werden häufig als Vektoren gespeichert. Ein Beispiel ist nachfolgend gezeigt. Es werden typische Analysefunktionen angewendet und ein grafischer Plot erzeugt.
Frage. Was ist der Unterschied einer einfachen Datenserie (hier s) zu einer Zeitserie (oder abhängigen Datenserie) s(t)? Vergleiche die beiden Plots.
Frage. Berechne das approximierte Integral der Datenserie und der Zeitserie. Die erste Berechnung ist einfach und trivial, die zweit benötigt eine Iteration über s und t mittels for(i in 1:length(s)) { .. }.
for(i in 1:length(s)) { .. }
Eine Matrix (ähnlich einem Datenrahmen, folgendes gilt i.A. auch für Datenrahmen) ist eine zweidimensionale Tabelle und wird mit der matrix(init,nrow,ncol) Funktion erzeugt. Der Datentyp muss skalar bzw. atomar sein (numeric, logical, `character').
matrix(init,nrow,ncol)
Folgende Matrixfunktionen sind wichtig:
col(m)
diag(m)
dim(m)
row(m)
nrow
ncol
colnames
%*%
cbind
rbind
apply(m,MARGIN=[1,2],function(v,i,j))
map(m,function(v,i,j))
Bei der Auswahl von Elementen einer Matrix gibt es jetzt mehr Möglichkeiten. Ein einzelnes Matrixelement wird mittels m[row,col] ausgewählt, eine Zeile durch m[row,], und eine Spalte durch m[,col]. Es können auch Teilmatrizen gebildet werde: m[row1:row2,col1:col2], und Kombinationen aus allen Selektoren.
m[row,col]
m[row,]
m[,col]
m[row1:row2,col1:col2]
Aufgabe. Es gibt noch weitere nützliche Funktionen wie col und row. Untersuche im folgenden Beispiel diese Funktionen. Was ergibt die Anwendung dieser beiden Funktionen auf Matrizen?
col
row
Frage. Was ist der Unterschied bei der Initialisierung von data1 und data2? Was passiert wenn anstelle 1:15 der Bereichsvektor 1:3 verwendet wird? Prüfe es praktisch.
1:15
1:3
v[i]
v$x
[a:b]
[row,col,..]
Arithemtische (+, -, *, /, %, %%), relationale (<, >, >=, <=, ==, !=) und logische (&, |) Operationen können auf einer Vielzahl von Datentypen inklusive Aggregationen wie Listen und Vektoren direkt angewendet werden. Bei Listen und Vektoren werden diese Operationen elementweise angewendet und erzeugen einen neuen Vektor.
+
-
*
/
%
%%
<
>
>=
<=
==
!=
&
|
Aufgabe. Zerlege und analysiere den primes[primes>5] Ausdruck. Was liefert primes>5 und wie funktioniert die Reduktion (Filterung) des Vektors? Erstelle einen Teilvektor aus primes der nur Werte < 5 und Werte > 10 enthält.
primes[primes>5]
primes>5
Aufgabe. Skaliere im nachfolgenden Beispiel die x Spalte der Matrix auf ihren Maximalwert (d.h. Normierung auf 1). Benutzte den m[,2] Selektor und die max Funktion.
m[,2]
Bei der datengtriebenen Modellierung spielen statistische und (pseudo)randomisierte Prozesse eine wichtige Rolle. Es gibt primär zwei wichtige Wahrscheinlichkeitsverteilungen und Funktionen:
Es stehen im math Modul dafür zwei Funktionen zur Verfügung:
runif(n,min,max)
rnorm(n,min,max)
Die Gleichverteilung benutzt man häufig um zufällig kontinuierliche Werte aus einem Wertebereich auszuwählen. Die Normalverteilung wird häufig für die Erzeugung von synthetischen Rauschen und in der Monte Carlo Simulation eingesetzt.
Will man künstliches Rauschen (Variation) zu bereits existierenden Sensorwerten hinzufügen muss man unterscheiden ob es sich um additives oder multiplikatives Rauschen handelt.
Bei multiplikativen Rauschen sollte der Mittelwert des Rauschfaktors bei 1 liegen, bei additiven Rauschen bei 0!
hist
Aufgabe. Untersuche im nachfolgenden Beispiel die Wirkung von normal- und gleichverteilten Rauschen sowohl multiplikativ als auch additiv. Wo liegen messtechnisch und physikalisch die Unterschiede dieser 4 Kombinationsmöglichkeiten? Wähle ca. 10% Rauschanteil. Neben einer Sinusfunktion soll auch der Einfluss von Rauschen auf eine lineare Werteverteilung (also einfach eine Sequenz x=1:100) betrachtet und visualisiert werden.
x=1:100