У нас есть таблица SQL Server, содержащая название компании, адрес и контактное имя (среди прочего).
Мы регулярно получаем файлы данных из внешних источников, которые требуют от нас сопоставления с этой таблицей. К сожалению, данные немного другие, так как они поступают из совершенно другой системы. Например, у нас есть "123 E. Main St.". и мы получаем "123 East Main Street". Другой пример, у нас есть «Acme, LLC», а файл содержит «Acme Inc.». Другой - у нас есть «Эд Смит», а у них - «Эдвард Смит»
У нас есть устаревшая система, которая использует некоторые довольно сложные и ресурсоемкие методы обработки этих совпадений. Некоторые используют чистый SQL, а другие включают код VBA в базе данных Access. Текущая система хороша, но не идеальна, громоздка и сложна в обслуживании.
Здесь руководство хочет расширить его использование. Разработчики, которые унаследуют поддержку системы, хотят заменить ее более гибким решением, требующим меньшего обслуживания.
Есть ли общепринятый способ справиться с подобным сопоставлением данных?





Вот что я написал для почти идентичного стека (нам нужно было стандартизировать названия производителей оборудования, и было множество вариантов). Однако это клиентская сторона (точнее, 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) имеет Нечеткий поиск, который предназначен как раз для таких задач очистки данных.
Помимо этого, я знаю только решения для конкретной предметной области, такие как очистка адреса или общий методы сопоставления строк.
Есть много поставщиков, которые предлагают продукты для подобного сопоставления с образцом. Я бы сделал небольшое исследование и найти хороший продукт с хорошей репутацией и отказаться от отечественной системы.
Как вы говорите, ваш продукт только хорош, и это достаточно распространенная потребность предприятий, и я уверен, что существует не один отличный продукт. Даже если лицензия будет стоить несколько тысяч долларов, это все равно будет дешевле, чем платить группе разработчиков за работу над чем-то собственными силами.
Кроме того, тот факт, что фразы «сложный», «интенсивно использующий процессор», «код VBA» и «база данных Access» встречаются вместе в описании вашей системы, является еще одной причиной для поиска хорошего стороннего инструмента.
Обновлено: также возможно, что .NET имеет встроенный компонент, который делает такие вещи, и в этом случае вам не придется за него платить. Я до сих пор время от времени удивляюсь инструментам, которые предлагает .NET.
Это кажется хорошим и разумным советом. Я должен сказать, что система просто выросла за последние несколько лет. Когда я сюда приехал, он был на месте и всегда работал достаточно хорошо. Ключевые слова «Доступ» и «VBA» тоже заставляют меня съежиться: o) Спасибо!
Слушать, как программист рассказывает о приложении Access, которое они унаследовали, - все равно что слушать, как больной раком рассказывает о химиотерапии. Сочувствую, но точно не хочу быть тобой.
У меня точно такая же проблема. Взгляни на:
Инструменты для сопоставления данных имени / адреса
для некоторых инструментов, которые могут помочь.
Я сделал поиск, прежде чем добавить вопрос. Я клянусь. На этот вопрос есть действительно хорошие ответы. Спасибо
В 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 даже для, казалось бы, несущественных задач.
Вы всегда можете изменить серверную часть на SQL-сервер, сохранив всю работу пользовательского интерфейса и позволив вам выполнить очистку в серверной части.
Есть несколько способов решить эту проблему, которые могут быть неочевидными. Лучше всего найти уникальные идентификаторы, которые можно использовать для сопоставления вне полей с неправильным написанием и т. д.
Некоторые мысли
Что касается производителей, я просто ответил на аналогичный вопрос и вставляю его ниже.
У каждого крупного провайдера есть собственное решение. Oracle, IBM, SAS Dataflux и т. д., И все они заявляют, что они лучше всех справляются с подобными проблемами.
Независимая проверенная оценка:
В Центре связи данных при Университете Кертина в Австралии было проведено исследование, в котором моделировалось сопоставление 4,4 миллиона записей. Определяли, какие поставщики имели с точки зрения точности (количество найденных и доступных совпадений. Количество ложных совпадений)
DataMatch Enterprise, Самая высокая точность (> 95%), очень быстро, низкая стоимость
IBM Quality Stage, высокая точность (> 90%), очень быстрая, высокая стоимость (> 100 тыс. Долларов США)
Поток данных SAS, средняя точность (> 85%), быстрый, высокая стоимость (> 100 тыс.) Это была лучшая независимая оценка, которую мы смогли найти, она была очень тщательной.
Это отличные ссылки, и нечеткий поиск выглядит увлекательно. Спасибо