Python vs Julia tự tương quan


19

Tôi đang cố gắng thực hiện tự động bằng cách sử dụng Julia và so sánh nó với kết quả của Python. Làm thế nào mà họ cho kết quả khác nhau?

Mã Julia

using StatsBase

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

acf = StatsBase.autocor(test_data)

cho

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

Mã Python

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)

cho

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

1
In dữ liệu thử nghiệm trong cả hai trường hợp
Mad Physicist

Câu trả lời:


26

Điều này là do bạn test_datakhác biệt:

Con trăn

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

Julia:

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

Điều này xảy ra bởi vì bạn đang lấy sinsố lượng rất lớn. Ví dụ: với số cuối cùng tlà 10,exp(10^2) là ~ 2,7 * 10 ^ 43. Ở quy mô này, độ chính xác của dấu phẩy động là khoảng 3 * 10 ^ 9. Vì vậy, nếu ngay cả bit có ý nghĩa nhỏ nhất là khác nhau đối với Python và Julia, singiá trị sẽ bị giảm.

Trong thực tế, chúng ta có thể kiểm tra các giá trị nhị phân cơ bản của mảng ban đầu t . Ví dụ: chúng khác nhau ở giá trị cuối cùng thứ ba:

Julia:

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

Con trăn

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

Chúng ta thực sự có thể thấy rằng họ không đồng ý bởi chính xác một máy epsilon. Và nếu chúng ta sử dụng Julia, hãy lấy singiá trị mà Python thu được:

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

Chúng tôi nhận được cùng một giá trị Python làm.


9

Chỉ cần mở rộng một chút về câu trả lời (thêm dưới dạng câu trả lời vì nó quá dài cho một nhận xét). Trong Julia bạn có những điều sau đây:

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

trong khi ở Python:

>>> 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])

và bạn thấy rằng số thứ 8 trong Python là một xấp xỉ không chính xác 70/9, trong khi ở Julia trong trường hợp này bạn có được chuỗi các xấp xỉ gần nhất của 10*i/9việc sử dụng Float64.

Vì vậy, có vẻ như bởi vì các trình tự ban đầu khác nhau, phần còn lại tuân theo những gì @Jakob Nissen nhận xét.

Tuy nhiên mọi thứ không đơn giản. Vì các exphàm trong Julia và Python khác nhau một chút trong những gì chúng tạo ra. Xem Python:

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

trong khi ở Julia:

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

(bạn có thể kiểm tra xem có (20/3)^2giống nhau Float64ở cả Julia và Python không).

Vì vậy, trong trường hợp này với expPython thì chính xác hơn Julia một chút. Do đó, ngay cả sửa lỗi t(dễ dàng bằng cách sử dụng một sự hiểu biết trong Python thay vìlinspace ) sẽ không làm cho ACF bằng nhau.

Tất cả trong tất cả các kết luận là những gì @Jakob Nissen nhận xét cho các giá trị lớn như vậy, kết quả sẽ bị ảnh hưởng mạnh mẽ bởi sự không chính xác về số.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.