Daniel Toups
RWTH Aachen University
daniel.toups@rwth-aachen.de


Abstract

Durch die immer stärker voranschreitende Digitalisierung unseres Alltages, wachsen auch die Datenmengen, die von Community-Detection-Algorithmen analysiert werden müssen. Bei zu großen Datenmengen können herkömmliche Algorithmen an oder sogar über ihre Grenzen kommen. In diesem Paper werden wir uns damit auseinandersetzen, welche Algorithmen man für diese Anwendung mit besonders großen Datensätzen verwenden kann und was ihre jeweiligen Vor- und Nachteile sind. Die vorgestellten Algorithmen sind vielversprechende Erweiterungen von bereits existierenden Lösungen oder sogar gänzlich neue Ansätze, die die Rechenzeit verbessern, ohne dabei signifikant an Genauigkeit zu verlieren. Dadurch ermöglicht sich das Untersuchen größerer oder volatileren Netzwerken, ohne dabei Genauigkeit zu verlieren. Die vorgestellten Methoden zeigen, dass es noch Optimierungsbedarf gibt (und vermutlich immer geben wird), wenn wir den wachsenden Herausforderungen unserer Zeit gerecht zu werden.

Keywords

Community Detection, BigData, social BigData


Inhaltsverzeichnis

  1. Einleitung
  2. Verwandte Arbeiten
  3. k-ICDK
    1.Ergebnisse k-ICDK 1.1
  4. QCA
    1.Hinzufügen Node 2.Entfernen Node 3.Hinzufügen Edge 4.Entfernen Edge 5.Ergebnisse-QCA
  5. Berger-Wolf-Framework 1.Ergebnisse Berger-Wolf
  6. Zusammenfassung
  7. Bedeutung für zukünfitge Forschung
  8. Referenzen



Einleitung

Unser Leben wird immer stärker digitalisiert. So werden tägliche Aspekte wie Einkaufen, Arbeiten, Unterhaltung und selbst das Aussuchen eines Rezeptes immer stärker über das Smartphone oder einen PC gemacht. Dazu zählt natürlich auch, dass wir unsere sozialen Aspekte des Lebens immer stärker in den digitalen Raum stellen. Das neueste Beispiel hierfür ist das von Meta (ehm. Facebook) angekündigte Metaverse. Dadurch, dass wir immer mehr unserer sozialen Interaktionen über soziale Netzwerke betreiben, fallen in eben diesen gigantischen Datenmengen an, was das Analysieren solcher Netzwerke sehr rechen- und zeitintensiv macht. Hinzu kommt, dass sich der für uns relevante Inhalt der Netzwerke häufig und schnell ändert, sodass man entweder kontinuierlich Momentaufnahmen betrachtet oder einen dauerhaft auf dem Netzwerk laufenden Algorithmus betrachtet jeweils die Veränderungen ohne jedes Mal das gesamte Netzwerk neu berechnen zu müssen.
Bei den Analysen ist es häufig das Ziel, Gruppen zu finden. Diese zeichnen sich dadurch aus, dass sie innerhalb der Gruppe gut vernetzt sind. Hierbei bietet es sich an, das soziale Netzwerk als Netz aus Graphen zu betrachten.
Durch die immer größer werdenden Netzwerke werden die heutigen Methoden meistens durch ihre Hardware gebremst. Daher besteht ein großes Interesse an effizienten Methoden zur Gruppenfindung in sozialen Netzwerken. In diesem Paper werden wir uns neben der Vorstellung bekannter Methoden mit deren Effektivität und Effizienz beschäftigen. Dafür habe ich drei Algorithmen mit möglichst unterschiedlichen Ansätzen ausgewählt. Unser Hauptaugenmerk liegt dabei bei den Arbeiten von (Wu et al., 17.12.2018 - 20.12.2018) zur zeitscheibenbasierten Erarbeitung von community-detection, (Berger-Wolf, 2007) die das Problem mithilfe von dynamic-programming in Angriff nimmt und (Nguyen et al., 2014), der die möglichen Ereignisse kategorisiert und versucht möglichst viele dieser Kategorien auf einfache Umstellungen zu führen. Anschließend werden die Ergebnisse zusammen gefasst und verglichen. Abschließend werden wir die Zusammenfassung und Ansätze für weitere Arbeiten besprechen.

Verwandte Arbeiten

Gruppenfindungsprobleme werden schon seit längerer Zeit erforscht. Viele Methoden dazu basieren auf Graphenstrukturen. Dazu gehören auch viele random walk basierte Methoden oder Userprofil-basierte Methoden. In sozialen Netzwerken, wo Informationen über Freundschaft(bzw. Konnektivität) zwischen den Nutzern inhaltlich relevant ist, werden oben genannte Methoden genutzt.
Obwohl solche sozialen Netzwerke sich über die Zeit entwickeln und aufbauen, sind die meisten Methoden zu Gruppenfindungen auf statische Netzwerke konzentriert. Gruppen und ihre Charakteristika ändern sich über Zeit, sodass eine immer wieder erfolgende Neuberechnung des Netzwerkes schnell sehr rechenintensiv wird. Über die Optimierung dieser Berechnungen schreibt (Berger-Wolf, 2007).
(Nguyen et al., 2014) schreibt über die strukturelle Veränderung von sozialen Netzwerken.
Die Gruppenfindungsmethoden für dynamische Netzwerke kann laut (Wu et al., 17.12.2018 - 20.12.2018) in zwei Lager geteilt werden:

  • Zeitscheibenbasierte Methoden:
    Eine Methode ist hier immer auf eine Momentaufnahme des Netzwerkes anzuwenden{Quelle 1 CPM13}
    Wegen ihres hohen Rechenaufwandes eignen sich diese Methoden jedoch nicht für große Netzwerke, da hier das gesamte Netzwerk bei jeden Durchlauf komplett neu betrachtet werden muss.

  • Iterative Methoden:
    Hier passt eine Methode die Ergebnisse kontinuierlich an, dadurch werden die Ergebnisse leicht inakkurater, dadurch lassen sich jedoch aufgrund des geringeren Rechenaufwandes deutlich größere Netzwerke betrachten.



ICDK

(Wu et al., 17.12.2018 - 20.12.2018) et al schlägt einen zeitscheibenbasierten Ansatz für das kontinuierliche Betrachten eines Netzwerkes vor. Dafür stellt er den ICDK-Alorithmus (Incremential community detection method using k-clique) vor, mithilfe dessen es möglich sein soll, schnell wandelnde Netzwerke effektiv und effizient zu betrachten.

Das Grundprinzip: Die Veränderungen an sich vom Zeitpunkt t zu t+1 werden als Netzwerk betrachtet, das mit dem bereits vorhandenen Communities aus t gemerged werden. Die Effizienzsteigerung liegt darin, dass Community-Detection in kleinen Netzwerken sehr effizient laufen kann. Dadurch kann man den Abstand etwas größer wählen und viele Veränderungen in einem Zeitabschnitt in relativ kurzer Zeit betrachten. Die “Delta-Netzwerke” werden dann mit den Ergebnissen des letzten Schrittes verknüpft.

Als grundlegender Algorithmus für das Finden von Gruppen wird hier der k-Clique-Algorithmus gewählt, ICDK ist also eine Weiterentwicklung von k-Clique.

k-ICDK Funktionsweise

ICDK - Ergebnisse

Leider war es mir nicht möglich den hier aufgeführten Algorithmus in der öffentlichen Domäne zu finden, daher muss auf die Ergebnisse der entsprechenden Paper selbst zurückgegriffen werden.

Bei (Wu et al., 17.12.2018 - 20.12.2018) wurden folgende Daten verwenden: Es wurde ein Datensatz der DBLP, Digital Bibliography and Library Project, in dem Veröffentlichungen verschiedener Autoren gesammelt werden. Die getesteten Algorithmen sollen über die Zusammenarbeit mehrerer Autoren einem Paper Gruppen formen. Hierbei ist ein Node ein Autor, eine Edge eine Kollaboration und eine Zeiteinheit ist jeweils 1Jahr.

Die Effizienz der verglichenen Algorithmen wird über die Zeitkosten verglichen. Sei RC(t) und C(t) die tatsächlichen Gruppen bzw. die errechneten Gruppen, dann wird die Genauigkeit errechnet, indem man die Schnittmenge der beiden Mengen durch die Vereinigung beider Mengen teilt (bzw. jeweils die Mächtigkeit von Nenner und Zähler).

(Wu et al., 17.12.2018 - 20.12.2018) testet seinen Algorithmus leider nun gegen den ihm zugrunde liegenden k-Cliquen-Algorithmus, was eine Evaluation im gesamten Bereich der Analyse von BigData etwas erschwert.

Auf den eben beschriebenen Datensatz wird k-ICDK mit k-Clique für die k-Werte 1, 2, 3 und 4 verglichen. Dabei gab sich eine Zeitkostenersparnis von 17%, 54%, 80% und 90%. Also lassen sich besonders bei großen Cliquen viel Zeitkosten einsparen.

Das alles ist jedoch nur relevant, wenn k-ICDK dabei nicht an der Genauigkeit der Gruppeneinteilung spart. Hierzu lässt sich sagen, dass die Anzahl der Gruppen, die die beiden Algorithmen finden, nahezu identisch ist. In der Bewertung der Genauigkeit sehen wir in dem vorstellendem Paper, dass der vorgestellte k-ICD-Algorithmus im Vergleich zum inkrementellen k-Cliquen-Algorithmus um rund 5-7 % genauer war.

k-ICDK vs k-Clique speed
Leider ist diese Grafik nicht in besserer Qualität verfügbar. In dieser Visualisierung repräsentiert der rote Graph k-ICDK und blau k-clique. Die y-Achse steht für die Zeit, also je niedriger, desto besser.

k-ICDK vs k-Clique Genauigkeit

Hier sehen wir die Genauigkeit der beiden Algorithmen. Die x-Achse steht für versch. Werte von k und die y-Achse für die Genauigkeit nach dem bereits vorgestellten Berechnungsverfahren.

k-ICDK kombiniert also eine deutliche Zeitersparnis mit einer moderaten Verbesserung der Genauigkeit gegenüber dem bereits bekannten k-Cliquen-Algorithmus.

Hier gilt allerdings folgendes zu bedenken: Der Vergleich konnte von mir bedauerlicherweise nicht reproduziert werden, da ich den vorgestellten Algorithmus nicht zum Herunterladen oder Benutzen finden konnte. Der Autor vergleicht seinen Algorithmus lediglich gegen den Algorithmus, auf dem k-ICDK basiert, zeigt also nicht zwangsweise, ob der Algorithmus besser als andere neue Methoden sind, sondern zeigt grundsätzlich nur, dass k-ICDK eine Verbesserung der k-Cliquen ist. Bei allen Werten für k sehen wir einen exponentiellen Anstieg der Berechnungszeit. Das genutzte Datenset beinhaltet jedoch nur 5tausend Nodes, sodass die Benutzbarkeit für größere Datensets schnell abnehmen könnte, wenn k-ICDK nur auf kleineren Datensets effizient läuft.

k-ICDK kann in Zukunft also noch verbessert werden, wenn eine schnellere oder genauere Alternative für einen zugrunde liegenden Algorithmus gefunden wird, oder der zugrunde liegende k-Cliquen-Algorithmus weiter verbessert werden sollte.

QCA

QCA (Quick Community adaption), vorgeschlagen von (Nguyen et al., 2014), versucht die Ereignisse in einem sozialen Netzwerk zu vereinfachen und dadurch auch die Bearbeitung zu beschleunigen.

Hierfür gehen wir davon aus, dass ein Netzwerk aus Edges und Nodes besteht, wobei Nodes Akteure darstellen und die Edges eine Verbindung im Kontext des Netzwerkes. Die Optimierung der Gruppenfindung basiert auf einem Wert modularity, der maximiert werden soll.

QCA vereinfacht die möglichen Ereignisse auf das Hinzufügen oder Entfernen von Edges bzw Nodes. Damit gibt es nur 4 Kategorien von Ereignissen, die betrachtet werden müssen.

Hinzufügen Node

Beim Hinzufügen eines Nodes besteht das best-Case Szenario, dass der Node keine anliegenden Edges hat. In dem Fall kann er einfach als Gruppe mit einem Akteur betrachtet werden.

Sollte der neue Node jedoch Edges haben, wird er zunächst wie ein Node ohne Edges als eigene Gruppe betrachtet. Anschließend wird über alle verbundenen Nodes geprüft, ob der neue Node in dessen Gruppe eingegliedert werden sollte. Dies erfolgt über die Werte Fin und Fout, die (Nguyen et al., 2014) in seinem Paper vorstellt.

Entfernen Node

Das Entfernen von Nodes ohne Edges oder mit nur einer Edge ist trivial. Mit steigendem Grad der Vernetzung (Anzahl der Edges eines Nodes) steigt die Gefahr, dass die Gruppe, der dieser Node angehörig ist, auseinander bricht und fragmentiert. Sollte eine Edge mit mehr als einer Edge entfernt werden, wird eine sog. 3-clique-percolation auf einem der Nachbarn genutzt, um die restlichen Nodes der entsprechenden Community in neue Gruppen zu fragmentieren. Anschließend wird für jeden der betroffenen Nodes entschieden, ob diese die Gruppe wechseln sollten (ähnlich wie beim Hinzufügen eines Nodes mit Edges). Das Resultat ist eine oder mehrere Gruppen, die aus der (ggf.) Zerteilung einer Gruppe entstehen.

Hinzufügen Edge

Beim Hinzufügen einer Edge innerhalb einer Gruppe, sind keine Änderungen notwendig, es wird lediglich der Zusammenhalt innerhalb der Gruppe gestärkt. Sollte eine neue Edge zwei Gruppen verbinden, wird mithilfe des modularity-Wertes errechnet, ob eine der beiden Verbundenen Nodes seine Gruppe wechseln sollte. In dem Fall müssen auch die zu dem wechselnden Knoten verbundenen Nodes entscheiden, ob sie die Gruppe wechseln sollten.

Entfernen Edge

Analog zum Hinzufügen von Edges, stärkt das Entfernen von Edges zwischen zwei Gruppen den Zusammenhalt der beiden Gruppen. Sollte eine Edge innerhalb einer Gruppe gelöscht werden, schwächt dies den Zusammenhalt der Gruppe. Doch auch hier gibt es verschiedene mögliche Fälle: 1: Einer der betroffenen Nodes hat nur diese eine Edge. In dem Fall wird er aus seiner Gruppe entfernt und bildet alleine eine Gruppe, der Rest bleibt unverändert. 2: Die Edge verbindet zwei Gruppen, in dem Fall bleibt alles unverändert. 3: Die Edge ist die einzige Verbindung von zwei Nodes. In dem Fall bleibt die Struktur der Gruppen gleich, mit der Ausnahme der zwei entstehenden Gruppen aus je einem Node 4:Die Edge ist eine Verbindung innerhalb einer Gruppe. In diesem, dem kompliziertesten Fall, suchen wir wieder sog. Cliquen aus der entsprechenden Gruppe, die dann als eigene Gruppen betrachtet werden. Alle restlichen Nodes können wie beim Hinzufügen von Nodes einmal entscheiden, welcher Gruppe sie beitreten. (Anmerkung: Es ist möglich das eine Edge innerhalb einer Gruppe entfernt wird, durch den starken Zusammenhalt der Gruppe kann es jedoch sein, dass die Gruppenstruktur bis auf die gelöschte Edge komplett identisch ist).

Der Algorithmus besteht stark vereinfacht lediglich in einer vierfachen if-Abfrage über das neue Event. Dieses wird dann wie oben erklärt abgearbeitet.

QCA - Ergebnisse

(Nguyen et al., 2014) vergleicht sein Framework gegen mehrere Algorithmen aus demselben Feld. Darunter sind LABEL, WAIT, MCP und MIEN.

Zunächst werden QCA, OSLOM, FaceNet und MIEN miteinander verglichen. Dabei wird als Vergleichswert für die Genauigkeit der NMI ( Normalized Mutual Information) verwendet. Die verschiedenen Algorithmen wurden auf einem synthetischen Datensatz getestet. Es wurde 4-mal getestet, um 2 verschiedene Werte für den Vermischungsparameter und 2 verschiedene Werte für die Datensatzgröße zu nehmen.

QCA mit synthetischem Datenset

Hierbei zeigt sich, dass QCA eine in allen 4 Tests den besten Wert für NMI haben. Die Tendenz zeigt, dass QCA sich im Fortlaufen der Zeit gegenüber den Kontrahenten immer mehr absetzt, also das Beobachten über längere Zeit scheint hier besonders gut zu funktionieren. Die Tests wurden auch mit dem in diesem Paper vorgestellten modularity-Wert verglichen, da dieser aber extra für diesen Algorithmus definiert wurde, halte ich ihn für zu voreingenommen, um diesen Vergleich hier aufzuführen.

In einem weiteren Test über ein E-Mail-Netzwerk wurden QCA, MIEN und OSLOM verglichen. In diesem Netzwerk gab es ca. 150 Nutzer, die über 21 Snapshots betrachtet werden. Für den NMI-Wert wechseln sich QCA und MIEN häufiger ab, QCA ist jedoch in seiner Genauigkeit deutlich stabiler, da MIEN phasenweise stark einbricht. OSLOM hängt bei der Genauigkeit deutlich hinterher und erreicht ca 20-30% weniger NMI-Wert. Zur Laufzeit fällt auf, dass QCA hier extrem weit von der Konkurrenz entfernt ist. Während QCA die Snapshots zuverlässig in ca. 0,25s berechnen kann, brauchen OSLOM und MIEN zwischen 1 und 2 Sekunden.

QCA mit e-mail Datenset

In weiteren von (Nguyen et al., 2014) gezeigten Tests setzen sich diese Ergebnisse fort. QCA ist in der Regel deutlich schneller und gleichzeitig bei der Genauigkeit immer unter den Besten.

Im Gegensatz zu k-ICDK basiert QCA nicht auf einem anderen Algorithmus, sodass es nicht ggf. dessen Schwächen übernimmt. QCA ist ein eigenständiger Algorithmus, der besonders durch seine kurze Laufzeit überzeugt. Dabei spart er nicht an Genauigkeit ein, setzt diese aber auch nicht explizit in den Fokus, sodass hier eventuell noch Verbesserungsbedarf besteht. QCA läuft auch auf größeren Netzwerken sehr schnell, sodass sich besonders der Einsatz bei besonders großen Datenmengen lohnen kann. Durch das Vereinfachen der möglichen Ereignisse kann QCA auch mit vielen Netzwerkveränderungen in geringer Zeit gut klarkommen.



Berger-Wolf-Framework

Last but not least stelle ich noch ein von (Berger-Wolf, 2007) vorgestelltes Framework. Ihr Ansatz sieht vor, die Community-Detection als Farbproblem zu betrachten, bei der sowohl einem Node als auch einer Gruppe eine Farbe zugewiesen wird. Zusätzlich entstehen sog. Kosten, die sich in i-cost, g-cost und c-cost unterteilen.

Diese Kosten können einzeln angepasst werden, um bestimmte Charakteristika zu erzwingen. Es kann beispielsweise kostenspielieger gemacht werden, wenn ein Node seine Farbe ändern will o.ä.

i-cost: Entsteht, wenn ein Node seine Farbe ändert. Es werden Kosten in Höhe von alpha fällig.

g-cost: Die Kosten beta1 beta2 entstehen, wenn ein Node keine Verbindung zu einer Gruppe der gleichen Farbe hat oder ein Node eine Verbindung zu einer Gruppe einer anderen Farbe als er selbst hat. Wenn ein Node also nicht in einer Gruppe derselben Farbe ist, entstehen automatisch Kosten in Höhe von beta1 + beta2

c-cost: Kosten für jede Farbe, die ein Node benutzt, die nicht die Farbe ist, mit der er initialisiert wurde.

Die Gruppenzugehörigkeit wird damit zu einer Frage der Kostenminimierung.

Optimierung des Algorithmus: Intuitiv betrachtet kann man sagen, dass eine Gruppeneinteilung gut ist, wenn viele Nodes ihre Gruppenzugehörigkeit nicht (oft) ändern müssen, da dadurch i-, und g-Kosten vermieden werden. Dies kann durch sog. bipartive Graphen erreicht werden, bei denen eine gewichtete Kante zwischen zwei Punkte g und g’ eingeführt wird. Hierbei gilt folgendes zu beachten: Die Kante kann nur eingefügt werden, wenn beide Nodes in den timeslices t und t+1 vorkommen. Außerdem wird die Kante von g in t zu g’ in t+1 gezogen. Nun werden die Paare mit den höchsten Übereinstimmungswert genommen und angenommen, dass diese auch in der nächsten Zeiteinheit die gleiche Farbe haben sollten.

Die Bestimmung des Übereinstimmungswertes errechnet man aus dem sog. Jaccard’s Index, der in unserem Fall noch durch die Zeitdifferenz |t-(t+1)| geteilt wird. Wir nutzen also jeweils die “günstigste” Verbindung zuerst, was dem MST-Algorithmus von Kruskal ähnelt.

Für die Speicheranforderungen und Zeitkosten gibt (Berger-Wolf, 2007) an, dass man eine Laufzeit von O(nTC22C) und eine Speicherplatzanforderung von O(2CC) erwarten kann.

Berger-Wolf - Ergebnisse

Das Framework hat es sich als Ziel gesetzt, die Veränderung von Gruppen in Netzwerken zu betrachtet. Leider wurde bei der Versuchsreihe kein Datensatz genutzt, der in den Bereich des BigData eingegriffen werden kann, sodass der Vergleich mit anderen Frameworks/Algorithmen deutlich erschwert wird. Ein Punkt für die zukünftige Forschung an diesem Framework ist also das Verhalten bei besonders großen Datensätzen. Zum anderen geht die Autorin davon aus, dass sich eine Gruppeneinteilung besonders dann als richtig erweist, wenn viele Nodes von einem Zeitschritt zum nächsten in derselben Gruppe bleiben können. Diese Einstellung teile ich persönlich, da die Corona-Pandemie gezeigt hat, wie schnell und frequent sich soziale Strukturen ändern können.

Berger Wolf testet das Framework mit einem Real-World Datenset, dass sich Southern Women nennt und die Teilnahme an sozialen Ereignissen von 18 Frauen zeigt. Ich bin der Ansicht, dass die Größe des Datensatzes nicht ausreicht, um eine Aussage über das Verhalten bei BigData-Datensätzen zu eruieren.

(Berger-Wolf, 2007) selbst sagt aus, dass das Framework noch nicht ausreichend für große Datensätze und große Beobachtungszeiträume getestet wurde und regt ebenfalls an, dass dies in Zukunft noch untersucht werden sollte. Die Stärken und Schwächen des vorgestellten Frameworkes lassen sich damit noch nicht eindeutig feststellen, solange keine ausreichende Datenbasis für das Verhalten bei BigData-Datensätzen vorliegt.

Zusammenfassung und Bedeutung für die zukünftige Forschung

Zusammenfassend lässt sich aussagen, dass alle drei vorgestellten Algorithmen oder Frameworks sehr unterschiedliche Ansätze verfolgen, was den Vergleich untereinander erschwert. Die Schwächen und Stärken der einzelnen Frameworks/Algorithmen haben wir bereits in den entsprechenden Abschnitten vorgestellt. Generell lässt sich sagen, dass die Problemstellung der OCD-Algorithmen für große Datensätze eine ist, die durch die stärkere Digitalisierung des Alltages immer relevanter wird. Aus diesem Grund wird auf viel Energie in die Weiterentwicklung bekannter Algorithmen und in das Erforschen neuer Algorithmen gesteckt, wie dieses Paper gezeigt hat. Da alle hier vorgestellten Algorithmen noch Verbesserungspotential haben und die Anforderungen mit jedem Tag steigen, werden wird noch viel Arbeit in das Erforschen effizienter und effektiver Algorithmen gesteckt werden müssen. Die hier vorgestellten Methoden geben jedoch alle Grund zur Hoffnung, dass wir nicht den Anschluss an unsere steigenden Anforderungen verlieren. So haben wir mit QCA beispielsweise ein Framework, das besonders auf das schnelle Erarbeiten von Datensätzen ausgelegt ist und mit k-ICDK eine Weiterentwicklung eines bereits bekannten Algorithmus.

Referenzen

  1. Wu, Z., Chen, J., & Zhang, Y. (17.12.2018 - 20.12.2018). An Incremental Community Detection Method in Social Big Data. 2018 IEEE/ACM 5th International Conference on Big Data Computing Applications and Technologies (BDCAT), 136–141. https://doi.org/10.1109/BDCAT.2018.00024
  2. Berger-Wolf, T. Y. (2007). A Framework For Community Identification in Dynamic Social Networks. 717–726.
  3. Nguyen, N. P., Dinh, T. N., Yilin Shen, & Thai, M. T. (2014). Dynamic Social Community Detection and Its Applications. PLOS ONE, 9(4), e91431. https://doi.org/10.1371/journal.pone.0091431