Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Большие данные и машинное обучение (v2) - лекци...

Anton
January 11, 2025

Большие данные и машинное обучение (v2) - лекция-5: категории и тексты

Лекция курса "Большие данные и машинное обучение" (v2.0-МОТ)
Лекция-5: категории и тексты

- Категориальные признаки: порядковые и номинальные
- Варианты кодирования: Pandas:Series.map
- Варианты кодирования: sklearn:LabelEncoder
- Варианты кодирования: дамми-кодирование, Pandas:get_dummies
- Варианты кодирования: sklearn:OneHotEncoder
- Варианты кодирования: Pandas:DataFrame.pivot_table
- ЕЯ — естественные языки (NLP — Natural language processing)
- Текстовые признаки
- Мешок слов
- Извлечение мешка слов из текстового признака: sklearn:CountVectorizer
- Превращение текстового признака в набор категориальных
- Пример: работа с категориями в датасете ILO (МОТ - Международная организация труда) ilostat.ilo.org
- Таблица данных vs таблица объектов
- Превращение таблицы сырых данных в таблицу объектов группировкой по категориям с преобразованием численных признаков: Pandas:DataFrame.groupby

Anton

January 11, 2025
Tweet

More Decks by Anton

Other Decks in Education

Transcript

  1. С использованием материалов • Введение в машинное обучение, ВШЭ, Курсера

    • Python и машинное обучение, Себастьян Рашка • Документация • StackOverflow, интернет
  2. Здесь и дальше договоримся обозначать • X - выборка (таблица)

    из n элементов (n строк), у каждого элемента m признаков (m столбцов) • x — произвольный элемент (<=> объект, строка) выборки, • x j — j-й признак элемента x • x(i) (верхний индекс в круглых скобках) — i-й элемент выборки x=(x 1 ,..., x m ) x(i)=(x 1 (i) ,..., x m (i))
  3. Здесь и дальше договоримся обозначать X= (x(1) ... x(n) )=

    (x 1 (1) ,..., x m (1) ... x 1 (n) ,..., x m (n) ) x(i)=(x 1 (i) ,..., x m (i)) x=(x 1 ,..., x m ) или
  4. Категориальные признаки • Нечисловые (текст или отдельные символы) признаки, монолитные

    значения из словаря • Порядковые: можно сравнивать между собой: размер одежды (S, M, L, XL), диапазон возрастов (ребенок, юноша, взрослый, старик) и т.п. • Номинальные: нельзя сравнивать между собой: теги, города, цвета и т. п. • Можем по ним фильтровать и искать • Но обычно мы хотим иметь дело с числами • Задача: превратить текстовые категории в числа
  5. Может просто назначить каждой категории отдельное число? • Для порядковых

    признаков решение норм: назначить числовые значения так, чтобы сохранить порядок сравнения оригинальных категорий ([S → 0] < [M → 1] < [L → 2] < [XL → 3]) • Для номинальных признаков: номинальные категории сравнивать нельзя, а числа сравнивать можно - Просто пронумеровав номинальные категории, мы внесем в данные информацию, которой там не было - Но если очень хочется, то почему бы и нет
  6. categories-basic.py import pandas as pd import numpy as np data

    = pd.DataFrame([ [ 'Александр', 'Нижний Новгород', True ], [ 'Сергей', 'Самара', True ], [ 'Лев', 'Самара', True ], [ 'Николай', 'Архангельск', False ], [ 'Петр', 'Нижний Новгород', False ], [ 'Илья', 'Архангельск', False ] ], columns=['имя', 'город', 'плоскостопие']) print( data )
  7. имя город плоскостопие 0 Александр Нижний Новгород True 1 Сергей

    Самара True 2 Лев Самара True 3 Николай Архангельск False 4 Петр Нижний Новгород False 5 Илья Архангельск False
  8. city_mapping = { 'Нижний Новгород': 152, 'Самара': 163, 'Архангельск': 29

    } #data['город'] = data.город.map(city_mapping) data['код_города'] = data['город'].map(city_mapping) data['код_города'] = data.город.map(city_mapping) print( data ) • pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.map.html Pandas Series.map
  9. имя город плоскостопие код_города 0 Александр Нижний Новгород True 152

    1 Сергей Самара True 163 2 Лев Самара True 163 3 Николай Архангельск False 29 4 Петр Нижний Новгород False 152 5 Илья Архангельск False 29
  10. Scikit-learn (sklearn) • scikit-learn.org pypi.org/project/scikit-learn github.com/scikit-learn/scikit-learn • Реализация множества алгоритмов

    машинного обучения • Предварительная обработка данных • Предсказательные модели (классификация, регрессия, кластеризация) • В т. ч. простые нейронные сети • И т. п.
  11. Scikit-learn (sklearn) • pip install scikit-learn python -m pip install

    scikit-learn • но НЕ так (пакет с таким именем есть, но не поддерживается): pip install sklearn • На моём python 3.9 проблемы с OneHotEncoder из примеров дальше, на 3.8 ок, поэтому: python3.8 -m pip install scikit-learn
  12. from sklearn.preprocessing import LabelEncoder lenc = LabelEncoder() print( lenc.fit_transform(data['город'].values) )

    • scikit-learn.org/stable/modules/generated/sklearn.preprocessing.LabelEncoder.html sklearn.preprocessing.LabelEncoder [1 2 2 0 1 0]
  13. data['город_enc'] = lenc.fit_transform(data['город'].values) print(data) sklearn.preprocessing.LabelEncoder имя город плоскостопие код_города город_enc

    0 Александр Нижний Новгород True 152 1 1 Сергей Самара True 163 2 2 Лев Самара True 163 2 3 Николай Архангельск False 29 0 4 Петр Нижний Новгород False 152 1 5 Илья Архангельск False 29 0
  14. data['город_enc_inv'] = lenc.inverse_transform(data['город_enc'].values) print(data) Исходная метка по коду имя город

    ... город_enc город_enc_inv 0 Александр Нижний Новгород ... 1 Нижний Новгород 1 Сергей Самара ... 2 Самара 2 Лев Самара ... 2 Самара 3 Николай Архангельск ... 0 Архангельск 4 Петр Нижний Новгород ... 1 Нижний Новгород 5 Илья Архангельск ... 0 Архангельск
  15. Дамми-кодирование номинальных категорий • (dummy — наивный, глупый) • Признак

    x j принимает значения из множества W={w 1 , ..., w l } — все категории: теги, города, цвета и т.п. • Создадим l [эль] (столько же, сколько всего категорий) новых бинарных фиктивных признаков-индикаторов u 1 , …, u l : • k-й индикатор u k показывает, равен ли категориальный признак x j на данном объекте значению k-й категории w k u k (i)= {1, x j (i)=w k 0, x j (i)≠w k ,k=1,...,l
  16. Пример: графа «город проживания» в анкете • W = {Нижний

    Новгород, Самара, Архангельск} • Кодируем тремя бинарными признаками (u 1 , u 2 , u 3 ): Нижний Новгород → (1, 0, 0) Самара → (0, 1, 0) Архангельск → (0, 0, 1)
  17. Имя Город Плоскостопие u 1 u 2 u 3 Александр

    Нижний Новгород да 1 0 0 Сергей Самара да 0 1 0 Лев Самара да 0 1 0 Николай Архангельск нет 0 0 1 Петр Нижний Новгород нет 1 0 0 Илья Архангельск нет 0 0 1 u 1 = город_Нижний_Новгород u 2 = город_Самара u 3 = город_Архангельск
  18. • Получили вместо одного категориального признака (1 колонка в таблице)

    3 бинарных признака (3 колонки в таблице) • Из всех новых признаков только один может принимать ненулевое значение для одного объекта (одна единица на строку)
  19. print( pd.get_dummies(data['город']) ) Архангельск Нижний Новгород Самара 0 0 1

    0 1 0 0 1 2 0 0 1 3 1 0 0 4 0 1 0 5 1 0 0 • pandas.pydata.org/pandas-docs/stable/reference/api/pandas.get_dummies.html pandas.get_dummies
  20. print( pd.get_dummies(data, columns=['город']) ) имя плоскостопие город_Архангельск город_Нижний Новгород город_Самара

    0 Александр True 0 1 0 1 Сергей True 0 0 1 2 Лев True 0 0 1 3 Николай False 1 0 0 4 Петр False 0 1 0 5 Илья False 1 0 0 pandas.get_dummies
  21. from sklearn.preprocessing import OneHotEncoder ohenc = OneHotEncoder() # все колонки

    print( ohenc.fit_transform(data).toarray() ) print( ohenc.get_feature_names() ) • scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html sklearn.preprocessing.OneHotEncoder
  22. [[1. 0. 0. 0. 0. 0. 0. 1. 0. 0.

    1.] [0. 0. 0. 0. 0. 1. 0. 0. 1. 0. 1.] [0. 0. 1. 0. 0. 0. 0. 0. 1. 0. 1.] [0. 0. 0. 1. 0. 0. 1. 0. 0. 1. 0.] [0. 0. 0. 0. 1. 0. 0. 1. 0. 1. 0.] [0. 1. 0. 0. 0. 0. 1. 0. 0. 1. 0.]] ['x0_Александр' 'x0_Илья' 'x0_Лев' 'x0_Николай' 'x0_Петр' 'x0_Сергей' 'x1_Архангельск' 'x1_Нижний Новгород' 'x1_Самара' 'x2_False' 'x2_True']
  23. # выбранная колонка - таблица из одной колонки print( ohenc.fit_transform(data[['город']]).toarray()

    ) print( ohenc.fit_transform(data['город'].to_frame()).toarray() ) #ohenc.fit_transform( data['город'].values.reshape(-1, 1) ) print( ohenc.get_feature_names() ) sklearn.preprocessing.OneHotEncoder • На входе fit_transform 2д-массив (таблица), а не 1-д массив (колонка) • Одинарные квадраные скобки — взять отдельную колонку, двойные квадратные скобки — взять несколько колонок из таблицы (здесь – таблица из одной колонки) или • pandas.pydata.org/pandas-docs/stable/reference/api/pandas.Series.to_frame.html или • Numpy.reshape
  24. [[0. 1. 0.] [0. 0. 1.] [0. 0. 1.] [1.

    0. 0.] [0. 1. 0.] [1. 0. 0.]] ['x0_Архангельск' 'x0_Нижний Новгород' 'x0_Самара']
  25. # сначала fit, потом transform print( data[['город']] ) ohenc.fit( data[['город']]

    ) print( ohenc.transform(data[['город']]).toarray() ) print( ohenc.get_feature_names() ) • scikit-learn.org/stable/modules/generated/sklearn.preprocessing.OneHotEncoder.html sklearn.preprocessing.OneHotEncoder
  26. город 0 Нижний Новгород 1 Самара 2 Самара 3 Архангельск

    4 Нижний Новгород 5 Архангельск [[0. 1. 0.] [0. 0. 1.] [0. 0. 1.] [1. 0. 0.] [0. 1. 0.] [1. 0. 0.]] ['x0_Архангельск' 'x0_Нижний Новгород' 'x0_Самара']
  27. # указать категории вручную ohenc.fit( [['Нижний Новгород'], ['Самара'], ['Архангельск']] )

    print( ohenc.transform(data[['город']]).toarray() ) print( ohenc.get_feature_names() ) sklearn.preprocessing.OneHotEncoder • важно: это не список категорий, а 2-д таблица с одной колонкой (поэтому каждый элемент в отдельных квадратных скобках) • По этой же причине порядок не имеет значения — он их всё равно пересортирует
  28. [[0. 1. 0.] [0. 0. 1.] [0. 0. 1.] [1.

    0. 0.] [0. 1. 0.] [1. 0. 0.]] ['x0_Архангельск' 'x0_Нижний Новгород' 'x0_Самара']
  29. # категории, которых нет в исходном датасете, # но могут

    появиться в дополненных таблицах ohenc.fit( [['Нижний Новгород'], ['Самара'], ['Архангельск'], ['Воронеж']] ) print( ohenc.transform(data[['город']]).toarray() ) print( ohenc.get_feature_names() ) sklearn.preprocessing.OneHotEncoder
  30. [[0. 0. 1. 0.] [0. 0. 0. 1.] [0. 0.

    0. 1.] [1. 0. 0. 0.] [0. 0. 1. 0.] [1. 0. 0. 0.]] ['x0_Архангельск' 'x0_Воронеж' 'x0_Нижний Новгород' 'x0_Самара']
  31. # если не конвертировать в массив с toarray # (разреженная

    матрица - экономия памяти) print( ohenc.transform(data[['город']]) ) sklearn.preprocessing.OneHotEncoder (0, 2) 1.0 (1, 3) 1.0 (2, 3) 1.0 (3, 0) 1.0 (4, 2) 1.0 (5, 0) 1.0 [[0. 0. 1. 0.] [0. 0. 0. 1.] [0. 0. 0. 1.] [1. 0. 0. 0.] [0. 0. 1. 0.] [1. 0. 0. 0.]]
  32. # склеить в таблицу DataFrame # (память на нулях больше

    не экономим) print( pd.DataFrame( ohenc.transform(data[['город']]).toarray(), columns=ohenc.get_feature_names()) ) sklearn.preprocessing.OneHotEncoder x0_Архангельск x0_Воронеж x0_Нижний Новгород x0_Самара 0 0.0 0.0 1.0 0.0 1 0.0 0.0 0.0 1.0 2 0.0 0.0 0.0 1.0 3 1.0 0.0 0.0 0.0 4 0.0 0.0 1.0 0.0 5 1.0 0.0 0.0 0.0
  33. # подклеить новую таблицу к старой исходной таблице data_oh =

    pd.DataFrame( ohenc.transform(data[['город']]).toarray(), columns=ohenc.get_feature_names()) print( pd.concat([data, data_oh], axis=1) ) sklearn.preprocessing.OneHotEncoder имя город плоскостопие x0_Архангельск x0_Воронеж x0_Нижний Новгород x0_Самара 0 Александр Нижний Новгород True 0.0 0.0 1.0 0.0 1 Сергей Самара True 0.0 0.0 0.0 1.0 2 Лев Самара True 0.0 0.0 0.0 1.0 3 Николай Архангельск False 1.0 0.0 0.0 0.0 4 Петр Нижний Новгород False 0.0 0.0 1.0 0.0 5 Илья Архангельск False 1.0 0.0 0.0 0.0 • pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html
  34. print( data.pivot_table( index=data.index, columns='город', values='город', aggfunc='count') ) DataFrame.pivot_table Traceback (most

    recent call last): File "categories-basic.py", line 23, in <module> print( data.pivot_table(index=data.index, columns='город', values='город', aggfunc='count', fill_value=0) ) [...] Grouping( File "/home/benderamp/.local/lib/python3.8/site-packages/pandas/core/groupby/grouper.py", line 543, in __init__ raise ValueError(f"Grouper for '{t}' not 1-dimensional") ValueError: Grouper for 'город' not 1-dimensional
  35. data['город_1'] = data['город'] print( data.pivot_table( index=data.index, columns='город', values='город_1', aggfunc='count') )

    DataFrame.pivot_table город Архангельск Нижний Новгород Самара 0 NaN 1.0 NaN 1 NaN NaN 1.0 2 NaN NaN 1.0 3 1.0 NaN NaN 4 NaN 1.0 NaN 5 1.0 NaN NaN
  36. data['город_1'] = data['город'] print( data.pivot_table( index=data.index, columns='город', values='город_1', aggfunc='count', fill_value=0)

    ) DataFrame.pivot_table город Архангельск Нижний Новгород Самара 0 0 1 0 1 0 0 1 2 0 0 1 3 1 0 0 4 0 1 0 5 1 0 0
  37. • Параметр values обычно должен содержать числовые значения (массив чисел),

    которые пойдут на вход агрегирующей функции aggfunc • Но если мы берем функцию aggfunc «count», то не важно, какого типа данные находятся в этом столбце — он просто считает количество элементов • Необходимость вводить фиктивную колонку «город_1» — какой-то глюк или особенность внутренней реализации алгоритма
  38. data['город_1'] = data['город'] data_pivot_dummy = data.pivot_table( index=data.index, columns='город', values='город_1', aggfunc='count',

    fill_value=0) data.drop(columns=['город_1']) print( pd.concat( [data, data_pivot_dummy.add_prefix('г_')], axis=1) ) DataFrame.pivot_table имя город плоскостопие город_1 г_Архангельск г_Нижний Новгород г_Самара 0 Александр Нижний Новгород True Нижний Новгород 0 1 0 1 Сергей Самара True Самара 0 0 1 2 Лев Самара True Самара 0 0 1 3 Николай Архангельск False Архангельск 1 0 0 4 Петр Нижний Новгород False Нижний Новгород 0 1 0 5 Илья Архангельск False Архангельск 1 0 0 • pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html • pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.add_prefix.html
  39. Возможные проблемы • Уникальные (или редкие) категории: алгоритм не выявит

    зависимостей (решение: объединить редкие категории в одну) • Большое количество возможных значений категории (провести замену как-то по- другому)
  40. Текстовые признаки • x j — текстовый признак: • Значение

    признака x j — последовательность слов (w 1 , w 2 , …, w p ) • В отличие от категорий, мы не рассматриваем признак целиком как есть (монолит), а разбиваем его на составляющие и работаем с ними
  41. Мешок слов • Выводы о тексте можно сделать, даже если

    слова перемешаны (частое употребление спец-терминов, эпоха, стиль, привычки автора и т.п.) • Все слова из всех текстов принадлежат словарю W = {w 1 , …, w l } • Создадим l [эль] новых фиктивных признаков-индикаторов u 1 , …, u l : • n(w k , x j ) — число вхождений слова w k в текст x j • k-й признак u k показывает, сколько раз k-е слово w k встречается в тексте x j • (похоже на дамми-кодирование, только вместо двоичных признаков числовые, ненулевых значений столько, сколько слов в тексте) u k ( j)=n(w k , x j (i)),k=1,...,l
  42. Пример • W = {игрушки, книжки, спят, усталые} (спят усталые

    игрушки, книжки спят) → (1, 1, 2, 1) (усталые игрушки усталые) → (1, 0, 0, 2) (книжки спят) → (0, 1, 1, 0)
  43. from sklearn.feature_extraction.text import CountVectorizer count_vect = CountVectorizer() data_txt = pd.DataFrame([

    ['спят усталые игрушки, книжки спят'], ['усталые игрушки усталые'], ['книжки спят'] ], columns=['текст']) sklearn.feature_extraction.text. CountVectorizer • scikit-learn.org/stable/modules/generated/sklearn.feature_extraction.text.CountVectorizer.html • scikit-learn.org/stable/modules/feature_extraction.html#text-feature-extraction
  44. bag = count_vect.fit_transform(data_txt['текст']) print( data_txt ) print( count_vect.get_feature_names() ) print(

    bag.toarray() ) текст 0 спят усталые игрушки, книжки спят 1 усталые игрушки усталые 2 книжки спят ['игрушки', 'книжки', 'спят', 'усталые'] [[1 1 2 1] [1 0 0 2] [0 1 1 0]]
  45. bag = count_vect.fit_transform(data_txt['текст']) print( data_txt ) print( count_vect.get_feature_names() ) print(

    bag.toarray() ) текст 0 спят усталые игрушки, книжки спят 1 усталые игрушки усталые 2 книжки спят ['игрушки', 'книжки', 'спят', 'усталые'] [[1 1 2 1] [1 0 0 2] [0 1 1 0]]
  46. print( pd.concat([data_txt, data_vect.add_prefix('w_')], axis=1) ) текст w_игрушки w_книжки w_спят w_усталые

    0 спят усталые игрушки, книжки спят 1 1 2 1 1 усталые игрушки усталые 1 0 0 2 2 книжки спят 0 1 1 0 • pandas.pydata.org/pandas-docs/stable/reference/api/pandas.concat.html • pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.add_prefix.html Склеить с исходной таблицей
  47. Замечание • Функции Sklearn работают с массивами numpy: принимают на

    входе, генерируют на выходе • Таблицы Pandas ей не нужны • Но с Pandas тоже интегрируется легко, т. к. pandas.DataFrame — это 2д массив numpy, а pandas.Series — это 1д массив numpy • Мы для удобства представления конвертировали результат обратно в таблицы pandas.DataFrame • Но во многих практических случаях это делать не обязательно, т. к. алгоритмы машинного обучения принимают на входе массивы numpy
  48. • Можно использовать счетчик для поиска наиболее важных слов для

    текстов • Или выбора характерных слов для корпуса текстов: определить тематику текста, эмоциональный окрас, определить автора и т. п. • Минус: общеупотребительная лексика → топ • Как решить — отдельная история Итого по мешку слов
  49. Ilostat.ilo.org > Labour migrants • Selected groups > Labour migrants

    ilostat.ilo.org/topics/labour-migration/ • Data > Inflow of foreign-born working-age population by sex and country of birth (in thousands) | Annual www.ilo.org/ilostat-files/WEB_bulk_download/indicator/ MFL_FPOP_SEX_CBR_NB_A.csv.gz • Расшифровки кодов: www.ilo.org/ilostat-files/WEB_bulk_download/html/bulk_dic.html
  50. Файл MFL_FPOP_SEX_CBR_NB_A.csv • Inflow of foreign-born working-age population by sex

    and country of birth (in thousands) | Annual • Database: International labour migration statistics (ILMS) • Last update: 16/11/2020 10:40:25
  51. Видим колонки • ref_area — код территории (страны) • indicator

    — MFL_FPOP_SEX_CBR_NB • source — код источника данных • sex — пол • classif1 — страна происхождения трудовых мигрантов • time — год • obs_value — количество мигрантов в указанной стране из указанной страны в указанный год (тыс. человек) • obs_status — ? • note_indicator, note_source — заметки
  52. print( data.ref_area.value_counts() ) посмотрим ref_area CHE 207 CHL 168 FRA

    165 HUN 162 PHL 126 ISR 105 MKD 99 ITA 90 LTU 81 HRV 81 ESP 81 BGR 81 KGZ 81 FJI 81 SVN 81 CRI 74 BEL 72 RUS 69 TUR 63 CIV 60 CAN 60 BOL 60 AUS 60 GIN 60 FIN 57 GBR 51 NER 48 KHM 34 UZB 30 GTM 21 ARM 21 KAZ 21 NOR 21 ROU 21 KWT 19 DEU 18 NAM 18 LVA 12 OMN 8 ARE 6 SAU 3 CPV 3 LKA 1 Name: ref_area, dtype: int64
  53. print( data.classif1.value_counts() ) и посмотрим classif1 CBR_BRT_TOTAL 354 CBR_BRT_X 282

    CBR_BRT_DEU 92 CBR_BRT_UKR 83 CBR_BRT_ITA 79 ... CBR_BRT_BRN 1 CBR_BRT_HKG 1 CBR_BRT_MMR 1 CBR_BRT_LAO 1 CBR_BRT_SGP 1 Name: classif1, Length: 132, dtype: int64
  54. bulk_dic/classif1_en.csv • "CBR_BRT_TOTAL","Country of birth: Total",576 • "CBR_BRT_AFG","Country of birth:

    Afghanistan",578 • "CBR_BRT_ALB","Country of birth: Albania",581 • "CBR_BRT_DZA","Country of birth: Algeria",582 • "CBR_BRT_AGO","Country of birth: Angola",586 • "CBR_BRT_ARG","Country of birth: Argentina",589 • "CBR_BRT_ARM","Country of birth: Armenia",591 • "CBR_BRT_AUS","Country of birth: Australia",593 [...] • "CBR_BRT_X","Country of birth: Other countries",955
  55. • До этого момента мы работали с таблицами просто как

    с множеством строк - делали всякие манипуляции, математические операции • Мы не относились к данным как к объектам • Алгоритмы машинного обучения подразумевают немного другой подход философский: - мы должны представлять таблицу как массив (набор) объектов - одна строка - один объект - колонки таблицы - признаки объекта
  56. • Технически это ничего не меняет: как были таблицы, так

    и остались, все старые операции доступны (и мы будем дальше активно использовать их) • Но это в некотором роде определяет подход к этим данным и даёт некоторое целеполагание на этапе промежуточной обработки • Мы должны определиться, что у нас является объектом, какие у него признаки • Далее, если они размазаны по разным строкам или второстепенным таблицам, мы должны свести все эти признаки в одну строку-объект • После того, как это будет сделано, нам останется один шаг до того, чтобы применить к набору данных алгоритмы классификации, экстраполяционного прогнозирования и т. п. (т. н. машинного обучения)
  57. print( data ) ref_area indicator source sex classif1 time obs_value

    obs_status note_indicator note_source 0 ARE MFL_FPOP_SEX_CBR_NB AA:858 SEX_T CBR_BRT_TOTAL 2005 147.345 NaN NaN NaN 1 ARE MFL_FPOP_SEX_CBR_NB AA:858 SEX_M CBR_BRT_TOTAL 2005 105.821 NaN NaN NaN 2 ARE MFL_FPOP_SEX_CBR_NB AA:858 SEX_F CBR_BRT_TOTAL 2005 41.524 NaN NaN NaN 3 ARE MFL_FPOP_SEX_CBR_NB EA:860 SEX_T CBR_BRT_TOTAL 2006 849.471 NaN NaN NaN 4 ARE MFL_FPOP_SEX_CBR_NB EA:860 SEX_T CBR_BRT_TOTAL 2007 1146.347 NaN NaN NaN ... ... ... ... ... ... ... ... ... ... ... 2675 UZB MFL_FPOP_SEX_CBR_NB FX:12977 SEX_M CBR_BRT_TOTAL 2016 0.803 NaN NaN NaN 2676 UZB MFL_FPOP_SEX_CBR_NB FX:12977 SEX_F CBR_BRT_TOTAL 2016 0.786 NaN NaN NaN 2677 UZB MFL_FPOP_SEX_CBR_NB FX:12977 SEX_T CBR_BRT_TOTAL 2017 1.860 NaN NaN T2:85 2678 UZB MFL_FPOP_SEX_CBR_NB FX:12977 SEX_M CBR_BRT_TOTAL 2017 0.808 NaN NaN T2:85 2679 UZB MFL_FPOP_SEX_CBR_NB FX:12977 SEX_F CBR_BRT_TOTAL 2017 1.052 NaN NaN T2:85
  58. Что здесь возьмем за объект? • Страна (key=ref_area) • Страна

    в указанный год (key=ref_area+time) • Мигранты из выбранной страны (key=classif1) • Мигранты из выбранной страны указанного пола (key=classif1+sex) • И т. п. • Остальные колонки — его свойства
  59. Пусть будет «страна в выбранный год» • Ключ = (ref_area+time)

    • Нужно все остальные значения для комбинации ref_area+time вытянуть в одну строку • Или удалить
  60. Как превратить страну рождения иммигрантов в категорию? • ref_area +

    time определяют объект, они не должны повторяться в разных строках • Для каждой комбинации «ref_area + time» в одной строке должно быть одно значение категории • Можно в качестве свойства-категории выбрать «страна рождения для наибольшего количества мигрантов» (из какой страны в выбранную страну в выбранный год больше всего ехало трудовых мигрантов)
  61. data = data[ (data.classif1 != 'CBR_BRT_TOTAL') & (data.classif1 != 'CBR_BRT_X')

    ] Убрать агрегированные строки и вариант CBR_BRT_X везде
  62. print( data ) ref_area time classif1 obs_value 7 ARM 2018

    CBR_BRT_GEO 1.875 8 ARM 2018 CBR_BRT_IRN 0.443 9 ARM 2018 CBR_BRT_SYR 0.168 10 ARM 2018 CBR_BRT_CIS 1.097 11 ARM 2018 CBR_BRT_EUR 0.102 ... ... ... ... ... 2630 TUR 2018 CBR_BRT_AFG 28.613 2631 TUR 2018 CBR_BRT_IRN 28.803 2632 TUR 2018 CBR_BRT_IRQ 70.309 2633 TUR 2018 CBR_BRT_SYR 26.497 2634 TUR 2018 CBR_BRT_TKM 33.473
  63. ref_area time classif1 obs_value 7 ARM 2018 CBR_BRT_GEO 1.875 29

    AUS 2017 CBR_BRT_CHN 83.020 95 BEL 2017 CBR_BRT_MAR 239.931 141 BEL 2018 CBR_BRT_MAR 217.114 170 BGR 2017 CBR_BRT_RUS 2.660 ... ... ... ... ... 2508 SVN 2017 CBR_BRT_BIH 6.465 2567 SVN 2018 CBR_BRT_BIH 10.775 2590 TUR 2016 CBR_BRT_IRQ 44.614 2611 TUR 2017 CBR_BRT_IRQ 59.177 2632 TUR 2018 CBR_BRT_IRQ 70.309
  64. ref_area time migrants_pop_homeland migrants_pop_inflow 7 ARM 2018 CBR_BRT_GEO 1.875 29

    AUS 2017 CBR_BRT_CHN 83.020 95 BEL 2017 CBR_BRT_MAR 239.931 141 BEL 2018 CBR_BRT_MAR 217.114 170 BGR 2017 CBR_BRT_RUS 2.660 ... ... ... ... ... 2508 SVN 2017 CBR_BRT_BIH 6.465 2567 SVN 2018 CBR_BRT_BIH 10.775 2590 TUR 2016 CBR_BRT_IRQ 44.614 2611 TUR 2017 CBR_BRT_IRQ 59.177 2632 TUR 2018 CBR_BRT_IRQ 70.309 [100 rows x 4 columns]
  65. print( data1[data1.ref_area == 'RUS'] ) ref_area time migrants_pop_homeland migrants_pop_inflow 2439

    RUS 2011 CBR_BRT_UZB 61.067 2446 RUS 2012 CBR_BRT_UZB 83.793 2453 RUS 2013 CBR_BRT_UZB 113.354 2460 RUS 2014 CBR_BRT_UZB 126.016 2466 RUS 2015 CBR_BRT_UKR 156.262 2473 RUS 2016 CBR_BRT_UKR 149.155 2492 RUS 2017 CBR_BRT_UKR 126.967 2500 RUS 2018 CBR_BRT_UKR 118.544
  66. print( data1[ data1.migrants_pop_homeland == 'CBR_BRT_RUS' ] ) ref_area time migrants_pop_homeland

    migrants_pop_inflow 170 BGR 2017 CBR_BRT_RUS 2.660 221 BGR 2018 CBR_BRT_RUS 1.950 1694 ISR 2016 CBR_BRT_RUS 6.450 1736 ISR 2018 CBR_BRT_RUS 9.144
  67. print( data1.migrants_pop_homeland.value_counts() ) CBR_BRT_UKR 12 CBR_BRT_ROU 11 CBR_BRT_DEU 8 CBR_BRT_MAR

    7 CBR_BRT_CHN 7 CBR_BRT_NIC 5 CBR_BRT_UZB 5 CBR_BRT_PER 5 CBR_BRT_VEN 4 CBR_BRT_RUS 4 CBR_BRT_BIH 4 CBR_BRT_IRQ 4 CBR_BRT_TUR 3 [...]
  68. print( data[data.classif1 == 'CBR_BRT_USA'] ) ref_area time classif1 obs_value 44

    AUS 2017 CBR_BRT_USA 11.980 177 BGR 2017 CBR_BRT_USA 0.260 258 BOL 2012 CBR_BRT_USA 3.946 318 CAN 2017 CBR_BRT_USA 7.955 504 CHE 2017 CBR_BRT_USA 3.630 829 CRI 2016 CBR_BRT_USA 0.069 844 CRI 2017 CBR_BRT_USA 0.207 859 CRI 2018 CBR_BRT_USA 0.372 987 FIN 2017 CBR_BRT_USA 0.484 1093 FJI 2018 CBR_BRT_USA 1.058 1211 FRA 2017 CBR_BRT_USA 5.864 1343 GIN 2014 CBR_BRT_USA 0.174 1390 GTM 2018 CBR_BRT_USA 0.996 1424 HRV 2017 CBR_BRT_USA 0.130 1654 ISR 2014 CBR_BRT_USA 2.619 1675 ISR 2015 CBR_BRT_USA 2.633 1696 ISR 2016 CBR_BRT_USA 2.636 1717 ISR 2017 CBR_BRT_USA 2.649 1738 ISR 2018 CBR_BRT_USA 2.558 1975 KHM 2008 CBR_BRT_USA 0.469 2039 LTU 2017 CBR_BRT_USA 0.106 2524 SVN 2017 CBR_BRT_USA 0.102
  69. print( data[data.classif1 == 'CBR_BRT_RUS'] ) ref_area time classif1 obs_value 170

    BGR 2017 CBR_BRT_RUS 2.660 221 BGR 2018 CBR_BRT_RUS 1.950 980 FIN 2017 CBR_BRT_RUS 0.768 1417 HRV 2017 CBR_BRT_RUS 0.149 1652 ISR 2014 CBR_BRT_RUS 4.491 1673 ISR 2015 CBR_BRT_RUS 6.192 1694 ISR 2016 CBR_BRT_RUS 6.450 1715 ISR 2017 CBR_BRT_RUS 6.594 1736 ISR 2018 CBR_BRT_RUS 9.144 1847 KAZ 2018 CBR_BRT_RUS 0.983 1878 KGZ 2017 CBR_BRT_RUS 0.039 1928 KGZ 2018 CBR_BRT_RUS 0.038 2004 LTU 2018 CBR_BRT_RUS 1.153 2034 LTU 2017 CBR_BRT_RUS 1.087 2126 MKD 2017 CBR_BRT_RUS 0.033 2519 SVN 2017 CBR_BRT_RUS 0.481
  70. А что если мы хотим сохранить данные по всем странам

    в виде категорий? • Придумать, как их вытянуть все в строку • Например, при помощи сводной таблицы pivot_table • Можно сделать аналог дамми-кодирования и мешка слов • Для каждой страны-происхождения по одной колонке • И в этой колонке флаг: 1 — иммигранты есть в выбранной строке в выбранный год, 0 — иммигрантов нет • Колонок будет много, да