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

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

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

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

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

Есть ли общепринятый способ справиться с подобным сопоставлением данных?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
5
0
421
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

Ответ принят как подходящий

Вот что я написал для почти идентичного стека (нам нужно было стандартизировать названия производителей оборудования, и было множество вариантов). Однако это клиентская сторона (точнее, 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

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

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

Это отличные ссылки, и нечеткий поиск выглядит увлекательно. Спасибо

wcm 24.09.2008 16:54

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

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

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

Обновлено: также возможно, что .NET имеет встроенный компонент, который делает такие вещи, и в этом случае вам не придется за него платить. Я до сих пор время от времени удивляюсь инструментам, которые предлагает .NET.

Это кажется хорошим и разумным советом. Я должен сказать, что система просто выросла за последние несколько лет. Когда я сюда приехал, он был на месте и всегда работал достаточно хорошо. Ключевые слова «Доступ» и «VBA» тоже заставляют меня съежиться: o) Спасибо!

wcm 24.09.2008 17:01

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

MusiGenesis 24.09.2008 17:10

У меня точно такая же проблема. Взгляни на:

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

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

Я сделал поиск, прежде чем добавить вопрос. Я клянусь. На этот вопрос есть действительно хорошие ответы. Спасибо

wcm 24.09.2008 18:04

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

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

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

idfield Имя

100 Acme, Inc.

100 Acme, Inc

100 Acme, Incorporated

100 Акме, ООО

100 Акме

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

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

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

Спасибо за вдумчивый ответ. Данные хранятся на сервере SQL Server 2000 Enterprise. У нас есть доступ к 2005 году. Именно так подрядчик решил в то время решить эту конкретную проблему. Вот почему вам НИКОГДА не следует использовать Access даже для, казалось бы, несущественных задач.

wcm 24.09.2008 18:13

Вы всегда можете изменить серверную часть на SQL-сервер, сохранив всю работу пользовательского интерфейса и позволив вам выполнить очистку в серверной части.

HLGEM 24.09.2008 18:36

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

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

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

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

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

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

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

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

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

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

Другие вопросы по теме