如何让这段代码更加Pythonic?
-
06-07-2019 - |
题
你们能告诉我如何让下面的代码更加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
解决方案
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
其他提示
一个明显的变化是去掉“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.0。还有更好的方法吗?
代码顶部:
from __future__ import division
在Python 2.6及更早版本中,整数除法总是返回一个整数,除非其中至少有一个浮点数。在Python 3.0(以及2.6中的 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
将文件读入列表的代码可以非常简单
for line in open("q1x.dat", "r"):
x = map(float,line.split(" ")[1:])
y = map(float, open("q1y.dat", "r").readlines())
不隶属于 StackOverflow