2017-01-19 3 views
0

Ich habe eine mittlere Liste von Berechtigungen und Benutzer diesen Berechtigungen zugewiesen. Ich möchte Benutzer zu Rollen zusammenfassen, wenn sie die gleichen Berechtigungen teilen, aber ich stoße auf einige Probleme.Wie kann ich Untergruppen identifizieren, die in einer Gruppe ähnlicher Gruppen vorhanden sind?

Indem ich die Daten in einer Tabelle manipuliere, kann ich jeden eindeutigen Satz von Berechtigungen berechnen und Benutzer auf der Basis ihrer gesamten Berechtigungen zu einer Rolle zusammenfassen. Dies hat zur Folge, dass jeder Benutzer nur eine einzige Rolle innehat.

Ich würde gerne in der Lage sein, Untergruppen im Datensatz zu identifizieren, um die Anzahl der Rollen zu reduzieren und gleichzeitig die Anzahl der Rollenzuweisungen pro Benutzer zu erhöhen.

Hier ist ein Beispiel Datensatz: enter image description here

am Daten Blick ist es einfach, potenzielle Rollen (Benutzer 1 und 2 beide teilen sich die ersten 6 Berechtigungen) zu finden, aber ist es eine Möglichkeit, diese Art von Daten zu necken out durch SQL, Tabellenkalkulation oder ein einfaches Programm?

Ich weiß, gibt es mehrere Antworten auf diese Frage auf einer Mindestanzahl von Berechtigungen pro Rolle basiert, oder minimale Anzahl von Benutzern zu einer Rolle zugewiesen, usw.

Ich erwarte keine endgültige Antwort zu finden, aber versuchen, einen algorithmischen Schritt voranzutreiben, wenn das Sinn macht.

Antwort

1

Anstatt Clustering (die auf binäre Daten wirklich schlecht ist) verwenden entweder:

  • Link Vorhersage/Recommender Systeme: Wenn Benutzer A Berechtigungen b und c hat, welche anderen Berechtigungen vorschlagen?
  • häufig itemset Bergbau/Assoziationsregeln: wenn der Benutzer eine hat, b dann sollte er auch die Erlaubnis c a, b -> c
+0

Haben ein wenig über diese Theorien gegraben, sie sind unglaublich faszinierend, aber ich denke, sie sind viel zu weit für meine kleine Datenmenge. – gfroese

+0

(Ich habe mein Editierfenster verpasst) Danke für die Info, ich nehme an, ich habe auf einen einfachen Algorithmus gehofft, den Sie einfach in 2 Gruppen und deren Assoziationen einspeisen könnten und eine Vielzahl von Möglichkeiten zur effizientesten Kategorisierung dieser Assoziationen erhalten. Ich denke, ich versuche einfach, diese Beziehungen in einem großen Raster zu visualisieren und ähnliche Benutzer manuell im Raster zu gruppieren und dann die Gruppen von Hand zu erstellen. – gfroese

+0

Nach ein wenig mehr lesen stolperte ich über diese erstaunliche [Bibliothek] (http://www.philippe-fournier-viger.com/spmf/index.php?link=documentation.php#example1), die genau das tut, was ich brauche . Vielen Dank! – gfroese

1

Ok, lass uns ein paar Daten machen!

DECLARE @User TABLE 
(
    Perm INT, 
    User1 INT, 
    User2 INT, 
    User3 INT, 
    User4 INT, 
    User5 INT, 
    User6 INT, 
    User7 INT, 
    User8 INT, 
    User9 INT, 
    User10 INT 
) 

INSERT INTO @User 
(Perm, User1, User2, User3, User4, User5, User6, User7, User8, User9, User10) 
VALUES 
(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1), 
(2, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1), 
(3, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0), 
(4, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0), 
(5, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1), 
(6, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1), 
(7, 0, 0, 1, 1, 1, 1, 1, 0, 1, 1), 
(8, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0), 
(9, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1); 

Jetzt haben wir die Berechtigungen und Benutzer in einer Tabelle, jetzt machen wir ein bisschen Zählen und machen einen Gruppierungswert. Hier

SELECT 
    u.Perm, 
    u.User1, 
    u.User2, 
    u.User3, 
    u.User4, 
    u.User5, 
    u.User6, 
    u.User7, 
    u.User8, 
    u.User9, 
    u.User10, 
    CASE WHEN u.User1 = 1 THEN 1 ELSE 0 END + 
    CASE WHEN u.User2 = 1 THEN 2 ELSE 0 END + 
    CASE WHEN u.User3 = 1 THEN 4 ELSE 0 END + 
    CASE WHEN u.User4 = 1 THEN 8 ELSE 0 END + 
    CASE WHEN u.User5 = 1 THEN 16 ELSE 0 END + 
    CASE WHEN u.User6 = 1 THEN 32 ELSE 0 END + 
    CASE WHEN u.User7 = 1 THEN 64 ELSE 0 END + 
    CASE WHEN u.User8 = 1 THEN 128 ELSE 0 END + 
    CASE WHEN u.User9 = 1 THEN 256 ELSE 0 END + 
    CASE WHEN u.User10 = 1 THEN 512 ELSE 0 END AS GroupMe 
FROM @User u 

ist die Ausgabe:

Perm User1 User2 User3 User4 User5 User6 User7 User8 User9 User10 GroupMe 
1 1 1 1 1 1 1 1 1 1 1 1023 
2 1 1 0 0 0 0 0 1 1 1 899 
3 1 0 0 0 0 0 0 0 0 0 1 
4 1 1 1 1 0 0 0 0 0 0 15 
5 1 1 0 0 0 0 0 1 1 1 899 
6 1 1 0 0 0 0 0 0 1 1 771 
7 0 0 1 1 1 1 1 0 1 1 892 
8 1 0 0 0 0 0 0 0 0 0 1 
9 1 0 1 1 0 1 1 0 1 1 877 

Sie werden sehen, dass 3 und 8 den gleichen Wert haben. Auch 2 und 5 haben den gleichen Wert.

Ok, läßt einen zul Breakout-Bereich mit einer Zahlen-Tabelle hinzufügen:

;WITH 
a AS (SELECT 1 AS i UNION ALL SELECT 1), 
b AS (SELECT 1 AS i FROM a AS x, a AS y), 
c AS (SELECT 1 AS i FROM b AS x, b AS y), 
d AS (SELECT 1 AS i FROM c AS x, c AS y), 
e AS (SELECT 1 AS i FROM d AS x, d AS y), 
f AS (SELECT 1 AS i FROM e AS x, e AS y), 
numbers AS 
(
    SELECT TOP(10) 
     ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS number 
    FROM f 
), PrivBreakout AS 
(
    SELECT 1 AS UserId, u.Perm 
    FROM @User u 
    WHERE u.User1 = 1 
    UNION 
    SELECT 2 AS UserId, u.Perm 
    FROM @User u 
    WHERE u.User2 = 1 
    UNION 
    SELECT 3 AS UserId, u.Perm 
    FROM @User u 
    WHERE u.User3 = 3 
    UNION 
    SELECT 4 AS UserId, u.Perm 
    FROM @User u 
    WHERE u.User4 = 1 
    UNION 
    SELECT 5 AS UserId, u.Perm 
    FROM @User u 
    WHERE u.User5 = 1 
    UNION 
    SELECT 6 AS UserId, u.Perm 
    FROM @User u 
    WHERE u.User6 = 1 
    UNION 
    SELECT 7 AS UserId, u.Perm 
    FROM @User u 
    WHERE u.User7 = 1 
    UNION 
    SELECT 8 AS UserId, u.Perm 
    FROM @User u 
    WHERE u.User8 = 1 
    UNION 
    SELECT 9 AS UserId, u.Perm 
    FROM @User u 
    WHERE u.User9 = 1 
    UNION 
    SELECT 10 AS UserId, u.Perm 
    FROM @User u 
    WHERE u.User10 = 1 
), ThreeLayerCombo AS 
(
    SELECT 
     a.number AS priva, 
     b.number AS privb, 
     c.number AS privc 
    FROM numbers a 
    CROSS JOIN numbers b 
    CROSS JOIN numbers c 
    WHERE b.number > a.number 
     AND c.number > b.number 
) 

nun in dem obigen Code, entschied ich mich für Kombinationen von mindestens 3 Berechtigungen suchen

SELECT t.priva, t.privb, t.privc, COUNT(DISTINCT a.UserId) AS Grouper 
FROM ThreeLayerCombo t 
INNER JOIN PrivBreakout a 
    ON t.priva = a.Perm 
INNER JOIN PrivBreakout b 
    ON b.UserId = a.UserId 
    AND t.privb = b.Perm 
INNER JOIN PrivBreakout c 
    ON c.UserId = a.UserId 
    AND t.privc = c.Perm 
GROUP BY t.priva, t.privb, t.privc 
ORDER BY COUNT(DISTINCT a.UserId) DESC 

Schauen sie sich für die besten Combos, hier ist die Ausgabe:

priva privb privc Grouper 
1 2 5 5 
1 7 9 5 
2 5 6 4 
1 2 6 4 
1 5 6 4 
1 2 9 3 
2 5 9 3 
1 5 9 3 
1 6 9 3 
2 6 9 3 
5 6 9 3 
5 7 9 2 
5 6 7 2 
4 5 6 2 
2 7 9 2 
6 7 9 2 
1 4 9 2 
1 6 7 2 
2 6 7 2 
2 5 7 2 
2 4 5 2 
2 4 6 2 
1 2 7 2 
1 5 7 2 
1 2 4 2 
1 4 5 2 
1 4 6 2 
1 4 7 1 
1 4 8 1 
1 2 3 1 
1 5 8 1 
1 2 8 1 
1 3 4 1 
1 3 5 1 
1 3 6 1 
1 3 8 1 
1 3 9 1 
2 4 8 1 
2 4 9 1 
2 5 8 1 
2 6 8 1 
1 6 8 1 
1 8 9 1 
2 3 4 1 
2 3 5 1 
2 3 6 1 
2 3 8 1 
2 3 9 1 
6 8 9 1 
2 8 9 1 
3 4 5 1 
3 4 6 1 
3 4 8 1 
3 4 9 1 
3 5 6 1 
3 5 8 1 
3 5 9 1 
3 6 8 1 
3 6 9 1 
3 8 9 1 
4 5 8 1 
4 5 9 1 
4 6 8 1 
4 6 9 1 
4 7 9 1 
4 8 9 1 
5 6 8 1 
5 8 9 1 

Vom Ausgang der besten Wetten sind (1, 2, 5) und (1, 7, 9) um spezifische Rollen gegen zu bauen.

Hoffe, das hilft!

+0

Dank Kevin hat, das ist eigentlich die gleiche Methode, die ich verwenden, um meine ursprünglichen Gruppen zu erstellen. Mein Ziel ist es, gemeinsame Untergruppen zu finden. In dieser Lösung ist jeder Benutzer das Mitglied von genau einer Gruppe/Rolle, in Wirklichkeit sind sie wahrscheinlich Teil mehrerer kleinerer Gruppen von Berechtigungen/Rollen. – gfroese

Verwandte Themen