Aggregieren von Polygonen zur Erfüllung der Datenschutzanforderungen

10

Ich habe eine Punkt-Feature-Class, die Bürostandorte aller Arbeitgeber in einer bestimmten Branche darstellt. Die Feature-Class verfügt über ein Attribut zum Speichern der Anzahl der Mitarbeiter in jedem Büro. Jemand hat darum gebeten, diese Daten räumlich mit der kleinstmöglichen geografischen Einheit zu verbinden - in diesem Fall mit Volkszählungsblöcken. Eine Datenschutzvereinbarung verhindert jedoch die unveröffentlichte Veröffentlichung der Daten. Stattdessen muss es unterdrückt werden, um zwei Kriterien zu erfüllen:

  1. Jedes Polygon muss mindestens 3 Arbeitgeber (Punkte) enthalten.
  2. Nicht mehr als 80% der Gesamtbeschäftigung innerhalb eines Polygons dürfen von einem einzigen Arbeitgeber ausgeübt werden.

Ich habe erfolgreich ein Skript geschrieben, das die Punkte räumlich mit Volkszählungsblöcken verbindet und dabei die Summe und die maximale Beschäftigung beibehält. Jeder, der die Unterdrückungskriterien nicht erfüllt, wird markiert. (Polygone keine Punkte enthalten , sind nicht gekennzeichnet, da es keine Daten zu unterdrücken ist.) Jeder Block I dann überprüfen Gruppe , um zu sehen , ob irgendwelche Blöcke gekennzeichnet sind darin enthalten. Blockgruppen, die nur nicht gekennzeichnete Blöcke enthalten, werden dann durch die Blöcke ersetzt. Die resultierende Feature-Class wird dann anhand der Unterdrückungskriterien überprüft, um zu überprüfen, ob die Blockgruppen die Daten angemessen unterdrückt haben.

Der gleiche Vorgang wird für Tracts wiederholt, sodass ich einen Datensatz habe, der aus Tracts (einige markiert und andere nicht), Blockgruppen und Blöcken (alle nicht markiert) besteht. Der nächste Fortschritt in der geografischen Hierarchie ist jedoch der Landkreis, der für die Person, die diese Daten anfordert, nicht von Nutzen ist.

Meine Frage lautet also: Gibt es allgemein akzeptierte Methoden, um Polygone in so viele Gruppen wie möglich zu aggregieren, damit alle einige Mindestkriterien erfüllen?

Hier sind einige Regeln, die ich auf die Aggregation anwenden möchte:

  • Nach Möglichkeit sollten gekennzeichnete Gebiete nur mit anderen gekennzeichneten Gebieten aggregiert werden.
  • Für die gekennzeichneten Gebiete, die nicht an andere angrenzen (oder isolierte Gruppierungen, die die Kriterien immer noch nicht erfüllen), können sie mit Gebieten verbunden werden, die bereits den Kriterien entsprechen, obwohl es möglicherweise Gebiete gibt, zwischen denen sich keine Arbeitgeber befinden müssen enthalten sein.
  • Ich möchte die Bezirksgrenzen intakt halten, es sei denn, dies ist absolut unmöglich (und ich erwarte dies, indem ich die Eingabemerkmale vor der Verarbeitung in ihre jeweiligen Bezirke aufteile).
  • Die Lösung muss in Python unter Verwendung von ArcGIS-Tools oder Open-Source-Python-Bibliotheken vorliegen.

Im Idealfall kann mich jemand auf ein vorhandenes Mittel zur Implementierung dieser Aggregation hinweisen. Wenn nicht, codiere ich den Algorithmus gerne selbst, obwohl eine Liste spezifischer Schritte / Tools sehr willkommen wäre. Das Problem scheint mir ein Sonderfall der Umverteilung (mit nicht zusammenhängenden Polygonen) zu sein, und zu diesem Zweck habe ich die Verwendung der Regionalisierungsalgorithmen von PySAL untersucht , obwohl mir nicht klar ist, wie ich den maximalen Prozentsatz des Arbeitgebers an der Gesamtzahl der Beschäftigten, die diese verwenden, überprüfen kann .

nmpeterson
quelle

Antworten:

5

Für alle, die neugierig sind, habe ich selbst eine Lösung mit dem Region.Maxp-Algorithmus von PySAL entwickelt . Im Wesentlichen ermöglicht mir Max-p, eine Reihe von Regionen zu generieren, die mein erstes Kriterium erfüllen (Mindestanzahl von Arbeitgebern pro Region), und ich füge dies in eine while-Schleife ein, die alle Lösungen von Max-p ablehnt, die dies auch nicht tun das zweite Kriterium erfüllen (Prozentsatz der Beschäftigung, die der größte Arbeitgeber in einer Region beisteuert). Ich habe es als ArcGIS-Tool implementiert.

Ich beschloss, die Arbeit, die ich zuvor geleistet hatte, zu verwerfen, um Blöcke / Blockgruppen / Traktate zu kennzeichnen, und stattdessen Max-p für Blöcke auszuführen (obwohl ich alle meine Tests für Traktate durchgeführt habe, da die Anzahl der Eingabepolygone geringfügig zugenommen hat ein dramatischer Effekt auf die Verarbeitungszeit). Der relevante Teil meines Codes folgt. Das "Shapefile", das als Eingabe für die generate_regions()Funktion benötigt wird (als Zeichenfolge übergeben, die den vollständigen Pfad eines Shapefiles enthält), ist eines, mit dem die Punktmerkmale des Arbeitgebers bereits räumlich verbunden sind, mit der Anzahl der Arbeitgeber, maximal den Mitarbeitern eines einzelnen Arbeitgebers und Gesamtzahl der Mitarbeiter, die als Attribut für jede Eingabefunktion gespeichert sind.

import arcpy, math, pysal, random
import numpy as np

# Suppression criteria:
MIN_EMP_CT = 3      # Minimum number of employers per polygon feature
MAX_EMP_FRAC = 0.8  # Maximum ratio of employees working for a single employer per polygon feature

def generate_regions(shapefile, min_emp_ct=MIN_EMP_CT, max_emp_frac=MAX_EMP_FRAC):
    '''Use pysal's region.Maxp method to generate regions that meet suppression criteria.'''
    w = pysal.rook_from_shapefile(shapefile, idVariable='GEOID10')
    dbf = pysal.open(shapefile[:-4] + '.dbf')
    ids = np.array((dbf.by_col['GEOID10']))
    vars = np.array((dbf.by_col[employer_count_fieldname],dbf.by_col[max_employees_fieldname],dbf.by_col[total_employees_fieldname]))
    employers = vars[0]
    vars = vars.transpose()
    vars_dict = {}
    for i in range(len(ids)):
        vars_dict[ids[i]] = [int(vars[i][0]),float(vars[i][1]),float(vars[i][2])]
    random.seed(100)     # Using non-random seeds ensures repeatability of results
    np.random.seed(100)  # Using non-random seeds ensures repeatability of results
    bump_iter = int(arcpy.GetParameterAsText(3)) # Number of failed iterations after which to increment the minimum number of employers per region (otherwise we could be stuck in the loop literally forever).
    iteration = 0
    tests_failed = 1
    while tests_failed:
        floor = int(min_emp_ct + math.floor(iteration / bump_iter))
        solution = pysal.region.Maxp(w,vars,floor,employers)
        regions_failed = 0
        for region in solution.regions:
            SUM_emp10sum = 0
            MAX_emp10max = 0
            for geo in region:
                emp10max = vars_dict[geo][1]
                emp10sum = vars_dict[geo][2]
                SUM_emp10sum += emp10sum
                MAX_emp10max = max(MAX_emp10max, emp10max)
            if SUM_emp10sum > 0:
                ratio = MAX_emp10max / SUM_emp10sum
            else:
                ratio = 1
            if ratio >= max_emp_frac:
                regions_failed += 1
        iteration += 1
        if regions_failed == 0:
            arcpy.AddMessage('Iteration ' + str(iteration) + ' (MIN_EMP_CT = ' + str(floor) +') - PASSED!')
            tests_failed = 0
        else:
            arcpy.AddMessage('Iteration ' + str(iteration) + ' (MIN_EMP_CT = ' + str(floor) +') - failed...')
    return solution

solution = generate_regions(spatially_joined_shapefile)

regions = solution.regions

### Write input-to-region conversion table to a CSV file.
csv = open(conversion_table,'w')
csv.write('"GEOID10","REGION_ID"\n')
for i in range(len(regions)):
    for geo in regions[i]:
        csv.write('"' + geo + '","' + str(i+1) + '"\n')
csv.close()
nmpeterson
quelle
2

Ich bin noch nie auf eine solche Situation gestoßen, und ich glaube, ein üblicherer Weg besteht darin, die Einheiten, für die Sie sich a priori entscheiden, beizubehalten und dann verschiedene Techniken zu verwenden, um die Daten zu "fummeln", um Datenschutzbedenken zu schützen.

Für eine Einführung in die Vielzahl von Möglichkeiten, wie Menschen Daten maskieren, würde ich diesen Artikel vorschlagen.

Matthews, Gregory J. & Ofer Harel. 2011. Vertraulichkeit von Daten: Eine Überprüfung der Methoden zur Einschränkung der statistischen Offenlegung und der Methoden zur Bewertung des Datenschutzes . Statistikumfragen 5 : 1-29. Das PDF ist bei Project Euclid unter dem obigen Link frei verfügbar.

Ich habe auch einige Links zu verschiedenen anderen Artikeln, in denen "Geomasking" an diesem Tag in meiner Citeulike-Bibliothek behandelt wird (nicht alle beziehen sich jedoch ausschließlich auf geografische Daten).

Obwohl dies Ihre Frage nicht beantwortet, ist es möglich, dass einige der im Artikel von Matthews und Ofer aufgeführten Techniken einfacher zu implementieren sind, um Ihre Anforderungen zu erfüllen. Insbesondere die Erstellung synthetischer Daten scheint eine logische Erweiterung Ihres Aufenthaltsortes zu sein (die externen Daten würden bei Bedarf von der umliegenden Volkszählungsblockgruppe oder dem Gebiet oder dem Landkreis entlehnt). Einige Arten des Datenaustauschs (im Weltraum) sind möglicherweise auch einfacher zu implementieren.

Andy W.
quelle
Danke für die Antwort / den Kommentar. Mir ist bekannt, dass es Methoden gibt, um Daten zu verfälschen, um die statistische Gültigkeit zu erhalten und gleichzeitig die Privatsphäre zu schützen, obwohl dieses Papier mir geholfen hat, die Einzelheiten ein bisschen besser zu verstehen. Leider scheinen solche Methoden für meine Situation nicht besonders anwendbar zu sein, wenn die einzige Information, die ich veröffentliche, die Anzahl der Arbeitgeber und Arbeitnehmer in einem bestimmten Bereich ist: Ein Ummischen würde unweigerlich die Gültigkeit einer auf ihnen basierenden Analyse beeinträchtigen, nicht wahr?
nmpeterson
Die Aggregation wirkt sich auf möglicherweise ähnliche Weise auf die Analyse aus. Es ist jedoch schwierig, allgemeine Ratschläge zu geben, und Ihr Endprodukt sollte sich daran orientieren, was die Benutzer anschließend mit den Daten tun werden. Ich kann mir einige Situationen vorstellen, in denen es problematisch wäre, Endeinheiten aus variablen Aggregationen zu erstellen. Wenn ich zum Beispiel daran interessiert wäre, Agglomeration / Wettbewerb zwischen Arbeitgebern zu vergleichen, wären verschiedene Einheiten ein Problem, aber insbesondere, wenn ich fortfahren und sie mit anderen demografischen Daten aus der Volkszählung verknüpfen möchte.
Andy W
In diesem Fall hätte ich lieber eine Analyseeinheit mit einer beliebigen Fehlermenge, aber ich bin sicher, Sie können sich andere Verwendungen vorstellen, bei denen Aggregation und (theoretisch) kein Fehler vorzuziehen wären.
Andy W