Visualisierung der thematischen Verwandtschaft zwischen allen Autoren des Wikis
Wer ist mit wem thematisch verwand? Welche User haben also auf der Ebene des gesamten Wikis mit welchen anderen Usern zusammen Artikel verfasst? Um diese Frage zu beantworten stellt meine Mediawiki Extension mit Hilfe von GraphViz die Wiki-global auftretenden Relationen dar. Die Ausgabe eignet sich u.A. für die Startseite, eine einzelne (Spezial-) Seite oder eine eigene TAB-Seite. Letzteres hätte den Vorteil, dass die Information stets in Aktionsnähe des Wiki-Benutzers wäre.
GraphViz bietet leider nur eine statische Ausgabe des Graphen, allerdings habe ich mich dennoch für GraphViz entschieden, weil es das einzige ‘Framework’ ist , welches möglichst viele der folgenden Anforderungen an den Graphen erfüllt:
- Es muss eine Darstellung eines zusammenhangslosen Graphen möglich sein. Nicht jeder Autor steht mit einem anderen Autor in Relation. Es können einzelne Autoren oder Autorengruppen von anderen Gruppen oder Autoren unabhängig sein.
- Es soll eine Ausdrucksmöglichkeit für die Nähe der Knoten existieren. Thematisch näher verwandte Autoren sollen vom Betrachter identifiziert werden können.
- Es soll eine Ausdruckmöglichkeit für die Anzahl der gesamten Editierungen eines Autors im Wiki geben. Damit kann der Betrachter Autoren, die nur selten Beiträge schreiben erkennen.
- Platzsparende Darstellung des Graphen.
- Die Abbildung soll die Übersichtlichkeit fördern und nicht verschlechtern. Überschneidungen der Kanten sollen minimiert werden können, da solche nicht der Übersichtlichkeit beitragen.
- Skalierbarkeit des Graphen. Ein Graph mit vielen Knoten und Kanten darf nicht unübersichtlich werden.
GraphViz erfüllt alle Anforderungen.
Generierung der Eingabedaten
Die Eingabedaten für GraphViz werden aus der Tabelle ‘revision’ in der Datenbank ausgelesen. Die ‘revision’ Tabelle enthält die Änderungen aller Artikel im Wiki. Dazu gehört auch das Anlegen einer neuen Seite. Jeder neu angelegten oder geänderten Seite sind Benutzer mit ihrer ID und ihrem Namen zugeordnet. Die Tabelle enthält zudem die Länge der Änderung, den Kommentar, Zeitstempel und die Information ob die Änderung ggf. nur geringfügig war. Es ist zudem möglich, durch einen Parameter festzulegen, ab welcher Anzahl an geänderten Wörtern eine Änderung unter die Klasse der thematischen Nähe fällt — ab wann also eine Änderung den Counter erhöht.
Die SQL-Query liest zu jeder (Artikel-)Seite die Benutzer, die darin editiert haben und deren ID aus. Da die thematische Verwandschaft sich durch die Anzahl der Editierungen an verschiedenen und nicht an gleichen Artikeln definiert, werden die Daten distinct ausgelesen. distinct liest nur die unterschiedlichen Elemente aus und verringert dadurch auch die Anzahl der Treffer an Artikeln mit nur einem einzigen Autor. Ferner wird abgefragt ob es sich um eine geringfügige Änderung (minor edit) handelt oder nicht. Geringfügige Änderungen werden nicht betrachtet, da sie in den meisten Fällen nur eine Formatierung korrigieren und somit keine Relation des Editors mit dem Autor darstellen.
Aus dem Ergebnis der Query wird ein mehrdimensionales Array erzeugt, so dass zu jeder Seite (Hauptindex des Arrays) jeweils ein Unterarray mit allen Autoren zugeordnet wird, die diese Seite editiert haben. Es werden also pro Seite die User, die gemeinsam daran gearbeitet haben, in n-Tupeln gesammelt. GraphViz würde zur Gestaltung des Graphes an sich, durchaus mit einer sich leicht aus dem Array erzeugbaren Adjazenzliste auskommen. Allerdings bietet die Grammatik keine Möglichkeit zur automatischen Zählung mehrfach vorkommender Relationen.
Um die Relationen jedoch korrekt auszuwerten, müssen nun alle n-Tupel auf 2er Tupel (‘Autorenpärchen’) aufgebrochen werden. Nur so ist es möglich das mehrfache Vorkommen gleicher Tupel zu zählen um die Anzahl in der Kantenstärke auszudrücken.
Hierbei ist es nicht mehr wichtig aus welchen Artikeln diese 2er Tupel Relationen genau entstanden sind, sondern nur noch die Anzahl ihres vorkommens. Denn falls ein Tupel mehrfach vorkommt, bedeutet dies, dass diese User mehrfach an verschiedenen Artikeln editiert haben. In diesem Fall erhöht sich durch die Definition der thematischen Verwandschaft die Nähe der beiden Autoren zueinander. Die Häufigkeit des Auftretens des Tupels wird dann als Maß für die Kantenstärke in der Darstellung der Relationen verwendet. Leider lässt sich die Nähe der Knoten in GraphViz nicht verlässlich abbilden, so dass die Abbildung der Nähe beider Objekte über die Kantendicke erfolgen muss. Die aufgespaltenen Tupel werden in ein neues Array geschrieben und deren Häufigkeit mittels der Funktion my-counter() hinzugefügt.
Die Funktion ‘makeGraph()’ baut anschließend aus diesem neuen Array, dass nur noch 2er Tupel und den Zähler enthält den GraphViz-Datensatz zusammen. Dabei werden alle Autoren aus der MediaWiki Datenbank gelesen und als Knoten in den Datensatz eingesetzt. Die Schriftgröße der Knoten wird auf den Logarithmus der Editcounts der Autoren gesetzt. MediaWiki speichert die Anzahl der globalen Editierungen eines Autors in einem Feld EditCount. Der Logarithmus beschränkt die Schriftgröße auf ein lesbares aber dennoch vergleichbares Maß. Mit der Schriftgröße wächst auch die Größe des Knotens. Je größer also ein Knoten, desto höher die allgemeine Beteiligung des Autors im Wiki. Die Schriftgröße spiegelt also die Wichtigkeit eines abgebildeten Autors wieder.
Schließlich wird jeder Knoten wird zudem auf die dazugehörige Benutzerseite verlinkt, die beiden Elemente des Tupels miteinander verbunden und der Zähler als Kantenstärke angehängt und der Datensatz mittels des MediaWiki Parsers an die GraphViz-Extension weitergereicht. Die Darstellung übernimmt darauf die GraphViz-Extension.
Darstellung
Für eine korrekte und aussagekräftige Darstellung sollte die Rendering-Engine der GraphViz-Extension auf neato umgestellt werden. Neato ist eine alternative Rendering-Engine von GraphViz, die zur Darstellung ein Spring-Modell-Layout verwendet. Neato ordnet die Knoten zirkulär von der Mitte nach außen an. Das Spring-Layout simuliert daraufhin physikalische Federkräfte zwischen den Knoten und Kanten, so dass ein Layout entsteht, in dem die Gesamtenergie des Systems möglichst gering ist. Dieses Layout ermöglicht durch die Angabe der len und weight Parameter die Kantenlänge zwischen den Knoten zu variieren, so dass Abstand der Knoten zueinander theoretisch bestimmt werden kann. len gibt dabei die bevorzugte Länge der Kante in Inch an. Je höher der Wert, desto Länger die Kante (um die Nähe auszudrücken wird hier der Kehrwert der Kantendicke gesetzt). weight gibt an, mit welcher Gewichtung der Layouter versuchen soll, die bevorzugte Länge der Kante einzuhalten. Um so höher der Wert, desto strenger ist die Einhaltung der Werte. Allerdings wird hier keine Garantie gegeben, dass dieser Wert eingehalten wird (besonders, wenn die Option zur Vermeidung von Überschneidungen der Knoten eingeschaltet ist), so dass über den Abstand der Knoten im Graph keine verlässliche Aussage über die Nähe der repräsentierten Autoren gegeben ist.
Um die Rendering-Engine von dot auf neato umzustellen muss die in der Installationsanleitung von GraphViz angegebene Zeile
$wgGraphVizSettings->dotCommand = '/<graphvizpath>/dot';
gegen die Zeile
$wgGraphVizSettings->dotCommand = '/<graphvizpath>/neato';
ausgetauscht werden. Wenn man jedoch vermeiden möchte, dass die Umstellung auf neato im gesamten Wiki vollzogen wird, kann man auch die von mir modifizierte graphViz.php Extension anstatt der originalen verwenden. Sie unterstützt im Gegensatz zur originalen Version (obwohl vom Autor angegeben) Parameter, die beim parsen ausgelesen werden. Der Parameter ‘renderer’ übermittelt dabei den gewünschte Rendering-Algorithmus. Die Verwendung der Extension ändert sich dann von
<graphviz> graph g{ a -- b;} </graphviz>
zu
<graphviz renderer='neato'>graph g{ a -- b;}</graphviz>
Falls die modifizierte Version verwendet wird, bedarf es einer weiteren Änderung. Der Graphviz Pfad darf nur noch auf den Ordner referenzieren, nicht mehr auf den Renderer selbst. Folgendes muss geändert werden:
$wgGraphVizSettings->dotCommand = '/<graphvizpath>/dot';
zu
$wgGraphVizSettings->dotCommand = '/<graphvizpath>/';
Falls kein Parameter angegeben wird, wird automatisch ‘dot’ verwendet. Erlaubt sind die Parameter renderer={dot,neato,dotty}

