Алгоритм сопоставления данных
В настоящее время я работаю над проектом, в котором должен быть реализован алгоритм сопоставления данных. Внешняя система передает все данные, которые она знает о клиенте, и система, которую я проектирую, должна возвращать согласованного клиента. Таким образом, внешняя система затем знает правильный идентификатор клиента, плюс она получает дополнительные данные или может обновлять свои собственные данные конкретного клиента.
Следующие поля передаются в:
- название
- Name2
- улица
- город
- Почтовый Индекс
- Номер банковского счета
- Название банка
- Код банка
- Эл. адрес
- Телефон
- факс
- Web
Данные могут быть высокого качества, и много информации доступно, но часто данные являются дрянными, и только имя и адрес доступны и могут иметь орфографию.
Я реализую проект в.Net. В настоящее время я делаю что-то вроде следующего:
public bool IsMatch(Customer customer)
{
// CanIdentify just checks if the info is provided and has a specific length (e.g. > 1)
if (CanIdentifyByStreet() && CanIdentifyByBankAccountNumber())
{
// some parsing of strings done before (substring, etc.)
if(Street == customer.Street && AccountNumber == customer.BankAccountNumber) return true;
}
if (CanIdentifyByStreet() && CanIdentifyByZipCode() &&CanIdentifyByName())
{
...
}
}
Я не очень доволен подходом выше. Это потому, что мне пришлось бы писать операторы if для всех разумных случаев (комбинаций), чтобы не упустить ни одного шанса на сопоставление сущности.
Поэтому я подумал, что, может быть, я смогу создать какой-нибудь подходящий счет Таким образом, для каждого соответствующего критерия будет добавлена оценка. Подобно:
public bool IsMatch(Customer customer)
{
int matchingScore = 0;
if (CanIdentifyByStreet())
{
if(....)
matchingScore += 10;
}
if (CanIdentifyByName())
{
if(....)
matchingScore += 10;
}
if (CanIdentifyBankAccountNumber())
{
if(....)
matchingScore += 10;
}
if(matchingScore > iDontKnow)
return true;
}
Это позволило бы мне принять во внимание все подходящие данные, и в зависимости от некоторого веса я бы увеличил счет соответствия. Если оценка достаточно высока, это совпадение.
Знайте, мой вопрос: есть ли лучшие практики для таких вещей, как сопоставление шаблонов алгоритмов и т. Д.? Большое спасибо!
4 ответа
Для вдохновения посмотрите на алгоритм расстояния Левенштейна. Это даст вам разумный механизм для взвешивания ваших сравнений.
Я также хотел бы добавить, что по моему опыту вы никогда не сможете сопоставить две произвольные части данных в одной и той же сущности с абсолютной уверенностью. Вам необходимо представить правдоподобные совпадения пользователю, который затем может точно проверить, что Джон Смит в 1920 г. Э. Пайн - это тот же человек, что и Джон Смит в 192 Ист-Пайн-роуд или нет.
По моему опыту с такими вещами, именно деловые люди определяли правила того, что было приемлемо как совпадение, а не как техническое решение. Это имело смысл для меня, так как бизнес принимает на себя риск. Кроме того, то, что составляет совпадение, может быть подвержено изменениям, например, если они используют систему и обнаружат, что слишком много людей исключено.
Я думаю, что ваш первый подход имеет больше смысла, потому что если вы можете сопоставить кого-то по имени и номеру банковского счета, то вы почти уверены, что это они. Однако, если имя и банковские данные не совпадают, но адрес, телефон и все, что совпадают (например, супруг (а)), тогда система подсчета очков может неправильно соответствовать людям. Я понимаю, что это много кода, но пока вы извлекаете фактический соответствующий код (метод matchPhoneNumber и т. Д.), То это хорошо с точки зрения дизайна.
Я, вероятно, сделаю еще один шаг и вытащу совпадение в перечисление, а затем получу список приемлемых совпадений. Вроде как это: interface Match {логические совпадения (Customer c1, Customer c2); }
class BankAccountMatch implements Match
{
public boolean matches(Customer c1, Customer c2)
{
return c1.getBankAccountNumber() == c2.getBankAccountNumber();
}
}
static Match BANK_ACCOUNT_MATCH = new BankAccountMatch();
Match[][] validMatches = new Match[] [] {
{BANK_ACCOUNT_MATCH, NAME_MATCH},
{NAME_MATCH, ADDRESS_MATCH, FAX_MATCH}, ...
};
И тогда код, который выполняет проверку, просто перебирает массив validMatches и проверяет их, чтобы убедиться, что он подходит. Я мог бы даже вытащить списки действительных совпадений в файл конфигурации. Это все зависит от уровня надежности вашей системы, хотя.
Как насчет подхода машинного обучения. Создайте. Расстояния на единицу.
Они становятся вашим входным пространством. Постройте тренировочный набор на правильно подобранных кастерах на основе этих расстояний. Бегите через ваш любимый машинный ученик. Получите параметры для функции решения, которые отражают силу соответствия. Tune. Применитесь к новым случаям. Иди в банк.
Если вы ограничиваете себя адресом и именем, вы можете просто использовать формулу сбора урожая или пространственный индекс, если у вас есть геолокация. Для названия вы можете использовать три и получить только первые результаты, может быть, 10.