2009-06-17 119 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