python
July 6, 2022

Унификация формата вызова функций в Python

При автоматизации некоторого алгоритма зачастую сталкиваешься с трудностью передачи функций со схожим инструментарием, но разным набором аргументов. Например, вам хочется использовать единый интерфейс вызова метрики ошибки для модели регрессии с передачей в качестве параметров вектора целей и прогноза. В то же время для подсчета корня из среднеквадратичной ошибки потребуется в функцию mean_squared_error из модуля sklearn передать параметр squared=False, а для средней абсолютной ошибки дополнительных аргументов не требуется.

Соответственно, чтобы некоторый функционал принимал абстрактный метод ошибки и единообразно обрабатывал оба кейса, потребуется предпринять дополнительные усилия. Отличным решением ситуации является частичное определение дополнительных аргументов функции. Например, это можно сделать с помощью функции partial из модуля functools. Ниже трансформируем mean_squared_error в функцию rmse для подсчета корня из среднеквадратической ошибки:

import pandas as pd
from sklearn.metrics import mean_squared_error
from functools import partial

rmse = partial(mean_squared_error, squared=False)

rmse(pd.Series([8,8]), pd.Series([6,6]))

Такое частичное определение можно сделать и с помощью лямбда функций, например так:

rmse_alt = lambda x1,x2: mean_squared_error(x1, x2, squared=False)
rmse_alt(pd.Series([8,8]), pd.Series([6,6]))

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

from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error
mae(pd.Series([8,8]), pd.Series([6,6]))

А теперь после преобразований, вызов метрики ошибки для rmse и mae будет происходить одинаково. Пусть у нас имеется функция, выполняющая некую большую задачу и вычисляющая функцию ошибки регрессии, которую принимает в качестве аргумента. Схема ее определения может выглядеть так:

def f(metrics_func, other_args=None):
    # some calcs     
    x1 = pd.Series([8,8])
    x2 = pd.Series([6,6])
    print(metrics_func(x1, x2))

А так можно вызвать функцию с разными аргументами:

f(rmse)
f(mae)

При передаче в f ссылки на mean_squared_error вызов не завершается ошибкой, но параметр squared будет установлен в True и подсчитана среднеквадратическая ошибка, а не ее корень:

f(mean_squared_error)

Не пропустите ничего интересного и подписывайтесь на страницы канала в других социальных сетях:

Яндекс Дзен

Telegram