2012-12-05 31 views
5

Tôi đang cố gắng sao chép một số mã của tôi trong MATLAB sang python. Tôi tìm thấy hàm lượng tử trong MATLAB không có một "chính xác" tương ứng trong python. Những gì tôi tìm thấy gần nhất là mquantiles của python. ví dụ.lệnh python đẳng cấp cho định lượng trong MATLAB

cho matlab:

quantile([ 8.60789925e-05, 1.98989354e-05 , 1.68308882e-04, 1.69379370e-04], 0.8) 

cho: 0.00016958

cho python:

scipy.stats.mstats.mquantiles([8.60789925e-05, 1.98989354e-05, 1.68308882e-04, 1.69379370e-04], 0.8) 

cho 0.00016912

Có ai biết làm thế nào để chính xác tái tạo quantile matlab không? cảm ơn rất nhiều.

Trả lời

4

Vectơ đầu vào của bạn chỉ có 4 giá trị, quá ít để có được xấp xỉ tốt về số lượng của phân phối cơ bản. Sự khác biệt có lẽ là kết quả của Matlab và SciPy sử dụng các chẩn đoán khác nhau để tính toán lượng tử trên các bản phân phối được lấy mẫu.

+4

Tại sao bạn nên downvote? Nếu có vấn đề với câu trả lời của tôi, tôi rất muốn biết nó là gì. – slayton

4

documentation for quantile (trong phần Giới thiệu thêm>> Thuật toán) cung cấp thuật toán chính xác được sử dụng. Dưới đây là một số mã python nào đó cho một quantile duy nhất cho một mảng phẳng, sử dụng bottleneck để làm phân loại từng phần:

import numpy as np 
import botteleneck as bn 

def quantile(a, prob): 
    """ 
    Estimates the prob'th quantile of the values in a data array. 

    Uses the algorithm of matlab's quantile(), namely: 
     - Remove any nan values 
     - Take the sorted data as the (.5/n), (1.5/n), ..., (1-.5/n) quantiles. 
     - Use linear interpolation for values between (.5/n) and (1 - .5/n). 
     - Use the minimum or maximum for quantiles outside that range. 

    See also: scipy.stats.mstats.mquantiles 
    """ 
    a = np.asanyarray(a) 
    a = a[np.logical_not(np.isnan(a))].ravel() 
    n = a.size 

    if prob >= 1 - .5/n: 
     return a.max() 
    elif prob <= .5/n: 
     return a.min() 

    # find the two bounds we're interpreting between: 
    # that is, find i such that (i+.5)/n <= prob <= (i+1.5)/n 
    t = n * prob - .5 
    i = np.floor(t) 

    # partial sort so that the ith element is at position i, with bigger ones 
    # to the right and smaller to the left 
    a = bn.partsort(a, i) 

    if i == t: # did we luck out and get an integer index? 
     return a[i] 
    else: 
     # we'll linearly interpolate between this and the next index 
     smaller = a[i] 
     larger = a[i+1:].min() 
     if np.isinf(smaller): 
      return smaller # avoid inf - inf 
     return smaller + (larger - smaller) * (t - i) 

Tôi chỉ làm những đơn quantile, trường hợp 1d vì đó là tất cả những gì cần thiết. Nếu bạn muốn một số lượng tử, nó có thể đáng giá chỉ làm đủ loại; để làm điều đó trên mỗi trục và biết bạn không có bất kỳ lệnh cấm nào, tất cả những gì bạn cần làm là thêm đối số trục vào sắp xếp và vector hóa bit nội suy tuyến tính. Làm cho nó trên mỗi trục với nans sẽ là một chút phức tạp hơn.

Mã này cung cấp cho:

>>> quantile([ 8.60789925e-05, 1.98989354e-05 , 1.68308882e-04, 1.69379370e-04], 0.8) 
0.00016905822360000001 

và mã MATLAB cho 0.00016905822359999999; sự khác biệt là 3e-20. (ít hơn độ chính xác của máy)

3

Một chút trễ, nhưng:

mquantiles rất linh hoạt. Bạn chỉ cần cung cấp các tham số alphap và betap. Ở đây, vì MATLAB thực hiện phép nội suy tuyến tính, bạn cần đặt tham số thành (0.5,0.5).

In [9]: scipy.stats.mstats.mquantiles([8.60789925e-05, 1.98989354e-05, 1.68308882e-04, 1.69379370e-04], 0.8, alphap=0.5, betap=0.5) 

EDIT: MATLAB nói rằng nó làm suy tuyến tính, tuy nhiên có vẻ như nó tính toán quantile thông qua nội suy tuyến tính mảnh-khôn ngoan, đó là tương đương với Gõ 5 quantile trong R, và (0.5, 0.5) trong scipy.

Các vấn đề liên quan