簡體   English   中英

你如何使這段代碼更像 pythonic?

[英]How do you make this code more pythonic?

你們能告訴我如何讓下面的代碼更像 pythonic 嗎?

代碼是正確的。 全面披露 - 這是機器學習課程講義 #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

一個明顯的變化是去掉“for i in range(1, 100):”,只遍歷文件行。 要遍歷這兩個文件(xfile 和 yfile),zip 它們。 即用類似的東西替換那個塊:

 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 次迭代也是低效的——最好提前將其加載到 memory,然后在那里循環,即。 在你的循環之外,有:

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

矩陣一直四舍五入為整數,直到我將一個值初始化為 0.0。 有沒有更好的辦法?

在代碼的頂部:

from __future__ import division

在 Python 2.6 及更早版本中,除法 integer 始終返回 integer,除非其中至少有一個浮點數。 在 Python 3.0(以及未來2.6 中的除法)中,除法的工作方式更多地符合我們人類的預期。

如果您希望integer 除法返回 integer,並且您已從future導入,請使用雙 //。 那是

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

您可以使用with語句。

將文件讀入列表的代碼可以大大簡化

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM