Как проверить обратимость матрицы внутри класса
Не могу правильно собрать все процедуры внутри класса. Есть набор данных, которые нужно зашифровать. Создаю класс, внутри которого создается матрица и на нее умножаются исходные данные:
class Preparer(TransformerMixin, BaseEstimator):
def fit(self, X, y=None, random_state=None):
if random_state:
np.random.seed(random_state)
X_d = X.shape[1]
Z = np.random.normal(size=(X_d, X_d))
self.Z = Z
self.X = X
return self
def transform(self, X, y=None):
return X.dot(self.Z)
X_new = Preparer().fit_transform(X, random_state=12345)
Хочу добавить внутри класса проверку этой матрицы на обратимость, сначала попробовал вот так:
class Preparer(TransformerMixin, BaseEstimator):
def fit(self, X, y=None, random_state=None):
if random_state:
np.random.seed(random_state)
X_d = X.shape[1]
Z = np.random.normal(size=(X_d, X_d))
self.Z = Z
self.X = X
return self
def check(self):
ch = self.Z
Z_rev = np.linalg.inv(ch)
if np.allclose(np.dot(ch, Z_rev), np.eye(ch.shape[0])) is True:
ans = "Correct, it's alive"
else:
ans = "Incorrect"
return ans
def transform(self, X, y=None):
return X.dot(self.Z)
X_new = Preparer().fit_transform(X, random_state=12345)
print(Preparer().check())
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-49-970f16a02444> in <module>
1 X_new = Preparer().fit_transform(X, random_state=12345)
----> 2 check_m = Preparer().check()
3 print(Preparer().check())
4 display(X.shape, X_new.shape)
<ipython-input-48-325b53b325ec> in check(self, y)
15
16 def check(self, y=None):
---> 17 ch = self.Z
18 Z_rev = np.linalg.inv(ch)
19 if np.allclose(np.dot(ch, Z_rev), np.eye(ch.shape[0])) is True:
AttributeError: 'Preparer' object has no attribute 'Z'
Затем попробовал через конструктор определить переменные:
class Preparer(TransformerMixin, BaseEstimator):
def __init__(self, Z, X):
self.Z = Z
self.X = X
def fit(self, X, y=None, random_state=None):
if random_state:
np.random.seed(random_state)
X_d = X.shape[1]
self.Z = np.random.normal(size=(X_d, X_d))
return self
def check(self):
Z_rev = np.linalg.inv(Z)
if np.allclose(np.dot(self.Z, Z_rev), np.eye(self.Z.shape[0])) is True:
ans = "Correct, it's alive"
else:
ans = "Incorrect"
return ans
def transform(self, X, y=None):
return X.dot(self.Z)
В итоге ловлю вот такую ошибку:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-10-ceee7b2c8018> in <module>
----> 1 X_new = Preparer().fit_transform(X, random_state=12345)
2 #print(Preparer().check())
3 display(X.shape, X_new.shape)
TypeError: __init__() missing 2 required positional arguments: 'Z' and 'X'
Не могу понять, как правильно это все собрать. Просмотрел несколько статей по классам, но не смог найти какую-то подробную, там все слишком упрощенно, в реале потом воспроизвести на своем примере не получается. Подскажите, пожалуйста, как тут внутри класса все построить или может какую статью хорошую посоветуете.
Ответы (1 шт):
Создавайте экземпляр класса и работайте с ним. В sklearn насколько я помню все трансформеры именно так работают.
preparer = Preparer() # если есть параметры инициализации, передайте их тут
X_new = preparer.fit_transform(X, random_state=12345)
print(preparer.check())
Вы же просто создаёте в каждой строке новый экземпляр класса, вызывая его конструктор: Preparer(). Новый экземпляр класса ничего не знает о переменных предыдущего экземпляра (но знает статические переменные, что в общем-то не выход в данном случае). И в реализации класса вы путаете статические переменные и переменные экземпляра класса self., разберитесь, где у вас чего, и всё заработает. Лучше без особой надобности не делать статических переменных, обычно это плохой стиль, так же как и использовать глобальные переменные.