2009-06-17 118 views
3

难道你们请告诉我如何让下面的代码更pythonic?你如何使这段代码更pythonic?

该代码是正确的。充分披露 - 这是this机器学习课程讲义#4中的问题1b。我应该在两个数据集上使用牛顿算法来拟合逻辑假设。但他们使用matlab &我正在使用scipy

例如我有一个问题是矩阵保持四舍五入到整数,直到我初始化一个值为0.0。有没有更好的办法?

感谢

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 
+1

y = 11行是做什么的? – SilentGhost 2009-06-17 14:05:15

+0

设置酷点。 – Geo 2009-06-17 14:05:50

+0

+1在句子中使用pythonic这个词。 – samoz 2009-06-17 14:08:39

回答

4
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 
9

一个明显的变化是摆脱了“for i in range(1,100):”并且只是遍历文件行。要遍历这两个文件(xfile和yfile),将它们压缩。即喜欢的东西替换块:

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) 
    ... 

(这是假设是100线,(例如,你希望整个文件中的文件),如果你刻意限制到第一 100行,你。可以使用类似:

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

然而,它也效率低下的遍历同一个文件的6倍 - 更好地将其加载到存储器中,并遍历它在那里,也就是你的循环外,有:

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

而内刚:

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

,读取文件到列表可以大幅度简单

for line in open("q1x.dat", "r"): 
    x = map(float,line.split(" ")[1:]) 
y = map(float, open("q1y.dat", "r").readlines()) 
3

的矩阵保持四舍五入到整数,直到我初始化一个值的代码 到0.0。有没有更好的办法?

在你的代码的顶部:

from __future__ import division 

在Python 2.6和更早的版本,除非有至少一个范围内浮动点数整数除法总是返回一个整数。在Python 3.0(以及2.6中的未来分区)中,分区更多地工作于人类可能期望的状态。

如果你想整数师返回一个整数,你从未来进口,使用双//。那就是

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