Finden Sie Cluster positiver Korrelationen

Sep 01 2020

Ich habe eine quadratische Matrix, die Beziehungen zwischen 71 Pflanzen zeigt: 1 ist positiv, -1 ist negativ, 0 ist nicht schlüssig und Leerzeichen sind unbekannt:

Ich würde gerne die größten Pflanzengruppen finden, die nur eine positive Beziehung ohne negative Beziehungen zwischen den Mitgliedern haben.

data = {{"", "Basil", "Cucumber", "Tomato", "Potato", "Peanut"}, {"Basil", 
  "", 0, -1, 0, ""}, {"Cucumber", "", "", "", -1, -1}, {"Tomato", -1,
   "", "", "", ""}, {"Potato", "", -1, 0, "", ""}, {"Peanut", 1, -1, 
  "", "", ""}}

Der vollständige Satz:

https://pastebin.com/06krccza

Ich konnte herausfinden, wer ein Weighted Adjacency Graph erstellen sollte, indem ich:

Generieren eines Diagramms für soziale Netzwerke aus einer CSV-Datei

Ich bin jedoch auf der Suche nach etwas, das die Beziehungen vereinfacht, in denen ich Gruppen guter Übereinstimmungen auswählen kann.

Antworten

5 AntonAntonov Sep 02 2020 at 18:50

Nehmen Sie die Daten auf, erstellen Sie eine Matrix der Korrelationen und erstellen Sie eine Liste mit Pflanzennamen:

data = Get["~/Downloads/06krccza.txt"];
matData = data[[2 ;; -1, 2 ;; -1]];
lsPlantNames = Rest@data[[1]];
Length[lsPlantNames]

(*70*)

Machen Sie Assoziationen von Korrelationen und Entfernungen:

aCors = Association@
   Map[lsPlantNames[[#[[1]]]] -> #[[2]] &, 
    Most[ArrayRules[SparseArray[matData]]]];
aDists = Map[
   N@Which[TrueQ[# == 1], 0, TrueQ[# == -1], 1000, True, 1] &, aCors];

Beachten Sie, dass zur Behebung der wichtigsten, nicht trivialen Bedingung der Frage

[...] finden Sie die größten Gruppen von Pflanzen, die nur eine positive Beziehung ohne negative Beziehungen zwischen den Mitgliedern haben.

Die Abstände aDists, die negativen Korrelationen entsprechen, sind (sehr) große Zahlen.

Erstellen Sie ein Diagramm für die nächsten Nachbarn:

gr = NearestNeighborGraph[lsPlantNames, {90, 0.1}, 
  DistanceFunction -> (Lookup[aDists, Key[{#1, #2}], 1000] &), 
  Method -> "Octree", DirectedEdges -> False, 
  GraphLayout -> "SpringElectricalEmbedding", VertexLabels -> "Name"]

Cliquen / Cluster finden:

lsClqs = FindClique[gr, Infinity, All];
Length[lsClqs]

Untersuchen Sie die Clusterlängen:

Tally[Length /@ lsClqs]

(*{{4, 1}, {3, 10}, {2, 32}, {1, 36}}*)

Stellen Sie sicher, dass die gefundenen Cluster keine negativen Korrelationen aufweisen

aHasNegativeCor = 
  Association[# -> FreeQ[Outer[aCors[{##}] &, #, #], -1] & /@ clqs];
Tally[Values[aHasNegativeCor]]

(*{{True, 78}, {False, 1}}*)

Untersuchen Sie die negative Korrelation und / oder löschen Sie sie:

Select[aHasNegativeCor, ! # &]

(*<|{"Beans, Runner", "Garlic", "Leek"} -> False|>*)

Endergebnis:

lsClqs2 = Keys[Select[aHasNegativeCor, # &]];
lsClqs2[[1 ;; 4]]

(*{{"Onion", "Pea", "Potato", "Tomato"}, {"Onion", "Parsnip", 
  "Tomato"}, {"Leek", "Onion", "Pea"}, {"Garlic", "Leek", "Pea"}}*)

Erste Antwort

Code, der diesen Fragen helfen könnte.

Da keine Daten bereitgestellt wurden, lassen Sie uns einige machen:

SeedRandom[32]; 
data2 = Block[{lsWords = Sort@RandomWord[71], res},
   res = Flatten[
     Table[{lsWords[[i]], lsWords[[j]], 
       RandomChoice[{0.1, 0.8, 0.1} -> {-1, 0, 1}]}, {i, 1, 
       Length[lsWords]}, {j, i + 1, Length[lsWords]}], 1];
   res = Union[Join[res, res[[All, {2, 1, 3}]]]];
   Select[res, #[[3]] != 0 &]
   ];

Erstellen Sie ein Diagramm nur mit den positiven Korrelationen:

 gr = Graph[UndirectedEdge @@@ Select[data2, #[[3]] > 0 &]]

Grafik-Communitys finden:

 CommunityGraphPlot[gr, VertexLabels -> "Name"]

Wenn Sie die tatsächlichen Daten angeben, werden möglicherweise angemessenere Antworten gegeben.