multilinear
Multilinear
Bases: NToOneTransformer
N-to-1 transformation allowing to get 1 variable by applying a linear combination of N other variables.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
coefs | List[float] | Coefficients of the multilinear function. | required |
ignore_input_indexes | Optional[List[int]] | Indexes of the data in series to ignore when computing the repartition. | None |
Source code in eki_mmo_equations/n_to_one_transformations/multilinear.py
class Multilinear(NToOneTransformer):
"""N-to-1 transformation allowing to get 1 variable by applying a linear combination of N other variables.
```math
\\alpha_1 \\times serie_1 + \\alpha_2 \\times serie_2 + ... + \\alpha_N \\times serie_N
```
Args:
coefs (List[float]): Coefficients of the multilinear function.
ignore_input_indexes (Optional[List[int]], optional): Indexes of the data in series to ignore when
computing the repartition.
"""
def __init__(self, coefs: List[float], ignore_input_indexes: Optional[List[int]] = None):
self.coefs: List[float] = coefs
self.ignore_input_indexes: List[int] = ignore_input_indexes if ignore_input_indexes else []
@property
def parameters(self) -> Dict[str, float]:
return self.__dict__
@property
def is_linear(self) -> bool:
return True
# ------- METHODS -------
def transform(self, series: List[np.ndarray], copy=False) -> np.ndarray:
series = super().transform(series, copy)
return self._transformer(series, self.coefs)
def repartition(self, series: List[np.ndarray]) -> List[np.ndarray]:
"Returns the repartition of the output series from the initial input series."
repartition_series = [serie for i, serie in enumerate(series) if i not in self.ignore_input_indexes]
repartition_coefs = [coef for i, coef in enumerate(self.coefs) if i not in self.ignore_input_indexes]
weighted_series = [serie * coef for serie, coef in zip(repartition_series, repartition_coefs)]
proportionned_weighted_series = [
np.nan_to_num(weighted_serie / np.sum(weighted_series, axis=0)) for weighted_serie in weighted_series
]
for index in self.ignore_input_indexes:
proportionned_weighted_series.insert(index, np.zeros(len(series[index])))
return proportionned_weighted_series
# ------- TRANSFORMERS -------
@staticmethod
def _transformer(series: List[np.ndarray], coefs: List[float]) -> np.ndarray:
"Returns the linear combination of the different input variables."
return np.sum([serie * coef for serie, coef in zip(series, coefs)], axis=0)
# ------- CHECKERS -------
def check_params(self, series: List[np.ndarray]):
"""Check if parameters respect their application scope."""
if not len(self.coefs) == len(series):
raise ParameterScopeException(
"Number of series don't match number of coefs. "
+ f"Number of coefs:{len(self.coefs)} . Number of series:{len(series)}"
)
if len(self.ignore_input_indexes) != len(set(self.ignore_input_indexes)):
raise ParameterScopeException(
f"Incorrect {self.__class__.__name__} parameters. Values ignore_input_indexes"
f" should be unique. Current values:{self.ignore_input_indexes}"
)
if not all(index < len(series) for index in self.ignore_input_indexes):
raise ParameterScopeException(
f"Incorrect {self.__class__.__name__} parameters. Each value of ignore_input_indexes"
f" should be lower than the number of series as input - lower than {len(series)}."
)
if len(self.ignore_input_indexes) >= len(series):
raise ParameterScopeException(
f"Incorrect {self.__class__.__name__}. Length of ignore_input_indexes"
f" should be inferior to length of input series - lower than {len(series)}."
)
check_params(series)
Check if parameters respect their application scope.
Source code in eki_mmo_equations/n_to_one_transformations/multilinear.py
def check_params(self, series: List[np.ndarray]):
"""Check if parameters respect their application scope."""
if not len(self.coefs) == len(series):
raise ParameterScopeException(
"Number of series don't match number of coefs. "
+ f"Number of coefs:{len(self.coefs)} . Number of series:{len(series)}"
)
if len(self.ignore_input_indexes) != len(set(self.ignore_input_indexes)):
raise ParameterScopeException(
f"Incorrect {self.__class__.__name__} parameters. Values ignore_input_indexes"
f" should be unique. Current values:{self.ignore_input_indexes}"
)
if not all(index < len(series) for index in self.ignore_input_indexes):
raise ParameterScopeException(
f"Incorrect {self.__class__.__name__} parameters. Each value of ignore_input_indexes"
f" should be lower than the number of series as input - lower than {len(series)}."
)
if len(self.ignore_input_indexes) >= len(series):
raise ParameterScopeException(
f"Incorrect {self.__class__.__name__}. Length of ignore_input_indexes"
f" should be inferior to length of input series - lower than {len(series)}."
)
repartition(series)
Returns the repartition of the output series from the initial input series.
Source code in eki_mmo_equations/n_to_one_transformations/multilinear.py
def repartition(self, series: List[np.ndarray]) -> List[np.ndarray]:
"Returns the repartition of the output series from the initial input series."
repartition_series = [serie for i, serie in enumerate(series) if i not in self.ignore_input_indexes]
repartition_coefs = [coef for i, coef in enumerate(self.coefs) if i not in self.ignore_input_indexes]
weighted_series = [serie * coef for serie, coef in zip(repartition_series, repartition_coefs)]
proportionned_weighted_series = [
np.nan_to_num(weighted_serie / np.sum(weighted_series, axis=0)) for weighted_serie in weighted_series
]
for index in self.ignore_input_indexes:
proportionned_weighted_series.insert(index, np.zeros(len(series[index])))
return proportionned_weighted_series