Dedupe Python - «Записи не совпадают с моделью данных» - PullRequest
0 голосов
/ 22 января 2019

Я застрял с настройкой python и библиотекой дедупликации из dedupe.io для дедупликации набора записей в базе данных postgres. Ошибка - « Записи не совпадают с моделью данных », что должно быть легко решить, но я просто не понимаю, почему я получаю это сообщение.

Что у меня сейчас (сосредоточенный код и убраны другие функции)

# ## Setup
settings_file = 'lead_dedupe_settings'
training_file = 'lead_dedupe_training.json'

start_time = time.time()

...

def training():
    # We'll be using variations on this following select statement to pull
    # in campaign donor info.
    #
    # We did a fair amount of preprocessing of the fields in

    """ Define Lead Query """
    sql = "select id, phone, mobilephone, postalcode, email from dev_manuel.somedata"

    # ## Training

    if os.path.exists(settings_file):
        print('reading from ', settings_file)
        with open(settings_file, 'rb') as sf:
            deduper = dedupe.StaticDedupe(sf, num_cores=4)
    else:

        # Define the fields dedupe will pay attention to
        #
        # The address, city, and zip fields are often missing, so we'll
        # tell dedupe that, and we'll learn a model that take that into
        # account
        fields = [
                {'field': 'id', 'type': 'ShortString'},
                {'field': 'phone', 'type': 'String', 'has missing': True},
                {'field': 'mobilephone', 'type': 'String', 'has missing': True},
                {'field': 'postalcode', 'type': 'ShortString', 'has missing': True},
                {'field': 'email', 'type': 'String', 'has missing': True}
                ]

        # Create a new deduper object and pass our data model to it.
        deduper = dedupe.Dedupe(fields, num_cores=4)


        # connect to db and execute
        conn = None
        try:
            # read the connection parameters
            params = config()
            # connect to the PostgreSQL server
            conn = psycopg2.connect(**params)
            print('Connecting to the PostgreSQL database...')

            cur = conn.cursor()
            # excute sql
            cur.execute(sql)

            temp_d = dict((i, row) for i, row in enumerate(cur))

            print(temp_d)

            deduper.sample(temp_d, 10000)

            print('Done stage 1')

            del temp_d

            # close communication with the PostgreSQL database server
            cur.close()

        except (Exception, psycopg2.DatabaseError) as error:
            print(error)
        finally:
            if conn is not None:
                conn.close()
                print('Closed Connection')

        # If we have training data saved from a previous run of dedupe,
        # look for it an load it in.
        #
        # __Note:__ if you want to train from
        # scratch, delete the training_file
        if os.path.exists(training_file):
            print('reading labeled examples from ', training_file)
            with open(training_file) as tf:
                deduper.readTraining(tf)

        # ## Active learning

        print('starting active labeling...')
        # Starts the training loop. Dedupe will find the next pair of records
        # it is least certain about and ask you to label them as duplicates
        # or not.

        # debug
        print(deduper)
        # vars(deduper)

        # use 'y', 'n' and 'u' keys to flag duplicates
        # press 'f' when you are finished
        dedupe.convenience.consoleLabel(deduper)
        # When finished, save our labeled, training pairs to disk
        with open(training_file, 'w') as tf:
            deduper.writeTraining(tf)

        # Notice our argument here
        #
        # `recall` is the proportion of true dupes pairs that the learned
        # rules must cover. You may want to reduce this if your are making
        # too many blocks and too many comparisons.
        deduper.train(recall=0.90)

        with open(settings_file, 'wb') as sf:
            deduper.writeSettings(sf)

        # We can now remove some of the memory hobbing objects we used
        # for training
        deduper.cleanupTraining()

Сообщение об ошибке: «Записи не совпадают с моделью данных. Поле« id »находится в data_model, но не в записи». Как видите, я определяю 5 полей для «изучения». Запрос, который я использую, возвращает мне именно эти 5 столбцов с данными в нем. Выход

print(temp_d)

есть

{0: ('00Q1o00000OjmQmEAJ', '+4955555555', None, '01561', None), 1: ('00Q1o00000JhgSUEAZ', None, '+4915555555', '27729', 'email@aemail.de')}

Что выглядит как корректный ввод для библиотеки дедупликации.

Что я пробовал

  • Я проверил, если он уже записал файл в качестве учебного набора, который получит как-то читать и использовать, это не так (код даже сказал бы она)
  • Я попытался отладить «дедупер» объект, где определение поля и тому подобное, я вижу определение полей
  • глядя на другие примеры, такие как CSV или MySQL, которые делают почти то же самое, что и я.

Пожалуйста, укажите мне, где я ошибаюсь.

1 Ответ

0 голосов
/ 25 апреля 2019

Похоже, проблема может заключаться в том, что ваш temp_d является словарем кортежей, а не ожидаемым вводом словаря словарей. Я только начал работать с этим пакетом и нашел пример здесь , который работает для моих целей, который предоставляет эту функцию для настройки словаря, хотя из csv вместо извлечения данных, которое у вас есть в вашем.

data_d = {}
with open(filename) as f:
    reader = csv.DictReader(f)
    for row in reader:
        clean_row = [(k, preProcess(v)) for (k, v) in row.items()]
        row_id = int(row['Id'])
        data_d[row_id] = dict(clean_row)

return data_d
...