Hallo,
seit Tagen versuche ich einen Grubbstest zum Auffinden von Ausreißer als eine SQL-Abfrage oder Datenbankfunktion zu implementieren. Leider hat es bis jetzt nicht geklappt, deswegen bitte um HILFE.
Gegeben ist eine Tabelle namens Data mit folgender Struktur:
create table data (id integer, value numeric, set_id integer).
Jeder Datensatz der tabelle repräsentiert eine Messung, set_id zeigt welche Werte zu welcher Stichprobe gehören, z. B.
id value set_id
1 0.5 1
2 0.7 1
3 1.0 2
usw.
Man soll eine SQL-Abfrage/Funktion etwickeln, die Grubbs-Test durchfüht und die Ausreißer markiert, so dass das Ergebniss etwa so ist:
id value set_id aussreisser
1 0.5 1 ja
2 0.7 1 nein
3 1.0 2 nein
Habe schon mit vieles probiert, komme aber nicht dahinter.
Wäre dankbar für jede Hilfe.
Uhm. Das ist ja eine statistische Funktion. Für solche Aufgaben gibt es spezielle Programme, z.B. R. Kennst Du Dich damit aus, also mit R?
Falls ja, hier die gute Nachricht: Du kannst PostgreSQL um die Sprache pl/R erweitern, das ist faktisch das Statistik-Paket R mit PostgreSQL als Datenhalde.
R gibt es als Open Source definitiv für Linux und wohl auch für Kleinweich.
R findest Du hier: The R Project for Statistical Computing
pl/R hier: PL/R - R Procedural Language for PostgreSQL
Alternativ: selber eine Funktion schreiben.
Andreas
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
Hallo Andreas,
mit dem Pl/R kenne ich mich nicht aus. Mir geht es aber darum die Funktion zu schreiben, die eine Tupelmenge übergeben bekommt und sie rekursiv abarbeitet, wobei in jedem Durchlauf eine Zeile zurückgegeben wird. Die Menge der verbleibenden Zeilen bildet das Ergebnis.
Falls du dich mit WITH RECURSIVE queries auskennst, muss etwa Folgendes getun werden:
WITH RECURSIVE t AS (
select * from data
except
SELECT grubbs_test(t) //gibt eine zeile zurück
)SELECT * FROM t;Aber WITH RECURSIVE gibt es in Postgre nur mit UNION und weiß nicht
wie ich das sonst machen soll.
Gruß
Alger
Hmm, sicher, dass ein UNION immer notwendig ist?
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören
Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler
PostgreSQL Service & Support
Hrm. Ich keine Ahnung von Mathe ;-)
Wenn ich Ausreißertest nach Grubbs – Wikipedia richtig interpretiere, solltest Du Deine Daten in eine Tabelle packen. Dann eine Funktion schreiben, die diese Tabelle EXCEPT eine (erst mal leere) Tabelle nimmt und davon die Ausreißer ermittelt und diese in dieser (ursprünglich leeren) Tabelle speichert. In einer Schleife rufst das halt solange auf, bis die ursprüngliche Tabelle EXCEPT der neuen Tabelle leer ist oder die EXCEPT-Tabelle nicht mehr größer wird.
Andreas
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
Scheinbar. Nur das ALL ist optional. PostgreSQL: Documentation: Manuals: PostgreSQL 8.4: WITH Queries Oder hast Du ein Beispiel ohne UNION?
Andreas
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
die funktion grubb liefert einen boolean, der true ist wenn der satz ein ausreißer ist, sonst falseCode:WITH RECURSIVE ausreisser(id int, messwert messtyp, ... ) AS ( -- 1. "recursion" -> 1. test -- LIMIT 1 - weil ja immer ein Ausreisser-Wert aussortiert wird .. SELECT messwert, .. FROM messungen m WHERE grubb(m.messwert, ... ) ORDER BY m.messnr LIMIT 1 UNION ALL -- die recursion .. SELECT messwert, .. FROM messungen m WHERE grubb(m.messwert, ... ) -- die gleiche bedingung wie oben AND m.id NOT IN (SELECT a.id FROM ausreisser a) -- die, welche wir schon haben nicht testen ORDER BY m.messnr ) select * from ausreisser
die musst du natuerlich noch implementieren
Geändert von symbiont (15.12.2009 um 16:05 Uhr)
Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören
Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler
PostgreSQL Service & Support
ich bin zwar etwas eingerostet
aber du kannst das auch so in etwa machen:
die tabelle waereCode:with kennzahlen (set_id, Xn, Sn) as ( select set_id, abs(x - avg(x) OVER (PARTITION BY set_id)) Xn, variance(x) OVER (PARTITION BY set_id) as Sn from messungen ) select max(Xn) OVER (PARTITION BY set_id) / Sn as G from kennzahlen
der akretschmer ist aber hier im forum der windowing-function-virtuoseCode:create table messungen ( x double precision, set_id int)
nachtrag:
weil eigentlich gehts ja darum jede zeile zu erhalten - zu jeder dieser zeilen das aggregat namens grubb zu berechnen - um dieses auszugeben / weiter zu verarbeiten ..
fuer solche faelle sind die windowing-functions gedacht .. man muss auch nicht immer alles auf einmal machen - aus dem beispiel oben (sofern inhaltlich korrekt) wuerd ich mir ein view bauen .. das kannst dann gegen deinen "ausreisser" wert checken
Geändert von symbiont (15.12.2009 um 19:57 Uhr)
--
https://www.xing.com/profile/Andreas_Kretschmer7ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
Links: Tobias Bauer - IT- und Funkdienstleistungen - Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen - Funkforum
Lesezeichen