Разница в использовании ** и функции Pow - PullRequest
0 голосов
/ 01 ноября 2018

при попытке написать функцию стоимости для линейной регрессии возникает ошибка при замене ** функцией pow в cost_function:

Функция первоначальной стоимости

def cost_function(x,y,theta):
    m = np.size(y)
    j = (1/(2*m))*np.sum(np.power(np.matmul(x,theta)-y),2)
    return j

Функция стоимости, дающая ошибку:

def cost_function(x,y,theta):
        m = np.size(y)
        j = (1/(2*m))*np.sum((np.matmul(x,theta)-y)**2)
        return j

Градиентный спуск

def gradient_descent(x,y,theta,learn_rate,iters):
    x = np.mat(x);y = np.mat(y); theta= np.mat(theta);
    m = np.size(y)
    j_hist = np.zeros(iters)
    for i in range(0,iters):
        temp = theta - (learn_rate/m)*(x.T*(x*theta-y))
        theta = temp
        j_hist[i] = cost_function(x,y,theta)
    return (theta),j_hist

Переменные значения

theta  = np.zeros((2,1))
learn_rate = 0.01
iters = 1000
x is (97,2) matrix
y is (97,1) matrix

функция стоимости рассчитывается штрафом со значением 32.0727 Ошибка возникает при использовании той же функции при градиентном спуске.

Получаемая ошибка: LinAlgError: последние 2 измерения массива должны быть квадратными

1 Ответ

0 голосов
/ 01 ноября 2018

Сначала давайте проведем различие между pow, ** и np.power. pow - это функция Python, которая согласно документам эквивалентна ** при использовании с 2 аргументами.

Во-вторых, вы применяете np.mat к массивам, создавая np.matrix объектов. Согласно документам:

Он имеет определенные специальные операторы, такие как * (матричное умножение) и ** (матричная мощность).

матричная мощность:

In [475]: np.mat([[1,2],[3,4]])**2
Out[475]: 
matrix([[ 7, 10],
        [15, 22]])

Поэлементный квадрат:

In [476]: np.array([[1,2],[3,4]])**2
Out[476]: 
array([[ 1,  4],
       [ 9, 16]])
In [477]: np.power(np.mat([[1,2],[3,4]]),2)
Out[477]: 
matrix([[ 1,  4],
        [ 9, 16]])

Матрица питания:

In [478]: arr = np.array([[1,2],[3,4]])
In [479]: arr@arr            # np.matmul
Out[479]: 
array([[ 7, 10],
       [15, 22]])

С неквадратной матрицей:

In [480]: np.power(np.mat([[1,2]]),2)
Out[480]: matrix([[1, 4]])             # elementwise

Попытка сделать matrix_power на неквадратной матрице:

In [481]: np.mat([[1,2]])**2
---------------------------------------------------------------------------
LinAlgError                               Traceback (most recent call last)
<ipython-input-481-18e19d5a9d6c> in <module>()
----> 1 np.mat([[1,2]])**2

/usr/local/lib/python3.6/dist-packages/numpy/matrixlib/defmatrix.py in __pow__(self, other)
    226 
    227     def __pow__(self, other):
--> 228         return matrix_power(self, other)
    229 
    230     def __ipow__(self, other):

/usr/local/lib/python3.6/dist-packages/numpy/linalg/linalg.py in matrix_power(a, n)
    600     a = asanyarray(a)
    601     _assertRankAtLeast2(a)
--> 602     _assertNdSquareness(a)
    603 
    604     try:

/usr/local/lib/python3.6/dist-packages/numpy/linalg/linalg.py in _assertNdSquareness(*arrays)
    213         m, n = a.shape[-2:]
    214         if m != n:
--> 215             raise LinAlgError('Last 2 dimensions of the array must be square')
    216 
    217 def _assertFinite(*arrays):

LinAlgError: Last 2 dimensions of the array must be square

Обратите внимание, что весь список трассировки matrix_power. Вот почему мы часто просим увидеть весь след.

Почему вы устанавливаете x, y и theta на np.mat? cost_function использует matmul. С этой функцией и ее оператором @ есть несколько (э) веских причин для использования np.matrix.

Несмотря на тему, вы не пытались использовать pow. Это смутило меня и еще одного комментатора. Я пытался найти np.pow или scipy версию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...