2012-02-08 19 views
236

này liên quan đến một câu hỏi trước đó từ phía sau vào tháng:Giảm thiểu NExpectation cho một phân phối tùy chỉnh trong Mathematica

Calculating expectation for a custom distribution in Mathematica

Tôi có một phân phối tùy chỉnh trộn được xác định bằng cách sử dụng phân phối tùy chỉnh thứ hai sau dọc theo dòng thảo luận bởi @Sasha trong một số câu trả lời trong năm qua.

Mã định phân phối sau:

nDist /: CharacteristicFunction[nDist[a_, b_, m_, s_], 
    t_] := (a b E^(I m t - (s^2 t^2)/2))/((I a + t) (-I b + t)); 
nDist /: PDF[nDist[a_, b_, m_, s_], x_] := (1/(2*(a + b)))*a* 
    b*(E^(a*(m + (a*s^2)/2 - x))* Erfc[(m + a*s^2 - x)/(Sqrt[2]*s)] + 
    E^(b*(-m + (b*s^2)/2 + x))* 
     Erfc[(-m + b*s^2 + x)/(Sqrt[2]*s)]); 
nDist /: CDF[nDist[a_, b_, m_, s_], 
    x_] := ((1/(2*(a + b)))*((a + b)*E^(a*x)* 
     Erfc[(m - x)/(Sqrt[2]*s)] - 
     b*E^(a*m + (a^2*s^2)/2)*Erfc[(m + a*s^2 - x)/(Sqrt[2]*s)] + 
     a*E^((-b)*m + (b^2*s^2)/2 + a*x + b*x)* 
     Erfc[(-m + b*s^2 + x)/(Sqrt[2]*s)]))/ E^(a*x);   

nDist /: Quantile[nDist[a_, b_, m_, s_], p_] := 
Module[{x}, 
    x /. FindRoot[CDF[nDist[a, b, m, s], x] == #, {x, m}] & /@ p] /; 
    VectorQ[p, 0 < # < 1 &] 
nDist /: Quantile[nDist[a_, b_, m_, s_], p_] := 
Module[{x}, x /. FindRoot[CDF[nDist[a, b, m, s], x] == p, {x, m}]] /; 
    0 < p < 1 
nDist /: Quantile[nDist[a_, b_, m_, s_], p_] := -Infinity /; p == 0 
nDist /: Quantile[nDist[a_, b_, m_, s_], p_] := Infinity /; p == 1 
nDist /: Mean[nDist[a_, b_, m_, s_]] := 1/a - 1/b + m; 
nDist /: Variance[nDist[a_, b_, m_, s_]] := 1/a^2 + 1/b^2 + s^2; 
nDist /: StandardDeviation[ nDist[a_, b_, m_, s_]] := 
    Sqrt[ 1/a^2 + 1/b^2 + s^2]; 
nDist /: DistributionDomain[nDist[a_, b_, m_, s_]] := 
Interval[{0, Infinity}] 
nDist /: DistributionParameterQ[nDist[a_, b_, m_, s_]] := ! 
    TrueQ[Not[Element[{a, b, s, m}, Reals] && a > 0 && b > 0 && s > 0]] 
nDist /: DistributionParameterAssumptions[nDist[a_, b_, m_, s_]] := 
Element[{a, b, s, m}, Reals] && a > 0 && b > 0 && s > 0 
nDist /: Random`DistributionVector[nDist[a_, b_, m_, s_], n_, prec_] := 

    RandomVariate[ExponentialDistribution[a], n, 
    WorkingPrecision -> prec] - 
    RandomVariate[ExponentialDistribution[b], n, 
    WorkingPrecision -> prec] + 
    RandomVariate[NormalDistribution[m, s], n, 
    WorkingPrecision -> prec]; 

(* Fitting: This uses Mean, central moments 2 and 3 and 4th cumulant \ 
but it often does not provide a solution *) 

nDistParam[data_] := Module[{mn, vv, m3, k4, al, be, m, si}, 
     mn = Mean[data]; 
     vv = CentralMoment[data, 2]; 
     m3 = CentralMoment[data, 3]; 
     k4 = Cumulant[data, 4]; 
     al = 
    ConditionalExpression[ 
    Root[864 - 864 m3 #1^3 - 216 k4 #1^4 + 648 m3^2 #1^6 + 
     36 k4^2 #1^8 - 216 m3^3 #1^9 + (-2 k4^3 + 27 m3^4) #1^12 &, 
     2], k4 > Root[-27 m3^4 + 4 #1^3 &, 1]]; 
     be = ConditionalExpression[ 

    Root[2 Root[ 
      864 - 864 m3 #1^3 - 216 k4 #1^4 + 648 m3^2 #1^6 + 
      36 k4^2 #1^8 - 
      216 m3^3 #1^9 + (-2 k4^3 + 27 m3^4) #1^12 &, 
      2]^3 + (-2 + 
      m3 Root[ 
       864 - 864 m3 #1^3 - 216 k4 #1^4 + 648 m3^2 #1^6 + 
       36 k4^2 #1^8 - 
       216 m3^3 #1^9 + (-2 k4^3 + 27 m3^4) #1^12 &, 
       2]^3) #1^3 &, 1], k4 > Root[-27 m3^4 + 4 #1^3 &, 1]]; 
     m = mn - 1/al + 1/be; 
     si = 
    Sqrt[Abs[-al^-2 - be^-2 + vv ]];(*Ensure positive*) 
     {al, 
    be, m, si}]; 

nDistLL = 
    Compile[{a, b, m, s, {x, _Real, 1}}, 
    Total[Log[ 
    1/(2 (a + 
      b)) a b (E^(a (m + (a s^2)/2 - x)) Erfc[(m + a s^2 - 
      x)/(Sqrt[2] s)] + 
     E^(b (-m + (b s^2)/2 + x)) Erfc[(-m + b s^2 + 
      x)/(Sqrt[2] s)])]](*, CompilationTarget->"C", 
    RuntimeAttributes->{Listable}, Parallelization->True*)]; 

nlloglike[data_, a_?NumericQ, b_?NumericQ, m_?NumericQ, s_?NumericQ] := 
    nDistLL[a, b, m, s, data]; 

nFit[data_] := Module[{a, b, m, s, a0, b0, m0, s0, res}, 

     (* So far have not found a good way to quickly estimate a and \ 
b. Starting assumption is that they both = 2,then m0 ~= 
    Mean and s0 ~= 
    StandardDeviation it seems to work better if a and b are not the \ 
same at start. *) 

    {a0, b0, m0, s0} = nDistParam[data];(*may give Undefined values*) 

    If[! (VectorQ[{a0, b0, m0, s0}, NumericQ] && 
     VectorQ[{a0, b0, s0}, # > 0 &]), 
      m0 = Mean[data]; 
      s0 = StandardDeviation[data]; 
      a0 = 1; 
      b0 = 2;]; 
    res = {a, b, m, s} /. 
    FindMaximum[ 
     nlloglike[data, Abs[a], Abs[b], m, 
     Abs[s]], {{a, a0}, {b, b0}, {m, m0}, {s, s0}}, 
       Method -> "PrincipalAxis"][[2]]; 
     {Abs[res[[1]]], Abs[res[[2]]], res[[3]], Abs[res[[4]]]}]; 

nFit[data_, {a0_, b0_, m0_, s0_}] := Module[{a, b, m, s, res}, 
     res = {a, b, m, s} /. 
    FindMaximum[ 
     nlloglike[data, Abs[a], Abs[b], m, 
     Abs[s]], {{a, a0}, {b, b0}, {m, m0}, {s, s0}}, 
       Method -> "PrincipalAxis"][[2]]; 
     {Abs[res[[1]]], Abs[res[[2]]], res[[3]], Abs[res[[4]]]}]; 

dDist /: PDF[dDist[a_, b_, m_, s_], x_] := 
    PDF[nDist[a, b, m, s], Log[x]]/x; 
dDist /: CDF[dDist[a_, b_, m_, s_], x_] := 
    CDF[nDist[a, b, m, s], Log[x]]; 
dDist /: EstimatedDistribution[data_, dDist[a_, b_, m_, s_]] := 
    dDist[Sequence @@ nFit[Log[data]]]; 
dDist /: EstimatedDistribution[data_, 
    dDist[a_, b_, m_, 
    s_], {{a_, a0_}, {b_, b0_}, {m_, m0_}, {s_, s0_}}] := 
    dDist[Sequence @@ nFit[Log[data], {a0, b0, m0, s0}]]; 
dDist /: Quantile[dDist[a_, b_, m_, s_], p_] := 
Module[{x}, x /. FindRoot[CDF[dDist[a, b, m, s], x] == p, {x, s}]] /; 
    0 < p < 1 
dDist /: Quantile[dDist[a_, b_, m_, s_], p_] := 
Module[{x}, 
    x /. FindRoot[ CDF[dDist[a, b, m, s], x] == #, {x, s}] & /@ p] /; 
    VectorQ[p, 0 < # < 1 &] 
dDist /: Quantile[dDist[a_, b_, m_, s_], p_] := -Infinity /; p == 0 
dDist /: Quantile[dDist[a_, b_, m_, s_], p_] := Infinity /; p == 1 
dDist /: DistributionDomain[dDist[a_, b_, m_, s_]] := 
Interval[{0, Infinity}] 
dDist /: DistributionParameterQ[dDist[a_, b_, m_, s_]] := ! 
    TrueQ[Not[Element[{a, b, s, m}, Reals] && a > 0 && b > 0 && s > 0]] 
dDist /: DistributionParameterAssumptions[dDist[a_, b_, m_, s_]] := 
Element[{a, b, s, m}, Reals] && a > 0 && b > 0 && s > 0 
dDist /: Random`DistributionVector[dDist[a_, b_, m_, s_], n_, prec_] := 
    Exp[RandomVariate[ExponentialDistribution[a], n, 
    WorkingPrecision -> prec] - 
     RandomVariate[ExponentialDistribution[b], n, 
    WorkingPrecision -> prec] + 
    RandomVariate[NormalDistribution[m, s], n, 
    WorkingPrecision -> prec]]; 

Điều này cho phép tôi để phù hợp với các thông số phân phối và tạo PDF củaCDF của. Một ví dụ về các lô:

Plot[PDF[dDist[3.77, 1.34, -2.65, 0.40], x], {x, 0, .3}, 
PlotRange -> All] 
Plot[CDF[dDist[3.77, 1.34, -2.65, 0.40], x], {x, 0, .3}, 
PlotRange -> All] 

enter image description here

Bây giờ tôi đã xác định một function để tính toán tuổi thọ còn lại trung bình (xem this question cho một lời giải thích).

MeanResidualLife[start_, dist_] := 
NExpectation[X \[Conditioned] X > start, X \[Distributed] dist] - 
    start 
MeanResidualLife[start_, limit_, dist_] := 
NExpectation[X \[Conditioned] start <= X <= limit, 
    X \[Distributed] dist] - start 

Việc đầu tiên trong số này không đặt giới hạn như thứ hai mất nhiều thời gian để tính, nhưng cả hai đều hoạt động.

Bây giờ tôi cần tìm mức tối thiểu của hàm MeanResidualLife cho cùng một bản phân phối (hoặc một số biến thể của nó) hoặc giảm thiểu nó.

Tôi đã thử một số biến thể về vấn đề này:

FindMinimum[MeanResidualLife[x, dDist[3.77, 1.34, -2.65, 0.40]], x] 
FindMinimum[MeanResidualLife[x, 1, dDist[3.77, 1.34, -2.65, 0.40]], x] 

NMinimize[{MeanResidualLife[x, dDist[3.77, 1.34, -2.65, 0.40]], 
    0 <= x <= 1}, x] 
NMinimize[{MeanResidualLife[x, 1, dDist[3.77, 1.34, -2.65, 0.40]], 0 <= x <= 1}, x] 

Những hoặc dường như chạy mãi mãi hoặc chạy vào:

điện :: infy: Infinite biểu 1/0. gặp . >>

Chức năng MeanResidualLife áp dụng cho một đơn giản nhưng phân phối hình dạng tương tự cho thấy rằng nó có tối thiểu duy nhất:

Plot[PDF[LogNormalDistribution[1.75, 0.65], x], {x, 0, 30}, 
PlotRange -> All] 
Plot[MeanResidualLife[x, LogNormalDistribution[1.75, 0.65]], {x, 0, 
    30}, 
PlotRange -> {{0, 30}, {4.5, 8}}] 

enter image description here

Ngoài ra cả hai:

FindMinimum[MeanResidualLife[x, LogNormalDistribution[1.75, 0.65]], x] 
FindMinimum[MeanResidualLife[x, 30, LogNormalDistribution[1.75, 0.65]], x] 

Hãy cho tôi câu trả lời (nếu có một loạt các tin nhắn đầu tiên) khi được sử dụng với LogNormalDistribution.

Bất kỳ suy nghĩ nào về cách làm cho tính năng này hoạt động đối với bản phân phối tùy chỉnh được mô tả ở trên?

Tôi có cần thêm ràng buộc hoặc tùy chọn không?

Tôi có cần xác định điều gì đó khác trong định nghĩa của bản phân phối tùy chỉnh không?

Có thể FindMinimum hoặc NMinimize chỉ cần chạy lâu hơn (tôi đã chạy chúng gần một giờ không có lịch phát sóng). Nếu vậy tôi chỉ cần một số cách để tăng tốc độ tìm kiếm tối thiểu của chức năng? Bất kỳ đề xuất về cách thức?

Mathematica có cách nào khác để thực hiện việc này không?

Added 09 Tháng Hai 17:50 EST:

Bất cứ ai cũng có thể tải về trình bày Oleksandr Pavlyk về tạo phân phối trong Mathematica từ Hội nghị Công nghệ Wolfram 2011 hội thảo 'Tạo phân phối riêng của bạn' here. Các bản tải xuống bao gồm sổ ghi chép, 'ExampleOfParametricDistribution.nb' dường như đưa ra tất cả các phần cần thiết để tạo ra một bản phân phối mà người ta có thể sử dụng như các bản phân phối đi kèm với Mathematica.

Nó có thể cung cấp một số câu trả lời.

+9

Không phải chuyên gia về Toán học, nhưng tôi đã gặp phải các vấn đề tương tự ở những nơi khác. Dường như bạn đang gặp sự cố khi miền của bạn bắt đầu ở 0. Hãy thử bắt đầu từ 0,1 trở lên và xem điều gì xảy ra. – Makketronix

+7

@Makketronix - Cảm ơn vì điều này. Hài hước, tôi đã bắt đầu xem lại điều này sau 3 năm. – Jagra

+8

Tôi không chắc chắn tôi có thể giúp bạn nhưng bạn có thể thử hỏi tại [Stackoverflow cụ thể Mathematica] (http://mathematica.stackexchange.com/). May mắn nhất! –

Trả lời

10

Theo tôi thấy, vấn đề là (như bạn đã viết), rằng MeanResidualLife mất một thời gian dài để tính toán, ngay cả đối với một đánh giá duy nhất. Bây giờ, các hàm FindMinimum hoặc tương tự cố gắng tìm mức tối thiểu cho hàm. Tìm tối thiểu yêu cầu hoặc là thiết lập đạo hàm đầu tiên của hàm số 0 và giải quyết một giải pháp. Vì hàm của bạn khá phức tạp (và có lẽ không có khả năng phân biệt), khả năng thứ hai là làm giảm thiểu số, đòi hỏi nhiều đánh giá về hàm của bạn. Ergo, nó rất chậm.

Tôi muốn đề xuất dùng thử mà không cần ma thuật Mathematica.

Trước tiên hãy xem những gì MeanResidualLife là, như bạn đã xác định. NExpectation hoặc Expectation tính toán expected value. Đối với giá trị dự kiến, chúng tôi chỉ cần số PDF của phân phối của bạn. Chúng ta hãy giải nén nó từ định nghĩa của bạn ở trên vào các chức năng đơn giản:

pdf[a_, b_, m_, s_, x_] := (1/(2*(a + b)))*a*b* 
    (E^(a*(m + (a*s^2)/2 - x))*Erfc[(m + a*s^2 - x)/(Sqrt[2]*s)] + 
    E^(b*(-m + (b*s^2)/2 + x))*Erfc[(-m + b*s^2 + x)/(Sqrt[2]*s)]) 
pdf2[a_, b_, m_, s_, x_] := pdf[a, b, m, s, Log[x]]/x; 

Nếu chúng ta vẽ pdf2 nó trông giống hệt như Lô của bạn

Plot[pdf2[3.77, 1.34, -2.65, 0.40, x], {x, 0, .3}] 

Plot of PDF

Bây giờ với giá trị mong đợi. Nếu tôi hiểu chính xác, chúng tôi phải tích hợp x * pdf[x] từ -inf đến +inf để có giá trị dự kiến ​​bình thường.

x * pdf[x] trông giống như

Plot[pdf2[3.77, 1.34, -2.65, 0.40, x]*x, {x, 0, .3}, PlotRange -> All] 

Plot of x * PDF

và giá trị kỳ vọng là

NIntegrate[pdf2[3.77, 1.34, -2.65, 0.40, x]*x, {x, 0, \[Infinity]}] 
Out= 0.0596504 

Nhưng kể từ khi bạn muốn giá trị kỳ vọng giữa một start+inf chúng ta cần phải tích hợp trong phạm vi này và vì PDF sau đó không còn tích hợp thành 1 trong khoảng thời gian nhỏ hơn này, tôi đoán chúng tôi đã hav e để chuẩn hóa kết quả được chia cho tích phân của PDF trong phạm vi này.Vì vậy, tôi đoán cho giá trị kỳ vọng trái-bound là

Và đối với MeanResidualLife bạn trừ start từ nó, cho

MRL[start_] := expVal[start] - start 

Những âm mưu như

Plot[MRL[start], {start, 0, 0.3}, PlotRange -> {0, All}] 

Plot of Mean Residual Life

Có vẻ hợp lý, nhưng tôi không có chuyên gia. Vì vậy, cuối cùng chúng tôi muốn giảm thiểu nó, tức là tìm thấy các start mà chức năng này là một tối thiểu địa phương. Tối thiểu có vẻ là khoảng 0,05, nhưng chúng ta hãy tìm một giá trị chính xác hơn bắt đầu từ đoán rằng

FindMinimum[MRL[start], {start, 0.05}] 

và sau khi một số lỗi (chức năng của bạn không được định nghĩa dưới 0, vì vậy tôi đoán minimizer chọc một chút trong cấm mà vùng) chúng tôi nhận

{0,0418137, {bắt đầu -> 0,0584312}}

Vì vậy, tối ưu nên có ít start = 0.0584312 với một cuộc sống dư trung bình của 0.0418137.

Tôi không biết điều này có đúng hay không nhưng có vẻ hợp lý.

+0

+1 - Chỉ cần nhìn thấy điều này vì vậy tôi sẽ cần phải làm việc thông qua nó, nhưng tôi nghĩ rằng cách bạn chia đưa vấn đề vào các bước có thể giải quyết được rất nhiều ý nghĩa. Ngoài ra, cốt truyện của chức năng MRL của bạn, chắc chắn trông tại chỗ. Rất cám ơn, tôi sẽ quay lại với điều này ngay sau khi tôi có thể dành thời gian để nghiên cứu câu trả lời của bạn. – Jagra