Pergunta

Nós temos uma tabela do SQL Server que contém nome da empresa, endereço, e Nome de contato (entre outros).

Recebemos regularmente arquivos de dados de fontes externas que nos obrigam a corresponder-se contra esta tabela. Infelizmente, os dados é um pouco diferente, uma vez que é proveniente de um sistema completamente diferente. Por exemplo, temos "123 E. Main St." e recebemos "123 East Main Street". Outro exemplo, temos "Acme, LLC" e o arquivo contém "Acme Inc.". Outra é, temos "Ed Smith" e têm "Edward Smith"

Temos um sistema legado que utiliza alguns métodos intensivos em vez intrincados e CPU para lidar com esses jogos. Alguns envolvem SQL pura e outros envolvem código VBA em um banco de dados Access. O sistema atual é bom, mas não perfeito e é pesado e difícil de manter

A gestão aqui quer expandir seu uso. Os desenvolvedores que herdarão o apoio do sistema quer substituí-lo por uma solução mais ágil que requer menos manutenção.

Existe uma maneira comumente aceitos para lidar com esse tipo de correspondência de dados?

Foi útil?

Solução

O Aqui algo que escrevi para uma pilha quase idêntico (que precisávamos para padronizar os nomes de fabricantes de hardware e havia todos os tipos de variações). Este é o lado cliente embora (VB.Net para ser exato) - e usar o algoritmo de distância Levenshtein (alterado para melhores resultados):

    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

Outras dicas

SSIS (em Sql 2005 + Empresa) tem Pesquisa Difusa que é projetado para apenas esses dados limpeza problemas.

Além disso, eu só sei de soluções específicas de domínio - como limpeza endereço , ou geral técnicas cadeia correspondente .

Existem muitos fornecedores lá fora, que oferecem produtos para fazer esse tipo de correspondência padrão. Gostaria de fazer algumas pesquisas e encontrar um bom, produto bem reputado e sucata o sistema de home-grown .

Como você disse, o produto só é bom, e esta é uma necessidade comum o suficiente para as empresas que eu tenho certeza que há mais do que um excelente produto para fora. Mesmo se ele custa alguns milhares de dólares para uma licença, ainda vai ser mais barato do que pagar um monte de desenvolvedores para trabalhar em algo em casa.

Além disso, o fato de que as frases "intricado", "CPU", "código VBA" e "banco de dados Access" aparecem juntos na descrição do seu sistema é outra razão para encontrar uma boa ferramenta de terceiros.

EDIT: também é possível que o .NET tem um built-in componente que faz esse tipo de coisa, caso em que você não teria que pagar por isso. Ainda fico surpreso de vez em quando pelas ferramentas que o .NET ofertas.

Estou lidando com exatamente o mesmo problema. Dê uma olhada em:

Ferramentas para nome correspondente / dados de endereço

para algumas ferramentas que podem ajudar.

Acesso realmente não tem as ferramentas para isso. Em um mundo ideal eu iria com a solução SSIS e usar pesquisa difusa. Mas se você estiver usando o Access, as chances de seu escritório comprando edição do SQL Server Enterprise parecer baixo para mim. Se você está preso com o ambiente atual, você pode tentar uma abordagem de força bruta.

Comece com limpeza padronizados de endereços. Pick abreviaturas padrão para Street, raod, etc. e escrever código para alterar todas as variações normais para esses addesses padrão. Substitua todas as instâncias de dois espaços com um espaço, cortar todos os dados e remover quaisquer caracteres não alfanuméricos. Como você pode ver esta é uma tarefa bastante.

Quanto aos nomes de empresas, talvez você possa testar a correspondência em 5 primeiros caracteres do nome e do endereço ou telefone. Você também pode criar uma tabela de variações conhecidas e que eles vão se relacionar no seu banco de dados para uso para cleanising arquivos futuros. Então, se você gravar com ID 100 é Acme, Inc. você poderia ter uma tabela como esta:

IDField Nome

100 Acme, Inc.

100 Acme, Inc

100 Acme, Incorporated

100 Acme, LLC

100 Acme

Isto irá começar pequeno, mas construir ao longo do tempo se você fizer uma entrada cada vez que você encontrar e corrigir uma duplicata (torná-lo parte de você de-dupping processo) e se você fizer uma entrada cada vez que você é capaz de combinar com o primeiro parte do nome e endereço de uma empresa já existente.

Eu também olhar para essa função torial publicado e ver se isso ajuda.

Tudo isso seria doloroso e demorado, mas iria ficar melhor ao longo do tempo como você encontrar novas variações e adicioná-los ao código ou lista. Se você decidir stardardize seu addressdata, certifique-se de dados de produção limpa em primeiro lugar, em seguida, fazer qualquer importação para uma mesa de trabalho e limpá-lo, em seguida, tentar igualar a dados de produção e inserir novos registros.

Eu encontrei esta ligação que está relacionado.

Eu juro que eu olhei antes de eu postei isso.

Há algumas maneiras para resolver este que pode não ser óbvio. O melhor é encontrar identificadores exclusivos que você pode usar para combinar fora dos campos com mis grafias, etc.

Alguns pensamentos

  1. O óbvio, número de segurança social, carteira de motorista, etc
  2. endereço de e-mail
  3. número Cleansed telefone (Rremove pontuação, etc)

Quanto fornecedores vão Eu apenas respondeu a uma pergunta semelhante e estou colando abaixo.

Cada grande provedor tem sua própria solução. Oracle, IBM, SAS DataFlux, etc e cada pretensão de ser o melhor neste tipo de problema.

Independent avaliação verificada:

Houve um estudo feito pelo Centro Universitário Curtin para Dados Linkage na Austrália, que simulou a correspondência de 4,4 milhões de registros. Identificado o que os provedores teve em termos de precisão (Número de registro de jogos vs disponível. Número de falsas partidas)

DataMatch Empresa, Melhor Precisão (> 95%), muito rápido, de baixo custo

IBM Qualidade Stage , de alta precisão (> 90 %), muito rápido, alto custo (> $ 100K)

SAS Flux dados, precisão média (> 85%), Fast, alto custo (> 100K) Essa foi a melhor avaliação independente poderíamos encontrar, foi muito completo.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top