Data handler module

Модуль направленный на подготовку данных для решения задачи отождествления.

class cosmatch.match.data_handler.OpticalNeighbours

Класс для получения позитивного (компаньонов рентгеновских источников) и негативного (не компаньонов рентгеновских источников) класса оптических объектов из тренеровочного оптического каталога. Для отбора используется вспомогательный рентгеновский каталог.

Отбор производится по следующему алгоритму:

  • Находятся пары рентген-оптика для оптических объектов обоих классов так, что дистанция в парах менее заданного порога угловых секунды.

  • Для каждого рентгеновского источника в парах вычисляется радиус, внутри которого с заданным шансом находящийся там оптический объект не будет компаньоном.

  • Оптические объекты положительного класса отбираются, как объекты в парах с дистанцией меньше вычисленного ранее радиуса. Дополнительно убираются неоднозначности.

  • Оптические объекты отрицательного класса отбираются, как объекты, для которых расстояние до любого рентгеновского соседа больше вычисленного радиуса.

static get_two_class_opt(frame, support, max_distance=15, prob=0.05)

Получение позитивной и негативной выборки frame объектов при помощи позиций target источников из вспомогательного каталога.

Parameters:
  • frame (DataFrame) – Каталог с frame объектами. Columns: id, ra, dec

  • support (DataFrame) – Каталог с target_support объектами. Columns: id, ra, dec

  • max_distance (float) – Максимальное расстояние между frame и target_support объектами.

  • prob (float) – Вероятность, что frame объект внутри радиуса будет неверным компаньоном для target источника.

Return type:

Tuple[DataFrame, DataFrame]

Returns:

  • Каталог с frame объектами - компаньонами, при том добавит координаты рентгеновского источника, которые нужны для более качественного дальнейшего отбора.

  • Каталог с frame объектами - не компаньонами.

Examples

>>> import numpy as np
>>> import pandas as pd
>>> from cosmatch.match.data_handler import OpticalNeighbours
>>> from cosmatch.fake import generate_catalog
>>>
>>> frame_size = 10000; target_size = 500
>>> frame = generate_catalog(name=None, size=frame_size, random_state=43)
>>> target_support = generate_catalog(name=None, size=target_size, random_state=44)
>>> positive, negative = OpticalNeighbours.get_two_class_opt(frame, target_support,
...                                                          max_distance=15, prob=0.05)
>>> positive.columns, negative.columns
(Index(['id', 'ra', 'dec', 'ra_support', 'dec_support'], dtype='object'),
Index(['id', 'ra', 'dec'], dtype='object'))
>>> positive.shape, negative.shape
((41, 5), (956, 3))

Объекты frame попадают только в один из наборов данных.

>>> positive['id'].isin(negative['id']).sum()
0

При увеличении prob размер позитивной выборки также увеличивается, при том в нем падает надежность - больше шанс отобрать верную пару

>>> positive, negative = OpticalNeighbours.get_two_class_opt(frame, target_support,
...                                                          max_distance=15, prob=0.10)
>>> positive.shape, negative.shape
((73, 5), (906, 3))
>>> positive, negative = OpticalNeighbours.get_two_class_opt(frame, target_support,
...                                                          max_distance=15, prob=0.20)
>>> positive.shape, negative.shape
((116, 5), (814, 3))
class cosmatch.match.data_handler.PrepareClasses

Класс для объединения отобранных в модуле OpticalNeighbours оптических компаньонов с основным рентгеновским каталогом для получения пар положительного (являются верным отождествлением) и отрицательного (не являются верным отождествлением) класса.

Для использования рекомендуется вызывать метод get_dataset() от результата метода get_pair() класса OpticalNeighbours.

На вход подается два множества - верные оптические компаньоны (оптические объекты, которые излучают в рентгене) и неверные оптические компаньоны (не изучают в рентгене).

Процесс объединения этих двух множеств с рентгеновским каталогом производится по следующему алгоритму:

  • Находятся пары рентген-оптика для оптических объектов обоих классов так, что дистанция в парах менее 30 угловых секунды.

  • Удаляются пары с верными оптическими компаньонами, расстояния между рентгеновскими источниками из основного и вспомогательного каталога менее r98.

  • Удаляются пары с верными оптическими компаньонами, в которых встречается неоднозначность соотнесения (один к многим и многие к одному).

  • Среди пар с неверными оптическими источниками остаются только те, у которых рентгеновский источник имеет верного оптического компаньона в наборе.

Полученные два класса и являются положительным и отрицательным классом.

static get_marked_data(frame, target, target_support, max_distance=15, probability=0.05)

Возвращает всевозможные пары объектов рентген-оптика в радиусе , где для каждой пары указана метка класса - верная пара(1) и неверная пара(0).

Return type:

DataFrame

static get_two_class_pair(target, frame_positive, frame_negative, max_distance=15)

Объединение каталогов оптических объектов с основным каталогом рентгеновских источников.

Parameters:
  • opt_positive – Каталог с парами рентген(основной)-оптика(вспомогательный) из положительного класса. Каталог должен содержать позиции рентгеновских источников из вспомогатьельного каталога, которые являются компаньонами оптических объектов.

  • opt_negative – Каталог с парами рентген(основной)-оптика(вспомогательный) из положительного класса.

  • max_distance (float) – Максимальная дистанция которая может быть между парами.

Return type:

DataFrame

Returns:

Каталог пар рентген-оптика, с меткой класса (класс 1 - верное отождествление, класс 0 - неверное).

Examples

TODO

class cosmatch.match.data_handler.SampleSelection

Класс для разделения обучающей выборки на тренеровочную и тестовую.

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

Разделение может производиться двумя способами:

  • base_split: разделение производится независимо от суммы потоков

  • improved_split: разделение производится таким образом, чтобы в тестовой выборке распределение главного потока у источников соответствовало распределению главного потока у источников из всего рентгеновского каталога.

Для использования improved_split необходимо задать поля потоков в нужных фильтрах в конфигурационном файле. Эти поля будут учитываться при разделении.

Таким образом, без заданных фильтров можно использовать только base_split.

static add_hostless(df, method='base', share=0.8, seed=42, df_to_filter=None)

Добавляет бездомные объекты в каталог, позволяя при этом получать метрики классификации бездомных источников. Без добавления бездомных источников метрики не посчитаются. (в наборе не будет бездомных источников для классификации).

Пока реализовано добавление ‘base’ - удаление (1-share)% верных пар, таким образом получаем (1- share)% бездомных источников.

Будет реализованно ‘improved’ - попытка построить бездомные на основании основного каталога. Для использования improved method необходимо установить параметр df_to_filter, в котором будет содержаться целевой поток, использование которого будет приводить к тому, что бездомные источники будут добавлены в зависимости от этого потока. Целевой поток достаточно критично влияет на вероятность быть бездомным на реалиных данных, так что использование этого метода позволит получить тестовую выборку гораздо более репрезентативную.

Parameters:
  • df (DataFrame) – Каталог пар рентген-оптика.

  • method (str) – Тип добавления бездомных источников. Есть варианты [‘no’,’base’,’improved’].

  • share (float) – Доля оставшихся объектов с парами.

  • seed (int) – np.random.seed().

  • df_to_filter (Optional[DataFrame]) – Каталог с целевыми потоками.

Return type:

None

Note

Функция изменяет каталог - удаляет некоторые строки.

Examples

Базовый пример добавления бездомных источников в каталог. В общем случае не рукомендуется использовать этот модуль непосредственно, лучше исполнять его в рамках cosmatch.match.Pipeline.

>>> import pandas as pd
>>> import numpy as np
>>> from cosmatch.match.data_handler import SampleSelection
>>> from cosmatch.utils import correlate
>>> from cosmatch.fake import generate_catalog
>>>
>>> size_opt = 1000; size_xray = 100
>>>
>>> opt = generate_catalog(name='opt', size=size_opt, random_state=42)
>>> xray = generate_catalog(name='xray', size=size_xray, random_state=42)
>>> df = correlate(opt, xray, 10, add_distance=True)
>>>
>>> # Ставим метку верного отождествления для пар с минимальной дистанцией (для эксперимента)
>>> min_distance = df.groupby('id_xray')['distance'].transform('min')
>>> df['mark'] = df['distance'] == min_distance
>>> df['mark'].sum() == df['id_xray'].nunique()
True

Для каждого уникального xray источника у нас есть верная с ним пара. Теперь уберем 20% таких пар:

>>> SampleSelection.add_hostless(df, method='base', share=0.8, seed=42)
>>> df['mark'].sum(), df['id_xray'].nunique()
(65, 100)

Важно заметить, что удаляются только пары с позитивными метками у тех target источников, для которых в наборе данных есть еще одна пара с меткой mark=0

Метод “improved” в разработке TODO.

static get_splited_data(df, split_method='base', hostless_method='no', train_size=0.8, seed=42, df_to_filter=None)

Разделяет входной каталог на обучающую и тестовую выборку определенным способом.

Parameters:
  • df (DataFrame) – Каталог верных и неверный пар рентген-оптика

  • split_method (str) – Вариант разбиения - [‘base’, ‘impoved’]

  • hostless_method (str) – Вариант добавления бездомных источников - [‘no’,’base’,’improved’]

  • train_size (float) – Пропорция тренеровочной выборки.

  • seed (int) – np.random.seed().

  • df_to_filter (Optional[DataFrame]) – Каталог для определения статистики по основному потоку.

Return type:

Tuple[DataFrame, DataFrame, ndarray, ndarray]

Returns:

  • Тренеровочный набор данных без меток класса.

  • Тестовый набор данных без меток класса.

  • Метки класса для пар из тренеровочного наборы данных.

  • Метки класса для пар из тестового набора данных.

Example

>>> from cosmatch.fake import generate_correlated_catalog
>>> from cosmatch.match.data_handler import SampleSelection
>>>
>>> ## Создаем совмещенный каталог
>>> data = generate_correlated_catalog(name_frame='frame', name_target='target',
...                                    size_frame=500, size_target=200,
...                                    random_state=42, num_frame_flux=0,
...                                    num_target_flux=0,max_distance=10, distance=True,
...                                    add_mark=True, mark_method='nearest')
>>>
>>> data.mark.value_counts()
>>> # mark
>>> # 0    26021
>>> # 1      200
>>> # Name: count, dtype: int64
>>>
>>> train, test, y_train, y_test = SampleSelection.get_splited_data(data, split_method='base', hostless_method='no',
...                                                                  train_size=0.8, seed=42)
>>> y_train.sum(), y_test.sum()
>>> # (160, 40)
>>>
>>> len(train), len(test)
>>> # (21070, 5151)

Рассмотрим добавление бездомных объектов:

>>> train, test, y_train, y_test = SampleSelection.get_splited_data(data, split_method='base', hostless_method='base',
...                                                                  train_size=0.8, seed=42)
>>> y_train.sum(), y_test.sum(),
>>> # (125, 36)
>>> len(train), len(test)
>>> # (21035, 5147)
cosmatch.match.data_handler.get_pairs_predict(frame, target, max_distance=15)

Возвращает каталог всевозможных пар рентген-оптика в заданном радиусе с необработанными колонками.

Данный каталог можно применять для предсказания верных отождествлений - по сути на построенном множестве пар и решается задача отождествления.

Parameters:
  • frame (DataFrame) – каталог c frame объектами. Attrs: [‘name’, ‘id’, ‘ra’, ‘dec’]

  • target (DataFrame) – каталог c target объектами. Attrs: [‘name’, ‘id’, ‘ra’, ‘dec’, ‘poserr’]

  • max_distance (float) – максимальное расстояние в парах между объектами объектами в угловых секундах.

Returns:

[‘name_frame’, ‘name_target’, ‘id_frame’, ‘id_target’, ‘ra_frame’, ‘dec_frame’, ‘ra_target’, ‘dec_target’, ‘ids’, ‘coords’]

Return type:

Набор пар frame-target со всеми колонками из обоих наборов данных. Attrs

Examples

Пример работы на сгенерированном каталоге:

>>> from cosmatch.match import get_pairs_predict
>>> from cosmatch.fake import generate_catalog
>>>
>>> frame_size = 200; target_size = 100
>>>
>>> frame = generate_catalog('opt', size=frame_size, random_state=42)
>>>
>>> target = generate_catalog('xray', size=target_size, random_state=42, other_columns=['poserr'])
>>> target.attrs['poserr'] = 'poserr'
>>>
>>> pairs = get_pairs_predict(frame, target, max_distance=15)
>>> pairs.columns
>>> # Index(['id_opt', 'id_xray', 'distance', 'ra_opt', 'dec_opt', 'ra_xray', 'dec_xray', 'poserr'], dtype='object')
>>> pairs.shape
>>> # (9725, 8)
>>> pairs['distance'].max()
>>> # 14.998417402192134
cosmatch.match.data_handler.get_pairs_train(frame, target, target_support, max_distance=15, probability=0.05)

Возвращает маркированный каталог пар рентген-оптика с необработанными колонками.

Parameters:
  • frame (DataFrame) – Каталог с frame объектами. Attrs: name, id, ra, dec

  • target (DataFrame) – Каталог с target объектами. Attrs: name, id, ra, dec, poserr

  • target_support (DataFrame) – Каталог с target_support объектами. Attrs: name, id, ra, dec

  • max_distance (float) – Максимальное расстояние в угловых секундах между frame и target_support объектами, которое будет в полученных парах. Следует выбирать в зависимости от того, как были получены наборы данных. Не рекомендуется делать менее 10.

  • probability (float) – Вероятность, что frame объект внутри радиуса будет неверным компаньоном для target источника. Напрямую влияет на размер положительной и отрицательной выборки.

Return type:

DataFrame

Returns:

Набор пар frame-target со всеми колонками из обоих наборов данных, включая колонку mark. mark=1 - верное отождествление, mark=0 - неверное отождествление.

Examples

Базовый пример работы функции:

>>> from cosmatch.match import get_pairs_train
>>> from cosmatch.fake import generate_catalog
>>>
>>> frame = generate_catalog(name='frame', size=100, random_state=42)
>>> frame.columns
>>> # Index(['id_frame', 'ra_frame', 'dec_frame'], dtype='object')
>>> frame.attrs
>>> # {'name': 'frame', 'id': 'id_frame', 'ra': 'ra_frame', 'dec': 'dec_frame'}
>>>
>>> target = generate_catalog(name='target', size=10, random_state=42, other_columns=['poserr'])
>>> target.attrs['poserr'] = 'poserr'
>>>
>>> target_support = generate_catalog(name='support', size=10, random_state=42)
>>>
>>> result = get_pairs_train(frame, target, target_support, max_distance=10, probability=0.05)
>>> result.columns
>>> # Index(['id_frame', 'id_target', 'mark', 'distance', 'ra_frame', 'dec_frame', 'ra_target', 'dec_target', 'poserr'], dtype='object')

Вы наборах данных могут содержаться любые дополнительные колонки, после выполнения функции они будут добавлены в результирующий набор. Ко всем колонкам, кроме основных (‘id’, ‘ra’, ‘dec’, ‘poserr’) будет добавлен постфикс f’_{name}’, где name соответствующий атрибут таблицы.

>>> frame['flux_1'] = ...
>>> frame['flux_2'] = ...
>>> target['flux_1'] = ...
>>> target['flux_2'] = ...
>>> result = get_pairs_train(frame, target, target_support, max_distance=10, probability=0.05)
>>> result.columns
>>> # Index(['id_frame', 'id_target', 'mark', 'distance','ra_frame', 'dec_frame', 'ra_target',
>>> #        'dec_target', 'frame_flux_1', 'frame_flux_2', 'poserr', 'target_flux_1',
>>> #        'target_flux_2'], dtype='object')
>>>
>>> result['distance'].max()
>>> # 9.895813043836682

В результирующем наборе будут следующие атрибуты:

>>> result.attrs
>>> # {'ids': ['id_frame', 'id_target'],
>>> # 'coords': ['ra_frame', 'dec_frame', 'ra_target', 'dec_target'],
>>> # 'name_frame': 'frame', 'id_frame': 'id_frame', 'ra_frame': 'ra_frame', 'dec_frame': 'dec_frame',
>>> # 'name_target': 'target', 'id_target': 'id_target', 'ra_target': 'ra_target', 'dec_target': 'dec_target'}

В дальнейшей работе программы эти атрибуты будут использоваться для добавления новых признаков, игнорирования признаков и многих других действий. Не рекомендуется изменять имена атрибутов без крайней необходимости.

Pipeline module

Модуль для составления пайплайна с предсказанием.

class cosmatch.match.pipeline.Pipeline(model, transforms=[], metrics=[RocAucNearest, RocAucHostless], ignored_features=[], how_to_split='base', add_hostless='base', df_to_filter=None, random_state=42)

TODO.

about()
Return type:

str

calc_metric_on_set(df, query=None)
Return type:

dict[Metric, float]

fit(df)
Return type:

Pipeline

get_name_pattern()
Return type:

dict[str, str]

predict(df, name_pattern=None, keep_features=False)
Return type:

DataFrame

split_data(df)
Return type:

tuple[DataFrame, DataFrame, ndarray, ndarray]

transform(df, name_pattern=None)
Return type:

DataFrame

tune_hyperopt(df, iters=50, save=False, name='tmp', verbose=True)
Return type:

Pipeline

Models module

Набор моделей для решения задачи отождествления и поиска бездомных источников.

class cosmatch.match.models.base.Model

Абстрактная модель для решения задачи отождествления.

fit(X, y)

Обучение модели.

Return type:

Model

get_predicted(X)

Сделать предсказания модели с 3 вероятностями: p_i, P_i, P_0 и флагом наиболее вероятного отождествления.

Return type:

DataFrame

abstract predict_proba(df)

Предсказание вероятностей.

Return type:

DataFrame

validate(X, y, metrics)

Валидация модели.

Return type:

dict[Metric, float]

class cosmatch.match.models.base.NearestNeighbour(frequency_between=(10, 15))

Модель поиска ближайшего соседа. Строит вероятнсти TODO.

predict_proba(X)

Выполняет метод predict_proba для внутренней модели.

Parameters:

X (DataFrame) – Таблица с парами рентген-оптика.

Return type:

ndarray

Returns:

Возвращает вероятности принадлежности пары к первому классу.

Metrics module

Модуль, содержащий метрики для разных задач.

Есть следующие метрики:

  • RocAucIdentification

  • RocAucNearest

  • Completeness

  • PrecisionIdentification

  • RocAucHostless

  • PrecisionHostless

class cosmatch.match.metrics.Completeness

Класс для посчета процента правильно найденных верных отождествлений.

\[\text{Completeness} = \frac{\text{Количество верно выбранных пар}}{\text{количество всех верных пар рентген-оптика}}\]

Где:

  • Количество верно выбранных пар - Для каждого рентгеновского истчоника оставляется пара с наибольшей вероятностью и подсчитывается количество верных пар среди этого множества.

  • Количество всех верных отождествлений рентген-оптика в каталоге.

Таким образом мы понимаем, какой процент верных пар рентген-оптика из всего множества был выбран, как наиболее верояная пара для рентгеновского источника.

Метрика Completeness рассчитывается только для верных пар рентген-оптика и не учитывает бездомные рентгеновские источники.

calculate(df)

Расчет метрики.

Набор данных должен содержать в себе колонки [‘id_xray’, ‘P_i’, ‘P_0’, ‘mark’].

Return type:

float

class cosmatch.match.metrics.Metric

Абстрактный класс для всех метрик.

От класса следует наследовать другие абстрактные классы, характеризующиеся на метриках для различных задач.

На данный момент есть метрики для следующих задач:

  • Задача отождествления: - Поиск верных пар рентген оптика - метрики строятся по уникальным парам рентген-оптикам в наборе.

  • Задача поиска бездомных источников: - Поиск рентгеновских источников, для которых отстутвует оптический компаньон в каталоге - метрика рассчитывается по уникальным рентгеновским источникам.

abstract calculate(df)

Подсчет метрики.

Return type:

float

class cosmatch.match.metrics.MetricHostless

Абстрактный класс для подсчета метрик для задачи поиска бездомных источников.

add_hostless_mark(df)

Добавляет метку бездомности рентгеновского источника.

Если метка равна 1 - у источника нет компаньона в наборе данных, если 0 - компаньон есть.

Return type:

None

class cosmatch.match.metrics.MetricIdentification

Абстрактный класс для подсчета метрик для задачи поиска отождествлений.

class cosmatch.match.metrics.PrecisionHostless

Класс для подсчета метрики precision при пороге recall=0.9 для задачи поиска бездомных источников.

Note

Метрика будет работать некоректно, если не было произведено добавления бездомных источников.

calculate(df, level=0.9)

Расчет метрики.

Набор данных должен содержать в себе колонки [‘id_xray’, ‘P_i’, ‘P_0’, ‘mark’].

Return type:

float

class cosmatch.match.metrics.PrecisionIdentification

Класс для подсчета метрики precision при пороге recall=0.9 для задачи отождествления.

Значение recall не может быть больше метрики completeness.

calculate(df, level=0.9)

Расчет метрики.

Набор данных должен содержать в себе колонки [‘id_xray’, ‘P_i’, ‘P_0’, ‘mark’].

Return type:

float

class cosmatch.match.metrics.RocAucHostless

Класс для расчета метрики ROC_AUC для задачи поиска бездомных источников.

В данном случае каталог группируется по всем рентгеновским источникам и рассматривается ROC_AUC по полю P_0 и показателю отсутсвие отождествления в каталоге.

Note

Метрика будет работать некоректно, если не было произведено добавления бездомных источников.

calculate(df)

Расчет метрики.

Набор данных должен содержать в себе колонки [‘id_xray’, ‘P_0’, ‘mark’].

Return type:

float

class cosmatch.match.metrics.RocAucIdentification

Класс для расчета метрики ROC_AUC для задачи отождествления для всего множества пар.

Метрика не очень информативна, так как в каталоге присутсвует множество неверных пар, которых легко классифицировать, как неверные пары.

calculate(df)

Расчет метрики.

Набор данных должен содержать в себе колонки [‘id_xray’, ‘mark’, ‘P_i’].

Return type:

float

class cosmatch.match.metrics.RocAucNearest

Класс для расчета метрики ROC_AUC для наиболее вероятных пар для задачи поиска отождествлений.

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

Метрика рекомендуется для рассчета, так как откидывает большенство неверных пар с малой вероятностью - а таких пар много (например, объекты с большой дистанцией).

calculate(df)

Расчет метрики.

Набор данных должен содержать в себе колонки [‘id_xray’, ‘P_i’, ‘mark’].

Return type:

float