Python vs Julia autocorrelation


19

ฉันกำลังพยายามทำออโตคอร์เรเลชันโดยใช้ Julia และเปรียบเทียบกับผลลัพธ์ของ Python ทำไมพวกเขาถึงให้ผลลัพธ์ที่แตกต่างกัน?

รหัสจูเลีย

using StatsBase

t = range(0, stop=10, length=10)
test_data = sin.(exp.(t.^2))

acf = StatsBase.autocor(test_data)

จะช่วยให้

10-element Array{Float64,1}:
  1.0                   
  0.13254954979179642   
 -0.2030283419321465    
  0.00029587850872956104
 -0.06629381497277881   
  0.031309038331589614  
 -0.16633393452504994   
 -0.08482388975165675   
  0.0006905628640697538 
 -0.1443650483145533

รหัสหลาม

from statsmodels.tsa.stattools import acf
import numpy as np

t = np.linspace(0,10,10)
test_data = np.sin(np.exp(t**2))

acf_result = acf(test_data)

จะช่วยให้

array([ 1.        ,  0.14589844, -0.10412699,  0.07817509, -0.12916543,
       -0.03469143, -0.129255  , -0.15982435, -0.02067688, -0.14633346])

1
พิมพ์ข้อมูลทดสอบในทั้งสองกรณี
Mad Physicist

คำตอบ:


26

นี่เป็นเพราะคุณtest_dataแตกต่าง:

งูหลาม:

array([ 0.84147098, -0.29102733,  0.96323736,  0.75441021, -0.37291918,
        0.85600145,  0.89676529, -0.34006519, -0.75811102, -0.99910501])

จูเลีย:

[0.8414709848078965, -0.2910273263243299, 0.963237364649543, 0.7544102058854344,
 -0.3729191776326039, 0.8560014512776061, 0.9841238290665676, 0.1665709194875013,
 -0.7581110212957692, -0.9991050130774393]

สิ่งนี้เกิดขึ้นเพราะคุณรับsinจำนวนมหาศาล ตัวอย่างเช่นเมื่อตัวเลขสุดท้ายtเป็น 10 exp(10^2)เท่ากับ ~ 2.7 * 10 ^ 43 ในระดับนี้ความคลาดเคลื่อนของจุดลอยตัวอยู่ที่ประมาณ 3 * 10 ^ 9 ดังนั้นแม้ว่าบิตที่มีนัยสำคัญน้อยที่สุดจะแตกต่างกันไปสำหรับ Python และ Julia sinค่าจะหลุดไป

tในความเป็นจริงเราสามารถตรวจสอบที่อยู่ภายใต้ค่าไบนารีของอาร์เรย์เริ่มต้น ตัวอย่างเช่นพวกเขาแตกต่างกันในค่าสุดท้ายที่สาม:

จูเลีย:

julia> reinterpret(Int, range(0, stop=10, length=10)[end-2])
4620443017702830535

งูหลาม:

>>> import struct
>>> s = struct.pack('>d', np.linspace(0,10,10)[-3])
>>> struct.unpack('>q', s)[0]
4620443017702830536

เราสามารถเห็นได้ว่าพวกเขาไม่เห็นด้วยโดย epsilon หนึ่งเครื่อง และถ้าเราใช้ Julia รับsinค่าที่ Python ได้รับ:

julia> sin(exp(reinterpret(Float64, 4620443017702830536)^2))
-0.3400651855865199

เราได้รับค่าเดียวกันกับที่ไพ ธ อนทำ


9

เพียงเพื่อขยายคำตอบเล็กน้อย (เพิ่มเป็นคำตอบเพราะยาวเกินไปสำหรับความคิดเห็น) ใน Julia คุณมีสิ่งต่อไปนี้:

julia> t = collect(range(0, stop=10, length=10))
10-element Array{Float64,1}:
  0.0               
  1.1111111111111112
  2.2222222222222223
  3.3333333333333335
  4.444444444444445 
  5.555555555555555 
  6.666666666666667 
  7.777777777777778 
  8.88888888888889  
 10.0               

julia> t .- [10*i / 9 for i in 0:9]
10-element Array{Float64,1}:
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0
 0.0

ในขณะที่อยู่ในหลาม:

>>> t = np.linspace(0,10,10)
>>> t - [10*i/9 for i in range(10)]
array([0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 0.0000000e+00,
       0.0000000e+00, 0.0000000e+00, 0.0000000e+00, 8.8817842e-16,
       0.0000000e+00, 0.0000000e+00])

และคุณจะเห็นว่าจำนวน 8 TH ในหลามเป็นประมาณไม่ถูกต้องของ70/9ในขณะที่จูเลียในกรณีนี้คุณจะได้รับลำดับของการประมาณที่ใกล้เคียงที่สุดของการใช้10*i/9Float64

ดังนั้นดูเหมือนว่าเพราะลำดับต้นฉบับทำให้คุณแตกต่างจากที่เหลือตามด้วย @Jakob Nissen แสดงความคิดเห็น

อย่างไรก็ตามสิ่งต่าง ๆ นั้นไม่ง่ายเลย เมื่อexpฟังก์ชั่นใน Julia และ Python แตกต่างกันเล็กน้อยในสิ่งที่พวกมันสร้างขึ้น ดู Python:

>>> from math import exp
>>> from mpmath import mp
>>> mp.dps = 1000
>>> float(mp.exp((20/3)**2) - exp((20/3)**2))
-1957.096392544307

ในขณะที่จูเลีย:

julia> setprecision(1000)
1000

julia> Float64(exp(big((20/3)^2)) - exp((20/3)^2))
2138.903607455693

julia> Float64(exp(big((20/3)^2)) - nextfloat(exp((20/3)^2)))
-1957.096392544307

(คุณสามารถตรวจสอบได้ว่า(20/3)^2เหมือนกันFloat64ทั้งใน Julia และ Python)

ดังนั้นในกรณีนี้ด้วยexpPython จะแม่นยำกว่า Julia เล็กน้อย ดังนั้นแม้การแก้ไขt(ซึ่งง่ายโดยใช้ความเข้าใจใน Python แทนlinspace) จะไม่ทำให้ ACF เท่ากัน

สรุปทั้งหมดคือสิ่งที่ @Jakob Nissen แสดงความคิดเห็นสำหรับค่าที่มีขนาดใหญ่เช่นนี้ผลลัพธ์จะได้รับอิทธิพลอย่างมากจากความไม่ถูกต้องเชิงตัวเลข

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.