سؤال

يمكن يا رفاق من فضلك قل لي كيف يمكنني جعل البرمجية التالية أكثر pythonic?

رمز هو الصحيح.الكشف الكامل - انها مشكلة 1b في صدقة #4 هذا آلة دورة التعلم.أنا من المفترض أن استخدام نيوتن الخوارزمية على مجموعتين من البيانات عن تركيب اللوجستية الفرضية.لكنها استخدام 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

نصائح أخرى

واحد تغيير واضح هو التخلص من "لأنني في مجموعة (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

في بيثون 2.6 و في وقت سابق ، قسمة عدد صحيح دائما بإرجاع عدد صحيح إلا إذا كان هناك واحد على الأقل النقطة العائمة عدد من الداخل.في بيثون 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

يمكنك الاستفادة من مع البيان.

ورمز الذي يقرأ الملفات إلى القوائم يمكن أن يكون أبسط بشكل كبير

for line in open("q1x.dat", "r"):
    x = map(float,line.split("  ")[1:])
y = map(float, open("q1y.dat", "r").readlines())
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top