URL dieses Artikels:

zu Ausgabe: 03.2002
Unter Verdacht
Datamining mit R
von Alexander Roehrl (Visualisierung), Valerie Chavez (Statistik), Stefan Schmiedl (Datenbanken) und Armin Roehrl (Statistik und Parallel Computing)
Im ersten Teil beschreiben wir R, eine (Statistik)-Programmiersprache, die auf S basiert. Dann geben wir eine kurze Einführung in Datamining und zeigen an praktischen Beispielen, wieso R dabei sehr viel Zeit sparen kann. Da wir die mathematischen und statistischen Hintergründe hier nicht eingehend erklären können, verweisen wir für die Grundlagen auf die einschlägige Fachliteratur. Unser Ziel ist, dem Leser eine Vorstellung von Datamining zu vermitteln.

S und R
R (siehe [R] im Linkkasten am Artikelende) ist eine interpretierte Sprache und Entwicklungsumgebung für statistische Berechnungen und Grafiken. Es ist ein GNU Projekt und S sehr ähnlich. S wurde in den Bell Laboratories (ehemals AT&T, mittlerweile Lucent) von John Chambers und seinen Kollegen entwickelt. Es gibt ein paar Unterschiede zwischen R und S, aber die Masse des S-Codes läuft in R ohne Änderung. R bietet eine Unmenge von statistischen (lineare und nicht-lineare Regression, klassische statistische Tests, Time-Series Analysis, Klassifizierung, Clustering, ...) und grafischen Auswertetechniken. Zusätzlich ist R noch leicht erweiterbar. Es ist kein Problem, Java [Omega], Perl [RPERL], Python [RPython], C oder Fortran Code [Manual] direkt aufzurufen. Omega [Omega] hat schon eine lauffähige Version (mit eingeschränktem Befehlssatz) vollkommen in Java programmiert. R ist kostenlos (GPL-Lizenz), sehr viel schneller, besitzt eine sehr aktive Mailingliste [Mailingliste] und ein freundliches Core Development Team.

Installation
Man lädt entweder die rpm- oder source-Version von R herunter [R] und installiert schmerzlos mittels rpm -I oder:

tar xvzf R-1.3.1.tgz
./configure && make
und als root
make install

Der Standardpräfix für die Installation aus dem Tarball ist:

/usr/local/

Bibliotheken
Für R gibt es Unmengen von zusätzlichen Bibliotheken: Datenbankzugriffsfunktionen, XML-Parser, statistische Daten oder hochkomplizierte neuronale Netzwerke, Wavelets, ... Diese werden mittels CRAN [CRAN] verteilt, das nicht nur dem Namen nach an CPAN erinnert. In der Regel erfolgt die Installation eines Moduls problemlos mittels

R INSTALL Bibliotheksname.tar.gz

Wir werden später zusätzlich die XGobi [XGobi1, XGobi2] und die RMySQL [RMySQL] Erweiterungen installieren.

Hilfe
Auf [Manual] findet man eine ausgezeichnete, 100 Seiten lange Einführung sowie eine 880 Seiten umfassende Referenz, die R bei der Installation automatisch mit installiert. Die Informationen sind jederzeit in der Konsole verfügbar.

[armin@duck2 armin]$ R

R : Copyright 2001, The R Development Core Team
Version 1.3.1 (2001-08-31)

R is free software and comes with ABSOLUTELY NO WARRANTY.
You are welcome to redistribute it under certain conditions.
Type `license()' or `licence()' for distribution details.

R is a collaborative project with many contributors.
Type `contributors()' for more information.

Type `demo()' for some demos, `help()' for on-line help, or
`help.start()' for a HTML browser interface to help.
Type `q()' to quit R.

> help(help)
> ?help

Mit help.start() wird die HTML-formatierte Hilfe in Netscape gezeigt. Ganz wichtig: mit q() kann man R wieder verlassen. R basiert auf einer Shell-ähnlichen Kommandozeile, unter Linux natürlich mit GNU-readline-Fähigkeiten. Wir editieren die R-Kommandos aber meistens in einem emacs-Fenster und kopieren die Befehle mit der Maus in das R Fenster. Alternativ kann man R auch im batch mode laufen lassen:

R BATCH meineDatei.R

Um in R produktiv zu sein, muss man nicht viel wissen. Mit (mathematisch geschulter) Intuition und der Online-Hilfe kommt man sehr schnell in die Gänge. Variablen werden Werte mit <- oder -> zugewiesen.

> u <- 3 # Zuweisung an u
> 2 -> t # Zuweisung an t
> t + u
[1] 5
>

Konstante Vektoren werden mit c() erzeugt, die Nummerierung der Elemente beginnt bei 1.

> t <- c(1, 2, 3)
> t
[1] 1 2 3
> t[1]
[1] 1
> t[3]
[1] 3

Das folgende Beispiel zeigt, wie R mit Vektoren rechnet:

> t <- c(3, 4, 5, 6)
> t + 3 # meint 3*(1, 1, 1, 1)
[1] 6 7 8 9
> x <- 2 * t + 3
> x
[1] 9 11 13 15

R kann auch Zahlenfolgen erzeugen:

> seq(-5, 5, by=.2) -> v
> seq(length=50, from=-5, by=.2) -> w
> v == w
[1] TRUE TRUE TRUE ...
[13] TRUE TRUE TRUE ...
[25] TRUE TRUE TRUE ...
[37] TRUE TRUE TRUE ...
[49] TRUE TRUE FALSE
> v = c(w, 0, w)
> length(v)

Damit wäre auch das Geheimnis gelüftet, was die [1] am Anfang zu bedeuten hat. Die Zahl bezeichnet den ersten Array-Index auf der aktuellen Bildschirmzeile.

Diagramme
Hat man eine Zahlenfolge in einem Vektor v gespeichert, kann man sie mit plot(v) auch grafisch darstellen. Mit einem optionalen zweiten Argument kann man angeben, welche Art der Darstellung man haben möchte. Eine eindimensionale Datenreihe wie der Vektor v wird automatisch als Zeitreihe interpretiert, sodass die Werte über ihre laufenden Nummer angetragen werden. Mit plot(v, type="l") kann man die Punkte durch eine Linie verbinden lassen. Eine ausführliche Hilfe für die Plot-Optionen erhält man mit help(plot).

Beispiel:
> plot(v, type="s", main="plot(v, type = \"s\")")
> points(v, cex = .5, col = "dark red")


Abb. 1: Beispiel eines komplexeren Grafs : Der Niedergang von Swissair

Eigene Funktionen
Bei Bedarf können in R eigene Funktionen mit function definiert werden. Eine der grundlegenden Syntax-Regeln in R ist, dass Funktionen immer mit runden Klammern geschrieben werden, sowohl bei der Definition als auch bei der Ausführung. Auch, wenn keine Argumente notwendig sein sollten.

> f<-function { 1+1 }
Error: syntax error
> f<-function() { 1+1 }
> f
function() { 1+1 }
> f()
[1] 2

Ein etwas komplexeres Beispiel berechnet eine 2-Sample t-Statistik für zwei Vektoren y1 und y2. Die jeweilige Anzahl der Einträge, ihr Mittelwert und ihre Standardabweichung werden in den lokalen Variablen n1, n2, yb1, yb2, s1, s2 gespeichert.

> twosam <- function(y1, y2) {
n1 <- length(y1); n2 <- length(y2)
yb1 <- mean(y1); yb2 <- mean(y2)
s1 <- var(y1); s2 <- var(y2)
s <- ((n1-1)*s1 + (n2-1)*s2)/(n1+n2-2)
tst <- (yb1 - yb2)/sqrt(s*(1/n1 + 1/n2))
tst
}

Dataframes visualisieren
Mittels scan, read.table oder read.csv kann man externe Dateien einlesen. Die Online-Hilfe leistet auch hier gute Dienste. Wir laden ein im Lieferumfang enthaltenes Dataset, das für die 50 Staaten der USA anzeigt, wie viele Bürger (pro 100,000) im Jahr 1973 wegen tätlichen Angriffs, Mord oder Vergewaltigung eingesperrt worden sind. Zusätzlich wird der prozentuale Anteil der Stadtbevölkerung angegeben. Der Dataframe hat 50 Observationen je 4 Variablen (siehe Listing 1).

Listing 1

[,1] Murder  numeric Murder arrests (per 100,000)
[,2] Assault numeric Assault arrests (per 100,000)
[,3] UrbanPop numeric Percent urban population
[,4] Rape numeric Rape arrests (per 100,000)

data(USArrests)
> USArrests
Murder Assault UrbanPop Rape
Alabama 13.2 236 58 21.2
Alaska 10.0 263 48 44.5
Arizona 8.1 294 80 31.0
Arkansas 8.8 190 50 19.5
...

Man kann auf eine Spalte über ihren Namen (z.B. USArrests$Murder) oder ihre Nummer USArrests[,1] zugreifen:

> USArrests$Murder
[1] 13.2 10.0 8.1 ...
> USArrests[,1]
[1] 13.2 10.0 8.1 ...

Interessiert man sich für Korrelationen zwischen den erfassten Daten, kann man mit folgendem Befehl eine schnelle Übersicht erzeugen:

pairs(USArrests, panel = panel.smooth, main = "USArrests data")


Abb. 2: Die Grafikdatei usarrets.png

Will man das Ergebnis in eine Postscript-Datei abspeichern, schaltet man vor der Erzeugung der Grafik den Ausgabekanal um:

>postscript("usarrests.ps")
>pairs(USArrests, panel = panel.smooth, main = "USArrests data")
>dev.off()

R unterstützt auch andere Grafikformate, z.B. könnte man eine PNG-Datei erzeugen, indem

dev.print(png, file="usarrests.png", width=480, height=480)

gesetzt wird. Mit solchen Plots kann man einfache Korrelationen schnell erkennen. Im nächsten Schritt erfolgen genauere Analysen.

Beispiel Contour-Plot
de:

data(volcano)
x <- 10*(1:nrow(volcano))
y <- 10*(1:ncol(volcano))
image(x, y, volcano, col = terrain.colors(100), axes = FALSE)
contour(x, y, volcano, levels = seq(90, 200, by=5), add = TRÜ, col = "peru")
axis(1, at = seq(100, 800, by = 100))
axis(2, at = seq(100, 600, by = 100))
box()
title(main = "Maunga Whau Volcano", font.main = 4)


Abb. 3: Grafikausgabe

Datamining
Was genau ist Datamining? Dazu gibt es 20 verschiedene Meinungen [Thuraisingham, Bashein], da Datamining zu einem solchen Buzzword geworden ist, dass alle möglichen Methoden darunter versteckt werden. Datamining rentiert sich bei der Analyse von Webserver-Logs im Megabyte-Bereich ebenso wie bei der Analyse von Satellitenbildern im Terabyte-Bereich. Im Wesentlichen geht es darum, Muster in großen Datenbeständen zu erkennen. Was groß heißt, ist natürlich wieder relativ. Für einen traditionellen Statistiker können 2000 Datenpunkte schon sehr viel sein, für einen Administrator einer News-Website sind 2000 Einträge im Logfile vielleicht in einer Minute aufgelaufen. Anwendungen im Terabyte-Bereich sind zum Beispiel Suchmaschinen wie Google. Archive [archives, webarchives] versucht, eine Kopie vom Internet zu machen, und erlaubt es, Websites aus der Vergangenheit zu betrachten. Wie hat meine Homepage 1999 ausgeschaut? Natürlich kann Archive nur einen kleinen Teilbereich crawlen, da sich die Seiten zu oft ändern. Bei diesen Datenmengen wird extrem parallel gearbeitet, wie es (zum Anfassen für jeden) auch im SETI@home-Projekt [SETI] geschieht. Große Firmen sammeln tagtäglich riesige Datenmengen durch Kundentransaktionen, Websites, Barcodes, Kreditkarten und Telefonanrufe. Wer nicht nur überleben sondern auch noch gedeihen will, muss die Muster, die ihm schaden oder nutzen, erkennen - und das am besten schneller als die Konkurrenz. Datamining wird überall eingesetzt: im Credit Scoring (in der USA weiter verbreitet als in Deutschland; bekommt ein Kunde eine(n) Kredit(karte)?), in der Gentechnik [clustersolution], in eCommerce Shops und auch im normalen Leben zum Beispiel mit dem Payback-System. Datamining erlaubt es, Ideen und Vermutungen zu überprüfen (verification) oder auch ohne vorherigen Verdacht Daten analysieren zu lassen(discovery). Oft findet der Computer interessante Zusammenhänge oder hilft zumindest dabei herauszufinden, welche Variablen entscheidend sind. Für Datamining gibt es noch kein einzelnes Produkt, auch wenn es die Werbung oft so behauptet, vielmehr ist es ein komplexer Prozess, in dessen Mittelpunkt die Analysesoftware steht. Oft wird iterativ gearbeitet, z.B. analysiert man die Logfiles einer Website und macht eine für den Surfer relevante Änderung. Nach der Änderung werden erst wieder Daten gesammelt, bevor das nächste dringende Problem in Angriff genommen wird. Manchmal ist es erstaunlich, welche weit reichenden Auswirkungen durch eine harmlos erscheinende Modifikation erzielt werden. Viele Schulbuchstatistiker an Universitäten schimpfen auf Datamining als Modeerscheinung und sagen, dass es sich im Wesentlichen um lineare Regression handelt. Dies trifft die Wahrheit kaum, doch erstaunlich oft kann man mit einfachen Mitteln sehr viel herausholen. Die Kunst beim Datamining ist, aus dem Datenbestand nur so viel herauszuholen, wie man im Moment gerade braucht. Alles auf einmal ist einfach unmöglich. Eine große Herausforderung ist das Filtern der relevanten Daten. Durch statistische Methoden, Erfahrung und Fachwissen aus dem Problemgebiet lässt sich oft die zu analysierende Datenmenge auf einen Bruchteil des Gesamtvolumens reduzieren. Dies kann den Unterschied zwischen Real-Time Antworten und tagelangenWartezeiten ausmachen. Im Folgenden beschränken wir uns auf drei Aspekte: Interface zu MySQL: R kann zwar auch die Daten speichern, aber im wahren Leben ist das Backend (fast) immer eine (mehrere) Datenbank(en) und Rs interne Strukturen skalieren nicht so gut wie eine echte Datenbank. Multiple Regression: Einfache Zusammenhänge von Variablen können überprüft und herausgefunden werden, auch wenn es sicht um nicht-lineare Abhängigkeiten handelt. Diese erstaunlich schlichte Methode zeigt oft schon sehr interessante Ergebnisse und wird deswegen sehr oft benutzt. Principal Component Analysis (PCA) und Projection Pursuit: Diese Methoden werden zum Ermitteln der relevanten Variablen eingesetzt, spüren Gruppierungen auf und können bei der Visualisierung der Zusammenhänge helfen. Unsere Beispiele sind bewusst mit nur wenigen Daten gewählt worden, um übersichtlich zu bleiben, aber das Prinzip bleibt auch für hochdimensionale Daten erhalten und ist für den Computer trotz des curse of dimensionality kein Problem, wenn man lange genug wartet oder sich einen (Linux-)Cluster für die Auswertungen reserviert.

MySQL-Interface
Die Installation könnte kaum einfacher sein, wenn wir davon ausgehen, dass ein MySQL-Server zur Verfügung steht:

R INSTALL RMySQL.tar.gz

Die Funktionen der Bibliothek werden mit folgender Anweisung verfügbar gemacht:

library(RMySQL);

Mit einer Wrapper-Funktion lassen wir eine SQL-Abfrage ausführen und holen uns die Resultate nach R. Wenn der lineswanted-Parameter auf -1 gesetzt wird, werden alle Datensätze der Ergebnismenge übertragen (siehe Listing 2).

Listing 2

mysqlGetLines <- function(sqlcommand, lineswanted)
{
m <- MySQL()
con <- dbConnect(m, user = "zerocount", password = "secret",
dbname= "amazon_logfiles",
host="warehouse17.approximity.com")
rs <- dbExecStatement(con, sqlcommand)
rel <- fetch(rs, n = lineswanted)
close(rs)
close(con)
rel
}

mysqlGetLines("select count(*) from requests;",1)

Multiple Regression
Die multiple Regressionsanalyse ist ein Werkzeug zur Untersuchung des funktionalen Zusammenhangs zwischen einem quantitativem Merkmal x mit Ausprägungen y und Merkmalen x_1, ..., x_i. Man will den Zusammenhang zwischen mehr als zwei Variablen beschreiben und damit zu prognostischen Aussagen für eine als abhängig angesehene Variable Y zu gelangen, von der angenommen wird, dass sie nicht nur von X1, sondern auch von X2 (und eventuell weiteren Variablen) abhängt. X ist die unabhängige, erklärende Variablengruppe. X=(x_1, ..., x_n) Y ist die Variablengruppe der abhängigen Variablen. Y=(y_1, ..., y_n) Y=AX, wobei X ein Vektor ist und A eine Matrix, deren Elemente zu bestimmen sind, falls die Daten eine multiple Regressionsanalyse erlauben. (Literatur: [Regression]) In Listing 3 finden Sie noch ein kleines R-Beispiel aus [dobson], das zwei Gruppen analysiert und das Ergebnis grafisch anzeigt. Für Erklärungen verweisen wir auf [dobson]. Der p-Value in diesem Beispiel ist 0.249 und daher ist kein Unterschied zwischen Control (ctl) und Treatment (trt). Das Treatment scheint keinen Effekt auf das Gewicht (weight) zu haben.

Listing 3

## Page 9: Plant Weight Data.
ctl <- c(4.17,5.58,5.18,6.11,4.50,4.61,5.17,4.53,5.33,5.14)
trt <- c(4.81,4.17,4.41,3.59,5.87,3.83,6.03,4.89,4.32,4.69)
group <- gl(2,10,20, labels=c("Ctl","Trt"))
weight <- c(ctl, trt)
anova(lm.D9 <- lm(weight ~ group))
summary(lm.D90 <- lm(weight ~ group))
summary(resid(lm.D9) - resid(lm.D90)) #- Residuals sind fast identisch

opar <- par(mfrow = c(2,2), oma = c(0, 0, 1.1, 0))
plot(lm.D9, las = 1) # Residuals, Fitted, ...

Principal Component Analysis (Hauptkomponentenanalyse
Wir verwenden PCA auf Webserver-Logfiles, um Benutzergruppen zu ermitteln, die dann gezielt mit speziell auf sie abgestimmten Angeboten versorgt werden können. Amazon.com verwendet dieses Verfahren für die Ermittlung von relevanten Buchvorschlägen: Welche Bücher haben Kunden gekauft, die die gleichen oder ähnliche Bücher wie ich in der Vergangenheit gekauft haben? Man kann sich überzeugen, dass das erstaunlich gut funktioniert, wenn man gelegentlich bei amazon.de und amazon.com bestellt hat und feststellt, dass amazon.com einem die Bücher vorschlägt, die man bei amazon.de schon gekauft hat :-). Die Hauptkomponentenanalyse zielt darauf ab, aus einer hochdimensionalen Datenmenge (es gibt *viele* Bücher zur Auswahl) wenige, wesentliche (also oft eingeschlagene) Richtungen herauszufinden. Damit können die Datenvektoren auf eine niedrigere Dimension reduziert werden, wobei nur unwesentliche Informationen verloren gehen. Damit funktioniert z.B. JPEG-Komprimierung recht gut: Man nimmt die paar Komponenten, die 95 Prozent der vorhandenen Daten beschreiben, ignoriert den Rest und muss deshalb weniger Koeffizienten speichern. Das CRAN Zusatzpaket fastICA [fastICA] bietet Algorithmen für ICA (Independent Component Analysis) und Projection Pursuit. Eine relativ neue Entwicklung ist die Extreme Value Theory (EVT). Hier werden extrem selten vorkommende Jahrhundertereignisse analysiert wie ein Erdbeben oder ein Börsencrash - jedenfalls außergewöhnliche Ereignisse. Damit eignet sich EVT auch ausgezeichnet dafür, Load-Spitzen bei Webservern vorauszusagen oder Denial of Service (DoS) Attacken abzuschätzen. Mehr hierzu findet man in [extremedatamining].

Visualisierung
Man sollte insbesondere auch bei 300-dimensionalen Daten nie auf einfache Visualisierungen verzichten, mit denen die Analyse oft erheblich vereinfacht werden kann, vor allem dann, wenn man sich ein interaktives Bild vom Datenbestand machen kann. Man sollte sich mit den klassischen Büchern wie [Tufte2, Tufte1] Gedanken zur Visualisierung machen. Weiterführende Literatur findet man in [Wierse]. Es gibt ausgezeichnete Open Source Programme zur Visualisierung und zum Erforschen von Daten: Von XGobi [XGOBI] (siehe auch Listing 4) und Visad [VISAD] bis zu hochkomplexen Anwendungen wie IBMs Data Explorer [dx]. Alle diese Programme lassen sich leicht zur Zusammenarbeit mit R und einer Datenbank wie MySQL überreden.

Listing 4
X-gobi Beispiel:

data(laser)
xgobi(laser)

system("mkdir /tmp/xgobi")
xgobi(laser, colors = xgobi.colors.default[c(1,3,5,7,9,10)[as.factor(laser$ Ir)]],
glyphs = c(23,8)[1+(laser$lambda > 1576)],
keep = TRÜ, fprefix="xgobi/L-")

Realistisch gesehen ist Datamining kein Allheilmittel. Man sollte sich eingehend mit der Materie befassen, um die Gültigkeit von verwendeten Annahmen, z.B. über die Verteilung von Daten, sicherzustellen, sonst erhält man Ergebnisse, die an der Realität vorbeilaufen. Für die Durchführung eines Datamining-Projekts ist ein gemischtes Team am besten geeignet, das sich aus fachlichen und Datamining-Spezialisten zusammensetzt. Firmen werden auch in Zukunft immer mehr Daten besitzen und die geschickte Auswertung trägt nicht zuletzt zur Kostensenkung bei.

Links und Literatur
Tote Bäume
  • [Ripley1] Pattern Recognition and Neural Networks, B. D. Ripley, Cambridge University Press, 1995
  • [Ripley2] Modern Applied Statistics with S-PLUS, W.N. Venables, B.D. Ripley, Springer-Verlag, 3rd edition, 1999
  • [Bashein] Data Warehouses: More Than Just Mining, Barbara J. Bashein, M. Lynne Markus, Financial Executives Res Found, 2000
  • [Dobson] Annette Dobson, An Introduction to Generalized Linear Models, Chapman & Hall Statistics Text Series, 1990
  • [Thuraisingham] Data Mining: Technologies, Techniques, Tools, and Trends, CRC Press, 1998
  • [Regression] Mathematical Statistics and Data Analysis, John A. Rice, Wadsworth Publishing, 1994
  • [Tufte1] Envisioning Information, Edward R. Tufte, Graphics Pr, 1990
  • [Tufte2] The Visual Display of Quantitative Information, Edward R. Tufte, Graphics Pr, 2nd edition, 2001
  • [Wierse] Information Visualization in Data Mining and Knowledge Discovery, Usama Fayyad, Georges Grinstein, Andreas Wierse, Morgan Kaufmann, 2001

© 2004 Software & Support Verlag GmbH. Vervielfältigung nur mit Genehmigung des Verlags. Fragen?