Очищення даних з OpenRefine
Last updated
Last updated
Автори: Сет ван Холанд, Рубен Ферборх та Макс де Вільде Переклала українською: Ліана Бліхарська Оригінал уроку:
Цей урок пропонує рішення для науковців щодо визначення коректності зібраних даних та відповідних дій щодо них.
Не сприймайте ваші дані за чисту монету. Дбайте про те, щоб дані з якими працюєте, були максимально коректними. Допомогти вам у цьому покликаний урок нижче. Він зосереджується на тому, як науковці можуть оцінити коректність даних і діяти відповідно до цього. Ви ознайомитесь з принципами і практиками очищення даних, а також дізнаєтесь, які чотири основні завдання з використанням можуть в цьому допомогти:
Видалення записів-дублікатів
Відокремлення декількох значень, що містяться в одному полі
Аналіз розподілу значень у наборі даних
Групування різних відображень однієї і тієї ж реальності
Виконання цих кроків ми проілюструємо на основі даних, отриманих з реєстраційних карток львівського ґетто, та продемонструємо, як (напів)автоматизовані методи допоможуть виправити неточності у ваших даних.
Дублікати записів, порожні значення та неузгоджені формати — ми повинні бути готові мати справу з такими випадками під час роботи з наборами історичних даних. Цей урок навчить вас знаходити розбіжності в записах, що містяться в електронних таблицях або базах даних. Позаяк ми все частіше ділимося, збираємо і повторно використовуємо дані в Інтернеті, історикам доведеться зважати на проблеми, які неминуче виникатимуть у зв'язку з якістю даних. Використовуючи програму OpenRefine, ви зможете легко виявити систематичні помилки, на кшталт порожніх комірок, дублікатів, орфографічних неточностей тощо. OpenRefine дозволяє не тільки швидко діагностувати коректність ваших даних, але й коригувати певні помилки в автоматичний спосіб.
Окрім операцій та очищення даних, додаткові розширення OpenRefine дозволяють користувачам ідентифікувати вирази/об’єкти/поняття в неструктурованому тексті (це процес, який називається (РІС), а також узгоджувати власні дані з наявними базами знань. Таким чином, OpenRefine може бути практичним інструментом для пов'язування даних з виразами та відомостями, які вже опубліковані або (OCLC). Очищення даних є передумовою для цих кроків; рівень успішності РІС як і успішність зіставлення із даними третіх сторін залежить від здатності зробити ваші дані якомога більш цілісними.
Для сьогоднішнього уроку ми використаємо інформацію, отриману в результаті роботи з реєстраційними картками мешканців львівського ґетто.
У цьому уроці, ви працюватимете зі спеціально підготовлено таблицею, яка містить записи з цих карток та інформацію про історичні назви вулиць.
На стартовій сторінці OpenRefine створіть новий проєкт вибравши опцію "Create project" ("Створити проєкт"), оберіть завантажений файл з даними, і натисніть кнопку "Next" ("Далі"). За замовчуванням, перший рядок буде правильно розпізнано як назву стовпця.
У цьому випадку, вам потрібно буде упевнитись, що у налаштуваннях внизу, знято прапорець біля опції "Use character" to enclose cells containing column separators" ("Застосувати лапки для створення комірок, що містять роздільники стовпців"). Лапки у файлі не мають жодного значення для процесів у OpenRefine. Натомість виберіть "Attempt to parse cell text into numbers" ("Розпізнати числа у текстових комірках"), щоб дозволити OpenRefine автоматично розпізнавати числа. Тепер натисніть кнопку "Create project" ("Створити проєкт"). Якщо все правильно запущено, ви побачите 106 рядків.
Дані у таблиці поділені за логікою записів у картках. Одна реєстраційна картка відповідає одному рядку, а в кожному рядку — тринадцять стовпців: більшість з них відповідає категоріям, які були вписані реєстраторами та є автентичними даними, наприклад: номер картки, прізвище, ім’я, день, місяць, рік народження, місце проживання (назва вулиці), місце проживання (номер будинку, та якщо є — помешкання), професія, місце працевлаштування, примітки. Два стовпці були додані авторами: номер відповідно до послідовності оцифрування карток та історичні назви згаданих вулиць. У цьому уроці нас найбільше цікавлять назви вулиць, саме з ними будемо виконувати подальші операції.
Перше, що потрібно зробити, це ознайомитись зі своїми даними. Ви можете перевірити різні значення даних, відображаючи їх у . Ви можете уявити фасет як лінзу, через яку переглядаєте певний набір даних на основі обраного вами критерію. Натисніть на трикутник перед назвою стовпця, виберіть "Facet" і створіть фасет, який відповідатиме вашим потребам. Наприклад, спробуйте створити фільтр (фасет) щодо тексту "Text facet"
або числа "Numeric facet"
, залежно від типу значень, що містяться в стовпцях (числові значення позначені зеленим кольором). Пам'ятайте, що текстові фасети найкраще використовувати для полів з великими значеннями (наприклад, вираховувати повторюваність назв вулиць у колонці "Wohnung Str."). Якщо ви зіткнетеся з помилкою "Too many to display" ("Занадто багато для відображення"), ви можете збільшити ліміт кількості варіантів за замовчуванням до 2000, але занадто високий ліміт може сповільнити роботу програми (5000 зазвичай є безпечним вибором). Числові фільтри не мають цього обмеження.
Щоб отримати більше можливостей, виберіть "Customized facets" ("Настроювані фасети"): наприклад, фасети для порожніх полів ("Facet by blank (Null or empty string)") корисні для того, щоб виявити записи із порожніми комірками. Ми розглянемо ці можливості в наступних вправах.
При створенні числового фасету для стовпця "Geburtsdatum" ("Дата народження" (рік), ви помітите, що у таблиці є чотири порожні рядки. Ви можете знайти їх, знявши прапорець для критерію "Numeric" ("Числові"), залишивши лише нечислові та порожні значення. Насправді, ці значення не є порожніми, вони недруковані символи, у чому ви зможете пересвідчитись, навівши курсор до місця, де мало б бути значення, і побачите там кнопку "Edit" ("Редагувати"). Тобто, навіть під час роботи з вже готовими файлами даних ви можете редагувати їх вручну.
Щоб видалити ці порожні рядки, натисніть трикутник першого стовпчика під назвою "All" ("Всі"), виберіть "Edit rows" ("Редагувати рядки"), а потім "Remove matching rows" ("Видалити рядки, що повторюються"). Закрийте числовий фасет, щоб побачити те, що залишилось – 102 рядки.
Другим кроком є виявлення і видалення дублікатів. Тепер ми переходимо до роботи з назвами вулиць. Дублікати можна виявити, відсортувавши за унікальним значенням, наприклад, цю операцію можна виконати, натиснувши трикутник ліворуч від "Wohnung Str.", вибрати опцію "Sort…" ("Сортувати…") і пізніше вибрати маркер "Text" ("За текстовими значеннями"). У цьому випадку сортування може відбуватися в алфавітному порядку від A до Z або навпаки. Тепер рядки з ідентичними назвами вулиць розміщені поруч один з одним. У OpenRefine сортування є лише візуальною підмогою, тому таке впорядкування потрібно зробити постійним вручну. Для цього натисніть меню "Sort" ("Сортувати"), яке щойно з'явилося вгорі, і виберіть опцію "Reorder rows permanently" ("Впорядкувати рядки назавжди"). Якщо ви забудете це зробити, то отримаєте непередбачувані результати в подальших кроках цього уроку.
Далі зробіть так, щоб у стовпці "Wohnung Str." залишились тільки унікальні дані – назви вулиць. Для цього потрібно позбавитись від рядків, у яких повторюються назви вулиць, позначивши їх як дублікати. Для цього натисніть на трикутник біля "Wohnung Str.", виберіть "Edit cells" ("Редагувати клітинки"), а після цього "Blank down" ("Спорожнити").
У повідомленні про стан ви побачите, що було змінено 70 комірок (якщо ви забули остаточно впорядкувати рядки, ви побачите лише 24; у такому разі, скасуйте операцію "Blank down" ("Спорожнити") на вкладці "Undo/Redo" ("Скасувати/повторити") і поверніться до попереднього пункту, щоб переконатися, що рядки було відсортовано постійно). Вкладка "Undo/Redo" ("Скасувати/повторити") зліва від таблиці, над полем, де відображалися результати фасетування.
Вилучіть ці рядки, створивши фасет "Blank cells" ("Пусті комірки") у стовпчику "Wohnung Str." ("Facet" > "Customized facets" > "Facet by blank"). Виокреміть 70 порожніх рядків, натиснувши на значення "True" ("Правдиве"), і вилучивши їх за допомогою операцій в трикутнику "All" ("Edit rows" > "Remove matching rows"). Після закриття фасета ви побачите 32 рядки з унікальними назвами вулиць.
Пам'ятайте, що при видаленні дублікатів потрібно бути особливо обережним. Цей урок побудований на спеціально підготовлених даних і зосереджується лише на колонці "Wohnung Str.", але у реальній ситуації варто перевіряти вручну, чи весь рядок є дублікатом, чи ні.
Після того, як ми видалили дублікати записів, ми можемо уважніше розглянути поле "Historischer Straßenname" ("Історичні назви вулиці"). Історичні назви кожної з вулиць містяться в одному полі, розділені символом "|". Наприклад, запис про вулицю "Czerechowa" містить дві її інші назви: "Orląt" і "Cheremkhova". Це назви, які носила вулиця до, перед та після нацистської окупації міста (того періоду, коли було створено реєстраційні картки). Щоб детально проаналізувати використання інших назв, значення поля "Historischer Straßenname" потрібно розбити на окремі комірки на основі символу вертикальної риски, розкривши 34 записи у 100 рядках. Виберіть "Edit cells" ("Редагувати клітинки"), "Split multi-valued cells" ("Розділити багатозначні комірки"), ввівши '|' як роздільник значень (separator). OpenRefine повідомить вам, що тепер у вас є 100 рядків.
Важливо зрозуміти принцип роботи з рядками/записами. Ви можете перемикати режими рядків і записів, натискаючи на відповідні опції над заголовками стовпців. У режимі "Rows" ("Рядки") ми можемо маніпулювати кожним з елементів запису окремо. У режимі "Records" ("Записи") під кожним номером міститься запис, який може мати різні значення в різних рядках (згруповані разом сірим або білим кольором), але ними можна маніпулювати лише як єдиним цілим.
Отже, зараз існує 100 значень (рядків), розподілених по 34 записах.
Після того, як вміст поля належним чином розподілено, можна застосувати фільтри, фасети і кластери, щоб отримати швидкий і зрозумілий огляд класичних завдань, які можна виконати з назвами вулиць. Застосувавши спеціальний фасет "Facet by null" ("Фасетування за порожніми значеннями") для поля "Historischer Straßenname", можна одразу виявити 10 записів, які не мають виписаних історичних назв вулиць (натиснувши опцію "True"). Пам’ятаємо, що дані в OpenRefine також можна редагувати вручну, відповідно, можна редагувати та дописувати інформацію з інших джерел.
Застосування текстового фасета до полів "Wohnung Str." та "Historischer Straßenname" дозволяє переглянути 63 різні назви вулиць, що використовуються в колекції (при роботі зі значно більшим масивом даних можна змінювати ліміт кількості варіантів; за замовчуванням їхня кількість становить 2000, ви можете натиснути кнопку "Set choice count limit" ("Встановити ліміт кількості варіантів"), щоб збільшити її до 5000). Заголовки можна сортувати за алфавітом або за частотою повторюваності ("Count").
Під час перегляду можна побачити, що дані у таблиці потребують упорядкування та уніфікації, наприклад, назви сучасної вулиці Липинського (Lypynskoho). Цю проблему зможе вирішити кластеризація, яка дозволяє розв'язувати завдання, пов'язані з невідповідністю назв, непослідовним використанням форми однини або множини, а також простими орфографічними помилками.
Після застосування текстового фасета, OpenRefine пропонує кластеризувати різні варіанти написання на основі різних методів подібності. Програма представляє пов'язані значення і пропонує об'єднати їх у найбільш повторювані. Для цього, щоб перейти до процесу кластеризації, натисніть на кнопку "Cluster" ("Кластеризувати"), яку знайдете у діалогових вікнах/полях, які з’явились після процесу фасетування зліва, де відображаються назви вулиць. У цьому уроці застосовано кластеризацію значень для колонки "Wohnung Str".
У діалоговому вікні, яке з’явилося, оберіть значення, які ви хочете згрупувати, вибравши їхні поля окремо або натиснувши "Select all" ("Виділити все") внизу, а потім натисніть "Merge Selected and Re-Cluster" ("Об'єднати вибране і повторно згрупувати").
Класичний метод кластеризації не надто ускладнений, тому він ще не знаходить усіх можливих кластерів. Поекспериментуйте з різними методами, щоб побачити, які результати вони дають. Проте будьте обережні: деякі методи занадто агресивні, тому ви можете об'єднати в кластери значення, які не належать один до одного. Експериментуючи з методами можна також перевіряти значення, які вам пропонує програма, відкривши їх у нових вкладках за допомогою опції "Browse this cluster" ("Переглянути цей кластер") (див. Зображення 19). Певні зміни можна також вносити вручну (див. Зображення 20).
Тепер, коли значення були згруповані окремо, ми можемо знову об'єднати їх в одну комірку. Натисніть на трикутник біля "Historischer Straßenname" і виберіть "Edit cells" ("Редагувати клітинки") > "Join multi-valued cells" ("Об'єднати багатозначні клітинки") > "ОК". Виберіть символ вертикальної риски (|) як роздільник. Тепер рядки виглядатимуть як раніше, з багатьма значеннями для історичних назв вулиць.
Мабуть, ви пам'ятаєте, що кількість записів збільшилася після розбиття на частини: два записи з'явилися нізвідки. Щоб з'ясувати причину такої різниці, нам потрібно повернутися до того моменту, як ми розділили категорії на окремі рядки. Для цього перемкніть вкладку "Undo/Redo" ("Скасувати/Повторити") праворуч від вкладки "Facet/Filter" ("Фасет/Фільтр"), і ви отримаєте історію всіх дій, виконаних з моменту створення проєкту. Виберіть крок безпосередньо перед "Split multi-valued cells in column Historischer Straßenname" ("Розділити багатозначні клітинки в стовпці Історичні назви вулиць") (якщо ви все робили за нашим прикладом, це має бути "Remove 70 rows" ("Видалити 70 рядків"), а потім поверніться на вкладку "Facet/Filter".
Проблема виникла під час операції розділення з застосуванням символу вертикальної риски, тому є велика ймовірність, що все, що вийшло не так, пов'язано саме з цим символом. Застосуймо фільтр до стовпця "Historischer Straßenname", вибравши в меню "Text filter" ("Текстовий фільтр"). Спочатку введіть один символ | у полі ліворуч. OpenRefine повідомить вам, що є 21 відповідний запис (тобто записи, що містять вертикальну риску) із загальної кількості 32. Комірки, які не містять вертикальної риски, можуть бути порожніми, але також можуть містити одну назву без роздільника, як, наприклад, запис 12, який містить лише одну історичну назву вулиці – "Majowa".
Тепер введіть другий символ | після першого, щоб отримати || (подвійну вертикальну риску): ви можете бачити, що 2 записи відповідають цьому типу запиту. Ймовірно, саме ці 2 записи зумовили розбіжність: коли OpenRefine розділяє їх, подвійна вертикальна риска інтерпретується як розрив між двома записами, а не як непотрібний подвійний роздільник. Як нам тепер виправити ці показники? Перейдіть до меню поля "Historischer Straßenname", і виберіть "Edit cells" ("Редагувати клітинки") > "Transform" ("Трансформувати").... Ласкаво просимо до інтерфейсу перетворення тексту, потужного функціоналу OpenRefine, що використовує команди розроблені на OpenRefine Expression Language (GREL).
У цьому прикладі ми хочемо замінити подвійні вертикальні риски на одинарні. Цього можна досягти, ввівши такий GREL вираз (не забудьте про лапки):
Під текстовим полем "Expression" ("Вираз") ви побачите попередній перегляд змінених значень з видаленими подвійними вертикальними рисками. Натисніть "OK", вимкніть фасет і спробуйте ще раз розділити категорії за допомогою "Edit cells" ("Редагувати клітинки") > "Split multi-valued cells" ("Розділити багатозначні клітинки"), тепер кількість записів залишиться така як і раніше – 32 записи (натисніть на кнопку "records", щоб перевірити це ще раз).
***
Ще одне завдання, з яким можна справитись за допомогою GREL команд – це ситуація з записами, для яких одна і та ж назва вказана двічі.
До прикладу, візьмемо запис 31, для нього є такі історичні назви вулиці:
"Wierzbowa|Gundulicza|Eisenbründlweg|Michurina|Karmanskoho|Michurina".
Назва "Michurina" з'являється другий раз непотрібно, тому ми хочемо видалити цей дублікат. Клацніть трикутник "Historischer Straßenname" і натисніть "Edit cells" ("Редагувати клітинки"), "Join multi-valued cells" ("Об'єднати багатозначні клітинки"), "OK". Виберіть символ вертикальних рисок як роздільник. Тепер категорії відображаються, як і раніше.
Потім, у цьому ж стовпці, виберіть "Edit cells" ("Редагувати клітинки") та після цього "Transform" ("Трансформувати"). За допомогою GREL команд ми можемо поступово розділяти категорії на символі вертикальної риски, шукати унікальні категорії і знову їх об'єднувати. Для цього просто введіть наступний вираз:
value.split("|").uniques().join("|")
Ви помітите, що було змінено 2 комірки, де були дублікати "Michurina" та "Zamarstynivska".
Якщо ви запам'ятаєте лише одну річ з цього уроку, то вона має бути такою: не буває цілковито чистих даних, але це можна виправити. Як ми тут показали, ви можете самостійно значно покращити їх якість. Перш за все, ви можете швидко виявити, скільки порожніх значень містить ваш набір даних і як часто певне значення (наприклад, назва вулиці) використовується. Цей урок також продемонстрував, як за допомогою OpenRefine в автоматизованому режимі розв'язувати такі проблеми, як дублікати та орфографічні помилки. Заохочуємо вас експериментувати з функціями чищення на копії вашого власного набору даних, адже OpenRefine дозволяє відстежити ваші кроки у випадку, якщо ви припустилися помилки.
Сет ван Холанд, професор кафедри Інформаційно-комунікаційних наук Брюссельського вільного університету. Рубен Ферборх, постдок дослідник Мультимедійної лабораторії Гентського університету. Макс де Вільде, аспірант кафедри Інформаційно-комунікаційних наук Брюссельського вільного університету.
Рекомендоване цитування: ван Холанд, Сет; де Вільде, Макс та Ферборх, Рубен. "Очищення даних з OpenRefine." Programming Historian (2013), переклала Ліана Бліхарська, Посібник з цифрової історії, 2025.
Із початком нацистської окупації у 1941 році, у північній частині Львова було створене ґетто, куди було переселено третину мешканців міста. Воно функціонувало до кінця червня 1943 року. Частина документів, створених нацистами щодо ґетто, збереглась у львівських державних архівах. У 1995 році команда Меморіального музею Голокосту () оцифрувала ці документи, включаючи корпус реєстраційних карток майже 18 000 його мешканців. Кожна з них містила детальну інформацію про особу: ім’я та прізвище, дату народження, місце проживання, професію, місце роботи та спеціальні відмітки. Ідентифікація та нанесення на мапу приблизних місць проживання частини мешканців, а також меж ґетто та порівняння їх розташування на історичних та сучасних мапах чи аерофотозйомці Янівського табору () стали можливими завдяки співпраці між істориком та у Львові. Ці джерела сприяють глибшому дослідженню історії Львова періоду нацистської окупації, зокрема, повсякденного життя мешканців львівського ґетто, примусової праці та депортації, виживання та поведінкових стратегій, трансформацій міського простору та топографії. Окрім цього, вони дозволяють розширити діяльність у сферах комеморації, туризму та освіти.
Завантажте і дотримуйтесь інструкцій зі встановлення. OpenRefine працює на різних операційних системах: Windows, Mac та Linux. Після запуску програми з’явиться термінал і у вашому браузері відкриється нова вкладка з інтерфейсом OpenRefine. Попри використання веб-браузера, важливо розуміти, що програма працює локально на вашому пристрої і ваші дані не зберігатимуться в Інтернеті. Файл з даними для цього уроку доступний . Будь ласка, завантажте його перед початком роботи.
Слово "Value" ("Значення") у текстовому полі представляє поточне значення кожної комірки, яке ви можете побачити нижче. Ми можемо змінити це значення за допомогою заданих методів (див. повний список у ).
Із моменту першого завантаження даних до OpenRefine, всі операції з очищення виконувалися в пам'яті програми, а ваш початковий набір даних залишався недоторканим. Якщо ви хочете зберегти очищені дані, вам потрібно експортувати їх, натиснувши на меню "Export" ("Експортувати") у верхньому правому куті екрана. OpenRefine підтримує велику кількість форматів, таких як , HTML або Excel: виберіть той, який вам найбільше підходить, або додайте власний шаблон експорту, натиснувши "Templating" ("Створення шаблону"). Ви також можете експортувати свій проєкт у внутрішньому форматі OpenRefine, щоб поділитися ним з іншими.
Переклад українською: Ліана Бліхарська, аспірантка кафедри історії Українського Католицького Університету, .
Переклад рецензували: Тарас Назарук, керівник напрямку цифрової історії Центру міської історії, аспірант Університету Гаґена, . Антон Кістол, науковий співробітник, Дніпропетровський національний історичний музей ім. Д. І. Яворницького.