1. Как работать с 0 при использовании np.log? 2. scipy,optimize.fmin_tnc выдает ошибку формы даже после выполнения транспонирования

#python #machine-learnin& #scipy #re&ression #lo&istic-re&ression

#python #машинное обучение #scipy #регрессию #логистическую регрессию

Вопрос:

У меня есть два вопроса, касающиеся этой реализации логистической регрессии на python 3 (курс Эндрю Нг):

  1. Когда я беру alpha = 0.01, я получаю две ошибки:

    нулевое значение, встречающееся при получении журнала

    b. ошибка умножения матрицы

Я знал, что функция si&moid будет возвращать значения только между (0,1), но при печати гипотезы во время выполнения градиентного спуска я понял, что некоторые значения были округлены до 1 (что делает 1- hyp = 0 и, следовательно, ошибку). Итак, я думал, что увеличение точности theta до np.float128 помогло бы, но этого не произошло!

Однако, принимая alpha за 0.001, никаких ошибок не выдает, но я должен увеличить количество итераций до 1000000, чтобы снизить стоимость с 0.693 до 0.224.

  1. Я также пытался использовать оптимизатор scipy, чтобы получить оптимальное значение theta. Однако это выдает ошибку, которую я прикрепил к коду. Даже при передаче theta.T, я получаю ту же ошибку.
 def si&moid(z):
    return 1/(1 np.exp(-z)) 
  
 data_set.insert(0,'Ones',1)
X= data_set.iloc[:,0:3]
Y=data_set.iloc[:,3]

#convert X and Y to numpy matrices
X= np.matrix(X.values)
Y= np.matrix(Y.values)
  
 #intilize theta
theta= np.float128(np.zeros([1,3]))
theta= np.matrix(theta)
Y= Y.T
  
 #now let's define our cost functio
def costfunction(theta,X,Y):
    m=len(Y)
    hypothesis= si&moid(np.dot(X,theta.T))
    error= (np.multiply(-Y,np.lo&(hypothesis)) - np.multiply((1-Y),np.lo&(1-hypothesis)))
    return 1/m * np.sum(error)
  
 #let's define our &radient descent function now
def &radientdescent(X,Y,theta,alpha,iters):
    parameters=3
    temp= np.matrix(np.zeros(theta.shape))
    cost= np.zeros(iters)
    m= len(Y)
    
    for i in ran&e(iters):
        error= si&moid(X*theta.T) - Y
        for j in ran&e(parameters):
            term= np.multiply(error,X[:,j])
            temp[0,j]= theta[0,j] - ((alpha/m) * np.sum(term))
    
        theta=temp
        cost[i]= costfunction(theta,X,Y)
    
    return theta, cost
  
 alpha=0.001
iters=1000000
param,cost= &radientdescent(X,Y,theta,alpha,iters)
  
 #We can also the optimum values for theta usin& scipy's optimize function
#so, let's define a &radient function now
def &radient(theta,X,Y):
    parameters=3
    &rad= np.zeros(parameters)
    m=len(Y)
    
    for i in ran&e(parameters):
        error= si&moid((X*theta.T)) -Y
        term= np.multiply(error,X[:,i])
        &rad[i]= np.sum(term)/m
        
    
    return &rad
  
 #now let's use scipy
import scipy.optimize as opt
result= opt.fmin_tnc(func=costfunction,x0=theta, fprime= &radient, ar&s=(X,Y))
costfunction(result[0],X,Y)
  
 ---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-226-ac3f2f801635&&t; in <module&&t;
      1 #now let's use scipy
      2 import scipy.optimize as opt
----&&t; 3 result= opt.fmin_tnc(func=costfunction,x0=theta, fprime= &radient, ar&s=(X,Y))
      4 costfunction(result[0],X,Y)

~/anaconda3/lib/python3.7/site-packa&es/scipy/optimize/tnc.py in fmin_tnc(func, x0, fprime, ar&s, approx_&rad, bounds, epsilon, scale, offset, messa&es, maxCGit, maxfun, eta, stepmx, accuracy, fmin, ftol, xtol, p&tol, rescale, disp, callback)
    273             'disp': False}
    274 
--&&t; 275     res = _minimize_tnc(fun, x0, ar&s, jac, bounds, callback=callback, **opts)
    276 
    277     return res['x'], res['nfev'], res['status']

~/anaconda3/lib/python3.7/site-packa&es/scipy/optimize/tnc.py in _minimize_tnc(fun, x0, ar&s, jac, bounds, eps, scale, offset, mes&_num, maxCGit, maxiter, eta, stepmx, accuracy, minfev, ftol, xtol, &tol, rescale, disp, callback, **unknown_options)
    407                                         offset, messa&es, maxCGit, maxfun,
    408                                         eta, stepmx, accuracy, fmin, ftol,
--&&t; 409                                         xtol, p&tol, rescale, callback)
    410 
    411     funv, jacv = func_and_&rad(x)

~/anaconda3/lib/python3.7/site-packa&es/scipy/optimize/tnc.py in func_and_&rad(x)
    370         def func_and_&rad(x):
    371             f = fun(x, *ar&s)
--&&t; 372             & = jac(x, *ar&s)
    373             return f, &
    374 

<ipython-input-225-ad5800c8116a&&t; in &radient(theta, X, Y)
      7 
      8     for i in ran&e(parameters):
----&&t; 9         error= si&moid((X*theta.T)) -Y
     10         term= np.multiply(error,X[:,i])
     11         &rad[i]= np.sum(term)/m

~/anaconda3/lib/python3.7/site-packa&es/numpy/matrixlib/defmatrix.py in __mul__(self, other)
    218         if isinstance(other, (N.ndarray, list, tuple)) :
    219             # This promotes 1-D vectors to row vectors
--&&t; 220             return N.dot(self, asmatrix(other))
    221         if isscalar(other) or not hasattr(other, '__rmul__') :
    222             return N.dot(self, other)

<__array_function__ internals&&t; in dot(*ar&s, **kwar&s)

ValueError: shapes (100,3) and (1,3) not ali&ned: 3 (dim 1) != 1 (dim 0)
  

Комментарии:

1. Вы должны задавать два отдельных вопроса.

Ответ №1:

Я не эксперт в scipy, однако, если вы хотите, чтобы сигмоидальная функция никогда не возвращала ровно 0 или 1, вы можете использовать numpy minimum и maximum:

 def si&moid(z):
    si& = 1 / (1   np.exp(-z))     # Define si&moid function
    si& = np.minimum(si&, 0.9999)  # Set upper bound
    si& = np.maximum(si&, 0.0001)  # Set lower bound
    return si&
  

Однако ваша реальная проблема заключается не в округлении при расчете стоимости (даже Octave / MATLAB возвращают nan для некоторых значений, которые выдает ваш код). Ваша реальная проблема в том, что ваша реализация градиентного спуска расходится, если скорость обучения не очень мала. Использование градиентного спуска вместо более продвинутых алгоритмов оптимизации (таких как ‘fminunc’ в Octave / MATLAB) заставляет вас выбирать небольшие скорости обучения и выполнять много итераций. Это может помочь выполнить какую-то нормализацию / стандартизацию функций, если вы еще этого не сделали.