#python #machine-learnin& #scipy #re&ression #lo&istic-re&ression
#python #машинное обучение #scipy #регрессию #логистическую регрессию
Вопрос:
У меня есть два вопроса, касающиеся этой реализации логистической регрессии на python 3 (курс Эндрю Нг):
-
Когда я беру alpha = 0.01, я получаю две ошибки:
нулевое значение, встречающееся при получении журнала
b. ошибка умножения матрицы
Я знал, что функция si&moid будет возвращать значения только между (0,1), но при печати гипотезы во время выполнения градиентного спуска я понял, что некоторые значения были округлены до 1 (что делает 1- hyp = 0 и, следовательно, ошибку). Итак, я думал, что увеличение точности theta до np.float128 помогло бы, но этого не произошло!
Однако, принимая alpha за 0.001, никаких ошибок не выдает, но я должен увеличить количество итераций до 1000000, чтобы снизить стоимость с 0.693 до 0.224.
- Я также пытался использовать оптимизатор 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) заставляет вас выбирать небольшие скорости обучения и выполнять много итераций. Это может помочь выполнить какую-то нормализацию / стандартизацию функций, если вы еще этого не сделали.