Я хочу построить модель линейной регрессии, которая принимает временные метки в качестве целей и использует секунды с 1970-01-01 00:00:00 (pd.Timestamp(0)
) внутри. predict
должен возвращать метки времени.
Я пытался сделать эту работу с TransformedTargetRegressor
. Тем не менее, я сталкиваюсь с TypeError: invalid type promotion
Я не могу решить.
Демонстрационный код:
import pandas as pd
import numpy as np
from sklearn.compose import TransformedTargetRegressor
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import FunctionTransformer
# helper function to convert a 2D numpy array of seconds to a 2D array of timestamps
def _to_timestamp(seconds: np.ndarray):
return pd.DataFrame(seconds).apply(pd.to_datetime, unit='s').values
# helper function to convert a 2D numpy array of timestamps to a 2D array of seconds
def _to_float(timestamps):
deltas = pd.DataFrame(timestamps).sub(pd.Timestamp(0))
return deltas.apply(lambda s: s.dt.total_seconds()).values
# build transformer from helper functions
TimeTransformer = FunctionTransformer(
func=_to_float,
inverse_func=_to_timestamp,
validate=True,
check_inverse=True
)
# make a LinearRegression chained with a TimeTransformer
def TimeTargetLinearRegression():
return TransformedTargetRegressor(
regressor=LinearRegression(),
transformer=TimeTransformer
)
# test run
if __name__ == '__main__':
model = TimeTargetLinearRegression()
X = np.array([[1], [2], [3]], dtype=float)
y = pd.date_range(start=0, periods=3, freq='s')
model.fit(X=X, y=y) # raises TypeError
Вывод:
Traceback (most recent call last):
File "<input>", line 1, in <module>
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.3.3\plugins\python-ce\helpers\pydev\_pydev_bundle\pydev_umd.py", line 197, in runfile
pydev_imports.execfile(filename, global_vars, local_vars) # execute the script
File "C:\Program Files\JetBrains\PyCharm Community Edition 2019.3.3\plugins\python-ce\helpers\pydev\_pydev_imps\_pydev_execfile.py", line 18, in execfile
exec(compile(contents+"\n", file, 'exec'), glob, loc)
File "C:/Users/actualpanda/.PyCharmCE2019.3/config/scratches/scratch2.py", line 36, in <module>
model.fit(X=X, y=y) # raises TypeError
File "C:\Users\actualpanda\.virtualenvs\SomeProject--3333Ox_\lib\site-packages\sklearn\compose\_target.py", line 185, in fit
self._fit_transformer(y_2d)
File "C:\Users\actualpanda\.virtualenvs\SomeProject--3333Ox_\lib\site-packages\sklearn\compose\_target.py", line 139, in _fit_transformer
self.transformer_.fit(y)
File "C:\Users\actualpanda\.virtualenvs\SomeProject--3333Ox_\lib\site-packages\sklearn\preprocessing\_function_transformer.py", line 125, in fit
self._check_inverse_transform(X)
File "C:\Users\actualpanda\.virtualenvs\SomeProject--3333Ox_\lib\site-packages\sklearn\preprocessing\_function_transformer.py", line 102, in _check_inverse_transform
if not _allclose_dense_sparse(X[idx_selected], X_round_trip):
File "C:\Users\actualpanda\.virtualenvs\SomeProject--3333Ox_\lib\site-packages\sklearn\utils\validation.py", line 1288, in _allclose_dense_sparse
return np.allclose(x, y, rtol=rtol, atol=atol)
File "<__array_function__ internals>", line 5, in allclose
File "C:\Users\actualpanda\.virtualenvs\SomeProject--3333Ox_\lib\site-packages\numpy\core\numeric.py", line 2159, in allclose
res = all(isclose(a, b, rtol=rtol, atol=atol, equal_nan=equal_nan))
File "<__array_function__ internals>", line 5, in isclose
File "C:\Users\actualpanda\.virtualenvs\SomeProject--3333Ox_\lib\site-packages\numpy\core\numeric.py", line 2254, in isclose
dt = multiarray.result_type(y, 1.)
File "<__array_function__ internals>", line 5, in result_type
TypeError: invalid type promotion
Я ищу ответ который объясняет / разрешает TypeError
и - в случае моего подхода некорректен - предлагает метод построения регрессора, который может обрабатывать нечисловые c цели (данные функции для преобразования и обратного преобразования).
Я знаю, что могу выполнять преобразование и обратное преобразование вне регрессора, но я хочу инкапсулировать процесс в аккуратную, удобную для пользователя модель, которая не протекает изнутри.