Question

Nous avons une table SQL Server contenant le nom de la société, l'adresse et le nom du contact (entre autres).

Nous recevons régulièrement des fichiers de données provenant de sources extérieures, ce qui nous oblige à les comparer à ce tableau. Malheureusement, les données sont légèrement différentes car elles proviennent d’un système complètement différent. Par exemple, nous avons " 123 E. Main St. " et nous recevons "123 East Main Street". Un autre exemple, nous avons " Acme, LLC " et le fichier contient "Acme Inc.". Nous en avons un autre: "Ed Smith". et ils ont " Edward Smith "

Nous avons un système hérité qui utilise des méthodes plutôt complexes et gourmandes en ressources CPU pour gérer ces correspondances. Certaines impliquent du SQL pur et d'autres du code VBA dans une base de données Access. Le système actuel est bon mais pas parfait, encombrant et difficile à maintenir

La direction souhaite élargir son utilisation. Les développeurs qui hériteront du support du système veulent le remplacer par une solution plus agile nécessitant moins de maintenance.

Existe-t-il un moyen communément accepté de traiter ce type de correspondance de données?

Était-ce utile?

La solution

Voici quelque chose que j'ai écrit pour une pile presque identique (nous avions besoin de normaliser les noms de fabricant pour le matériel et il y avait toutes sortes de variations). C’est du côté client cependant (VB.Net pour être exact) - et utilisez l’algorithme de distance de Levenshtein (modifié pour de meilleurs résultats):

    Public Shared Function FindMostSimilarString(ByVal toFind As String, ByVal ParamArray stringList() As String) As String
        Dim bestMatch As String = ""
        Dim bestDistance As Integer = 1000 'Almost anything should be better than that!

        For Each matchCandidate As String In stringList
            Dim candidateDistance As Integer = LevenshteinDistance(toFind, matchCandidate)
            If candidateDistance < bestDistance Then
                bestMatch = matchCandidate
                bestDistance = candidateDistance
            End If
        Next

        Return bestMatch
    End Function

    'This will be used to determine how similar strings are.  Modified from the link below...
    'Fxn from: http://ca0v.terapad.com/index.cfm?fa=contentNews.newsDetails&newsID=37030&from=list
    Public Shared Function LevenshteinDistance(ByVal s As String, ByVal t As String) As Integer
        Dim sLength As Integer = s.Length ' length of s
        Dim tLength As Integer = t.Length ' length of t
        Dim lvCost As Integer ' cost
        Dim lvDistance As Integer = 0
        Dim zeroCostCount As Integer = 0

        Try
            ' Step 1
            If tLength = 0 Then
                Return sLength
            ElseIf sLength = 0 Then
                Return tLength
            End If

            Dim lvMatrixSize As Integer = (1 + sLength) * (1 + tLength)
            Dim poBuffer() As Integer = New Integer(0 To lvMatrixSize - 1) {}

            ' fill first row
            For lvIndex As Integer = 0 To sLength
                poBuffer(lvIndex) = lvIndex
            Next

            'fill first column
            For lvIndex As Integer = 1 To tLength
                poBuffer(lvIndex * (sLength + 1)) = lvIndex
            Next

            For lvRowIndex As Integer = 0 To sLength - 1
                Dim s_i As Char = s(lvRowIndex)
                For lvColIndex As Integer = 0 To tLength - 1
                    If s_i = t(lvColIndex) Then
                        lvCost = 0
                        zeroCostCount += 1
                    Else
                        lvCost = 1
                    End If
                    ' Step 6
                    Dim lvTopLeftIndex As Integer = lvColIndex * (sLength + 1) + lvRowIndex
                    Dim lvTopLeft As Integer = poBuffer(lvTopLeftIndex)
                    Dim lvTop As Integer = poBuffer(lvTopLeftIndex + 1)
                    Dim lvLeft As Integer = poBuffer(lvTopLeftIndex + (sLength + 1))
                    lvDistance = Math.Min(lvTopLeft + lvCost, Math.Min(lvLeft, lvTop) + 1)
                    poBuffer(lvTopLeftIndex + sLength + 2) = lvDistance
                Next
            Next
        Catch ex As ThreadAbortException
            Err.Clear()
        Catch ex As Exception
            WriteDebugMessage(Application.StartupPath , [Assembly].GetExecutingAssembly().GetName.Name.ToString, MethodBase.GetCurrentMethod.Name, Err)
        End Try

        Return lvDistance - zeroCostCount
    End Function

Autres conseils

SSIS (dans SQL 2005+ Enterprise) a recherche floue . qui est conçu pour de tels problèmes de nettoyage de données.

En dehors de cela, je ne connais que des solutions spécifiques à un domaine, telles que le nettoyage des adresses , ou techniques de correspondance des chaînes .

De nombreux fournisseurs proposent des produits permettant ce type de correspondance. Je voudrais faire des recherches et trouver un bon produit bien réputé et mettre au rebut le système développé à la maison .

Comme vous le dites, votre produit n’est que bon, et c’est un besoin assez commun pour les entreprises qui, j'en suis sûr, ont plus d’un excellent produit sur le marché. Même si une licence coûte quelques milliers de dollars, cela coûtera toujours moins cher que de payer un lot de développeurs pour travailler sur quelque chose en interne.

En outre, le fait que les expressions "complexe", "gourmand en ressources CPU", "code VBA" et " Accès à la base de données " apparaître ensemble dans la description de votre système est une autre raison de trouver un bon outil tiers.

EDIT: il est également possible que .NET ait un composant intégré qui effectue ce type de tâche, auquel cas vous n’auriez pas à payer pour cela. Je suis toujours surpris de temps en temps par les outils offerts par .NET.

Je traite exactement le même problème. Regardez:

Outils permettant de faire correspondre les données de nom / adresse

pour des outils qui pourraient aider.

Access n’a pas vraiment les outils pour cela. Dans un monde idéal, j'utiliserais la solution SSIS et utiliserais la recherche floue. Mais si vous utilisez actuellement Access, les chances que votre bureau achète l'édition SQL Server Enterprise me paraissent faibles. Si vous êtes coincé dans l'environnement actuel, vous pouvez essayer une approche de force brute.

Commencez par un nettoyage normalisé des adresses. Abréviations standards PIck pour Street, raod, etc. et écrire du code pour modifier toutes les variations normales de ces addesses standard. Remplacez toutes les occurrences de deux espaces par un espace, coupez toutes les données et supprimez les caractères non alphanumériques. Comme vous pouvez le constater, c’est une tâche ardue.

En ce qui concerne les noms de sociétés, vous pouvez peut-être essayer de faire correspondre les 5 premiers caractères du nom et de l'adresse ou du téléphone. Vous pouvez également créer un tableau des variations connues et de leur lien dans votre base de données à utiliser pour nettoyer les futurs fichiers. Donc, si vous enregistrez avec l'id 100, c'est Acme, Inc., vous pourriez avoir un tableau comme celui-ci:

Nom idfield

100 Acme, Inc.

100 Acme, Inc

100 Acme, Incorporated

100 Acme, LLC

100 Acme

Cela commencera petit, mais augmentera avec le temps si vous faites une entrée à chaque fois que vous trouvez et corrigez un doublon (faites-en une partie du processus de déduplication) et si vous faites une entrée à chaque fois que vous pouvez faire correspondre le premier. partie du nom et de l'adresse d'une entreprise existante.

Je regarderais aussi cette fonction que Torial a postée pour voir si ça aide.

Tout cela serait pénible et prendrait beaucoup de temps, mais s'améliorerait avec le temps à mesure que vous trouviez de nouvelles variantes et que vous les ajoutiez au code ou à la liste. Si vous décidez de normaliser vos données d'adresse, assurez-vous de nettoyer d'abord les données de production, puis importez-les dans une table de travail, nettoyez-les, puis essayez de faire correspondre les données de production et d'insérer de nouveaux enregistrements.

Je viens de trouver ce lien associé.

Je jure que j'ai regardé avant de poster ceci.

Il existe de nombreuses façons de s’y attaquer qui peuvent ne pas être évidentes. Le mieux est de trouver des identifiants uniques que vous pouvez utiliser pour la correspondance en dehors des champs avec des orthographes erronées, etc.

Quelques pensées

  1. L'évident, numéro de sécurité sociale, permis de conduire, etc.
  2. Adresse électronique
  3. Numéro de téléphone nettoyé (supprimer la ponctuation, etc.)

En ce qui concerne les vendeurs, je viens de répondre à une question similaire et je colle en dessous.

Chaque fournisseur principal a sa propre solution. Oracle, IBM, SAS Dataflux, etc. et chacun prétend être le meilleur face à ce genre de problème.

Évaluation vérifiée indépendante:

Une étude réalisée au Centre australien de couplage de données de l’Université Curtin en Australie a simulé la correspondance de 4,4 millions d’enregistrements. Identifié ce que les fournisseurs avaient en termes d'exactitude (Nombre de correspondances trouvées par rapport à disponible. Nombre de correspondances fausses)

DataMatch Enterprise, Précision maximale (> 95%), très rapide, faible coût

Etape de qualité IBM , haute précision (> 90%), très rapide, coût élevé (& nd; 100 000 USD)

Flux de données SAS, précision moyenne (> 85%), rapide, coût élevé (> 100K) C’est la meilleure évaluation indépendante que nous ayons trouvée, très minutieuse.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top