Проверяя сценарий exmath.py
под ~/lib/python3.6/site-packages/sklearn/utils/extmath.py
, можно перейти к следующей функции
from scipy import linalg, sparse
def safe_sparse_dot(a, b, dense_output=False):
"""Dot product that handle the sparse matrix case correctly
Parameters
----------
a : array or sparse matrix
b : array or sparse matrix
dense_output : boolean, (default=False)
When False, ``a`` and ``b`` both being sparse will yield sparse output.
When True, output will always be a dense array.
Returns
-------
dot_product : array or sparse matrix
sparse if ``a`` and ``b`` are sparse and ``dense_output=False``.
"""
if a.ndim > 2 or b.ndim > 2:
if sparse.issparse(a):
# sparse is always 2D. Implies b is 3D+
# [i, j] @ [k, ..., l, m, n] -> [i, k, ..., l, n]
b_ = np.rollaxis(b, -2)
b_2d = b_.reshape((b.shape[-2], -1))
ret = a @ b_2d
ret = ret.reshape(a.shape[0], *b_.shape[1:])
elif sparse.issparse(b):
# sparse is always 2D. Implies a is 3D+
# [k, ..., l, m] @ [i, j] -> [k, ..., l, j]
a_2d = a.reshape(-1, a.shape[-1])
ret = a_2d @ b
ret = ret.reshape(*a.shape[:-1], b.shape[1])
else:
ret = np.dot(a, b)
else:
ret = a @ b
if (sparse.issparse(a) and sparse.issparse(b)
and dense_output and hasattr(ret, "toarray")):
return ret.toarray()
return ret
Обратите внимание, что он выполняет скалярное произведение между двумя массивами. Эта функция safe_sparse_dot
вызывается изнутри при вызове reg.score()
с параметрами X
, self.coef_.T
(в вашем примере это X
и reg.coef_.T
).
Случай n переменные регрессора с n> = 2
Теперь, , когда у вас есть две переменные регрессора, с fit_intercept=False
. Например, тот, который вы ранее упомянули
X, y = make_regression(n_samples=200, n_features=2, noise=4.0, random_state=0)
reg = TheilSenRegressor(random_state=0, fit_intercept=False, verbose=True).fit(X, y)
reg.score(X, y)
, вы получите следующие формы ваших переменных:
X.shape
>>> (200, 2)
reg.coef_.T.shape
>>> (2,)
. Теперь, если вы вызовете функцию разреженных точек, вы получите результат, потому что (200,2) x (2,) - допустимое умножение.
safe_sparse_dot(X, reg.coef_.T)
>>> array([-3.11195300e+01, 3.97852518e+00, 3.83392622e+01, 6.10470897e+01,
-4.93104975e+00, -7.79836353e+00, -2.92253822e+01, 1.95366691e+01,
-2.53890049e+01, 2.31799242e+00, -4.29133706e+01, -2.64249217e+01,
.....
.....
Случай регрессора с одной переменной
Когда вы рассматриваете единственную переменную регрессии . Например,
X, y = make_regression(n_samples=200, n_features=1, noise=4.0, random_state=0)
reg = TheilSenRegressor(random_state=0, fit_intercept=False, verbose=True).fit(X, y)
reg.score(X, y)
, вы получите следующую ошибку:
ValueError: matmul: Input operand 1 does not have enough dimensions (has 0, gufunc core with signature (n?,k),(k,m?)->(n?,m?) requires 1)
в основном потому, что reg.coef_
является скаляром и должен быть преобразован в 1d-массив, то есть reg.coef_.T.reshape(-1)
. Таким образом, операцию скалярного произведения можно назвать
safe_sparse_dot(X, reg.coef_.T.reshape(-1))
>>> array([-3.11195300e+01, 3.97852518e+00, 3.83392622e+01, 6.10470897e+01,
-4.93104975e+00, -7.79836353e+00, -2.92253822e+01, 1.95366691e+01,
-2.53890049e+01, 2.31799242e+00, -4.29133706e+01, -2.64249217e+01,
....
Я не знаю, поднималась ли уже эта проблема, но вы можете опубликовать ее на странице github scikit-learn.