Сравнение данных - PullRequest
       45

Сравнение данных

5 голосов
/ 24 сентября 2008

У нас есть таблица SQL Server, содержащая имя компании, адрес и имя контакта (среди прочих).

Мы регулярно получаем файлы данных из внешних источников, которые требуют от нас сопоставления с этой таблицей. К сожалению, данные немного отличаются, поскольку они поступают из совершенно другой системы. Например, у нас есть "123 E. Main St." и мы получаем "123 East Main Street". Другой пример, у нас есть «Acme, LLC», а файл содержит «Acme Inc.». Другой, у нас есть «Эд Смит», и у них есть «Эдвард Смит»

У нас есть устаревшая система, которая использует некоторые довольно сложные и ресурсоемкие методы для обработки этих совпадений. Некоторые включают чистый SQL, а другие - код VBA в базе данных Access. Нынешняя система хороша, но не совершенна, громоздка и сложна в обслуживании

Руководство здесь хочет расширить его использование. Разработчики, которые унаследуют поддержку системы, хотят заменить ее более гибким решением, которое требует меньшего обслуживания.

Существует ли общепринятый способ работы с такого рода сопоставлением данных?

Ответы [ 7 ]

4 голосов
/ 24 сентября 2008

Вот кое-что, что я написал для почти идентичного стека (нам нужно было стандартизировать названия производителей для оборудования, и было все виды вариаций). Это на стороне клиента (VB.Net, если быть точным) - и использовать алгоритм расстояния Левенштейна (модифицированный для лучших результатов):

    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
2 голосов
/ 24 сентября 2008

Я имею дело с точно такой же проблемой. Взгляните на:

Инструменты для сопоставления данных имени / адреса

для некоторых инструментов, которые могут помочь.

2 голосов
/ 24 сентября 2008

Есть много поставщиков, которые предлагают продукты для такого типа сопоставления с образцом. Я бы провел некоторое исследование и нашел бы хороший продукт с хорошей репутацией и отказался бы от отечественной системы .

Как вы говорите, ваш продукт только хороший, и это достаточно распространенная потребность для бизнеса, и я уверен, что существует более одного превосходного продукта. Даже если лицензия будет стоить несколько тысяч долларов, она все равно будет дешевле, чем платить кучке разработчиков за работу над чем-то внутри.

Кроме того, тот факт, что фразы "запутанный", "интенсивно использующий процессор", "код VBA" и "база данных доступа" встречаются вместе в описании вашей системы, является еще одной причиной для поиска хорошего стороннего инструмента.

РЕДАКТИРОВАТЬ: также возможно, что .NET имеет встроенный компонент, который делает такие вещи, в этом случае вам не придется платить за это. Время от времени я все еще удивляюсь инструментам, которые предлагает .NET.

2 голосов
/ 24 сентября 2008

SSIS (в Sql 2005+ Enterprise) имеет Fuzzy Lookup , который предназначен именно для таких проблем очистки данных.

Кроме этого, я знаю только о решениях для конкретной области, таких как очистка адреса или общие методы сопоставления строк .

1 голос
/ 24 сентября 2008

У Access на самом деле нет инструментов для этого. В идеальном мире я бы использовал решение SSIS и использовал нечеткий поиск. Но если вы в настоящее время используете Access, шансы вашего офиса на покупку выпуска SQL Server Enterprise кажутся мне низкими. Если вы застряли в текущей среде, вы можете попробовать подход грубой силы.

Начните со стандартной очистки адресов. Выберите стандартные сокращения для улиц, улиц и т. Д. И напишите код, чтобы изменить все обычные варианты этих стандартных адресов. Замените все экземпляры двух пробелов одним пробелом, обрежьте все данные и удалите все не алфавитно-цифровые символы. Как видите, это довольно сложная задача.

Что касается названий компаний, возможно, вы можете попробовать сопоставить первые 5 символов имени и адреса или телефона. Вы также можете создать таблицу известных вариантов и того, с чем они будут связаны в вашей базе данных, чтобы использовать их для очистки будущих файлов. Так что если вы записываете с идентификатором 100 Acme, Inc., у вас может быть такая таблица:

Имя idfield

100 Acme, Inc.

100 Acme, Inc

100 Acme, Incorporated

100 Акме, ООО

100 Acme

Это начнется с небольшого размера, но будет со временем формироваться, если вы будете делать запись каждый раз, когда найдете и исправляете дубликат (сделайте его частью процесса удаления дубликатов), и если вы делаете запись каждый раз, когда сможете найти первое часть названия и адрес существующей компании.

Я бы также посмотрел на эту функцию, опубликованную Ториалом, и посмотрю, поможет ли это.

Все это будет болезненным и трудоемким, но со временем станет лучше, если вы найдете новые варианты и добавите их в код или список. Если вы решите стандартизировать свои адресные данные, сначала обязательно очистите производственные данные, затем выполните любой импорт в рабочую таблицу и очистите ее, а затем попытайтесь сопоставить с производственными данными и вставить новые записи.

0 голосов
/ 12 сентября 2013

Существует довольно много способов решения этой проблемы, которые могут быть неочевидны. Лучше всего найти уникальные идентификаторы, которые можно использовать для сопоставления за пределами полей с ошибочными написаниями и т. Д.

Некоторые мысли

  1. Очевидный номер социального страхования, водительские права и т. Д.
  2. Адрес электронной почты
  3. Чистый номер телефона (убрать пунктуацию и т. Д.)

Что касается продавцов, я только что ответил на аналогичный вопрос и вставляю ниже.

У каждого крупного поставщика есть свое решение. Oracle, IBM, SAS Dataflux и т. Д., И каждый из них утверждает, что является лучшим в подобной проблеме.

Независимая проверенная оценка:

Было проведено исследование в Центре связи данных университета Кертина в Австралии, которое имитировало сопоставление 4,4 миллиона записей. Определил, какие поставщики имели с точки зрения точности (Количество найденных совпадений и доступных. Количество ложных совпадений)

DataMatch Enterprise, Высочайшая точность (> 95%), Очень быстрая, низкая стоимость

IBM Quality Stage , высокая точность (> 90%), очень быстрая, высокая стоимость (> 100 000 долл. США)

SAS Data Flux, средняя точность (> 85%), быстрая, высокая стоимость (> 100K) Это была лучшая независимая оценка, которую мы смогли найти, она была очень тщательной.

0 голосов
/ 24 сентября 2008

Я только что нашел эту ссылку , которая связана.

Клянусь, что посмотрел, прежде чем опубликовать это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...