Pergunta

vocês poderiam me dizer como eu posso fazer o seguinte código mais Python?

O código está correto. A divulgação completa - é problema 1b na Apostila # 4 de esta máquina curso de aprendizagem. Eu deveria usar o algoritmo de Newton sobre os dois conjuntos de dados para a montagem de uma hipótese logística. Mas eles usam Matlab e estou usando scipy

Por exemplo, uma pergunta que eu tenho é as matrizes mantidas arredondamento para números inteiros até que eu inicializado um valor para 0.0. Existe uma maneira melhor?

Graças

import os.path
import math
from numpy import matrix
from scipy.linalg import inv #, det, eig

x = matrix( '0.0;0;1'  )
y = 11
grad = matrix( '0.0;0;0'  )
hess = matrix('0.0,0,0;0,0,0;0,0,0')
theta = matrix( '0.0;0;0'  ) 


# run until convergence=6or7
for i in range(1, 6):
  #reset
  grad = matrix( '0.0;0;0'  )
  hess = matrix('0.0,0,0;0,0,0;0,0,0')

  xfile = open("q1x.dat", "r")
  yfile = open("q1y.dat", "r")


  #over whole set=99 items  
  for i in range(1, 100):    
    xline = xfile.readline()
    s= xline.split("  ")
    x[0] = float(s[1])
    x[1] = float(s[2])
    y = float(yfile.readline())

    hypoth = 1/ (1+ math.exp(-(theta.transpose() * x)))

    for j in range(0,3):
      grad[j] = grad[j] + (y-hypoth)* x[j]      
      for k in range(0,3):
        hess[j,k] = hess[j,k] - (hypoth *(1-hypoth)*x[j]*x[k])


  theta = theta - inv(hess)*grad #update theta after construction

  xfile.close()
  yfile.close()

print "done"
print theta
Foi útil?

Solução

x = matrix([[0.],[0],[1]])
theta = matrix(zeros([3,1]))
for i in range(5):
  grad = matrix(zeros([3,1]))
  hess = matrix(zeros([3,3]))
  [xfile, yfile] = [open('q1'+a+'.dat', 'r') for a in 'xy']
  for xline, yline in zip(xfile, yfile):
    x.transpose()[0,:2] = [map(float, xline.split("  ")[1:3])]
    y = float(yline)
    hypoth = 1 / (1 + math.exp(theta.transpose() * x))
    grad += (y - hypoth) * x
    hess -= hypoth * (1 - hypoth) * x * x.transpose()
  theta += inv(hess) * grad
print "done"
print theta

Outras dicas

Uma mudança óbvia é a de se livrar do "for i in range (1, 100):" e apenas iterar sobre as linhas de arquivo. Para iterar sobre os dois arquivos (XFile e yfile), zip-los. ou seja, substituir o bloco com algo como:

 import itertools

 for xline, yline in itertools.izip(xfile, yfile):
    s= xline.split("  ")
    x[0] = float(s[1])
    x[1] = float(s[2])
    y = float(yline)
    ...

(Isso supõe que o arquivo é de 100 linhas, (ou seja, você quer que o arquivo inteiro) Se você está restringindo deliberadamente para o primeiro 100 linhas, você pode usar algo como:..

 for i, xline, yline in itertools.izip(range(100), xfile, yfile):

No entanto, a sua também ineficiente para repetir o mesmo arquivo 6 vezes - melhor para carregá-lo na memória de antecedência, e loop sobre ele lá, ie. fora do seu loop, tem-se:

xfile = open("q1x.dat", "r")
yfile = open("q1y.dat", "r")
data = zip([line.split("  ")[1:3] for line in xfile], map(float, yfile))

E dentro apenas:

for (x1,x2), y in data:
    x[0] = x1
    x[1] = x2
     ...

as matrizes mantidas arredondamento para números inteiros até que eu inicializado um valor para 0,0. Existe uma maneira melhor?

No topo do seu código:

from __future__ import division

Em Python 2.6 e anteriores, a divisão inteira sempre retorna um inteiro a menos que haja pelo menos um número de ponto flutuante dentro. Em Python 3.0 (e em futuro divisão em 2.6), a divisão funciona mais como nós seres humanos poderia esperar que ele.

Se você deseja divisão inteira para retornar um inteiro, e você importados de futuro , use um duplo //. Isso é

from __future__ import division
print 1//2 # prints 0
print 5//2 # prints 2
print 1/2  # prints 0.5
print 5/2  # prints 2.5

Você poderia fazer uso do com comunicado.

o código que lê os arquivos em listas poderia ser drasticamente mais simples

for line in open("q1x.dat", "r"):
    x = map(float,line.split("  ")[1:])
y = map(float, open("q1y.dat", "r").readlines())
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top