ฉันสงสัยว่าได้รับการแจกแจงปกติสองค่าด้วยและ
- ฉันจะคำนวณเปอร์เซ็นต์ของพื้นที่ที่ทับซ้อนกันของการแจกแจงสองแบบได้อย่างไร
- ฉันคิดว่าปัญหานี้มีชื่อเฉพาะคุณทราบชื่อเฉพาะที่อธิบายถึงปัญหานี้หรือไม่?
- คุณทราบหรือไม่ว่ามีการใช้งานสิ่งนี้ (เช่นรหัส Java)?
ฉันสงสัยว่าได้รับการแจกแจงปกติสองค่าด้วยและ
คำตอบ:
นี่ก็มักจะเรียกว่า "สัมประสิทธิ์การทับซ้อนกัน" (OVL) Googling สำหรับสิ่งนี้จะทำให้คุณมีเพลงฮิตมากมาย คุณสามารถค้นหา nomogram สำหรับกรณีที่สองปกติที่นี่ กระดาษที่มีประโยชน์อาจเป็น:
แก้ไข
ตอนนี้คุณทำให้ฉันสนใจสิ่งนี้มากขึ้นดังนั้นฉันจึงไปข้างหน้าและสร้างรหัส R เพื่อคำนวณสิ่งนี้ (เป็นการรวมที่ง่าย) ฉันโยนพล็อตของการแจกแจงสองรายการรวมถึงการแรเงาของพื้นที่ทับซ้อน:
min.f1f2 <- function(x, mu1, mu2, sd1, sd2) {
f1 <- dnorm(x, mean=mu1, sd=sd1)
f2 <- dnorm(x, mean=mu2, sd=sd2)
pmin(f1, f2)
}
mu1 <- 2; sd1 <- 2
mu2 <- 1; sd2 <- 1
xs <- seq(min(mu1 - 3*sd1, mu2 - 3*sd2), max(mu1 + 3*sd1, mu2 + 3*sd2), .01)
f1 <- dnorm(xs, mean=mu1, sd=sd1)
f2 <- dnorm(xs, mean=mu2, sd=sd2)
plot(xs, f1, type="l", ylim=c(0, max(f1,f2)), ylab="density")
lines(xs, f2, lty="dotted")
ys <- min.f1f2(xs, mu1=mu1, mu2=mu2, sd1=sd1, sd2=sd2)
xs <- c(xs, xs[1])
ys <- c(ys, ys[1])
polygon(xs, ys, col="gray")
### only works for sd1 = sd2
SMD <- (mu1-mu2)/sd1
2 * pnorm(-abs(SMD)/2)
### this works in general
integrate(min.f1f2, -Inf, Inf, mu1=mu1, mu2=mu2, sd1=sd1, sd2=sd2)
ตัวอย่างเช่นนี้ผลที่ได้คือ: ด้วยข้อผิดพลาดแน่นอน0.6099324
< 1e-04
รูปด้านล่าง
นี้จะได้รับจากค่าสัมประสิทธิ์ Bhattacharyya สำหรับดิสทริบิวชันอื่น ๆ โปรดดูเวอร์ชันทั่วไปคือระยะทาง Hellinger ระหว่างการแจกแจงสองแบบ
ฉันไม่รู้เกี่ยวกับห้องสมุดใด ๆ ที่จะคำนวณสิ่งนี้ แต่เนื่องจากการกำหนดสูตรที่ชัดเจนในแง่ของระยะทาง Mahalanobis และตัวกำหนดความแปรปรวนของเมทริกซ์การใช้งานไม่ควรเป็นปัญหา
ฉันไม่รู้ว่ามีวิธีมาตรฐานที่ชัดเจนในการทำเช่นนี้ แต่:
ก่อนอื่นคุณจะพบจุดตัดกันระหว่างสองความหนาแน่น สิ่งนี้สามารถทำได้โดยง่ายโดยการเทียบความหนาแน่นทั้งสองซึ่งสำหรับการแจกแจงแบบปกติควรส่งผลให้สมการกำลังสองสำหรับ x
บางสิ่งบางอย่างใกล้กับ:
สามารถแก้ไขได้ด้วยแคลคูลัสเบื้องต้น
ดังนั้นคุณมีจุดศูนย์จุดหนึ่งหรือสองจุด ตอนนี้จุดแยกเหล่านี้แบ่งเส้นจริงเป็น 1, 2 หรือสามส่วนโดยที่ความหนาแน่นสองค่าใดค่าหนึ่งเป็นค่าต่ำสุด หากไม่มีอะไรมาคิดทางคณิตศาสตร์มากขึ้นเพียงแค่ลองจุดใดก็ได้ในส่วนใดส่วนหนึ่งเพื่อค้นหาว่าอันไหนที่ต่ำที่สุด
มูลค่าความสนใจของคุณคือผลรวมของพื้นที่ใต้เส้นโค้งความหนาแน่นต่ำสุดในแต่ละส่วน สามารถหาพื้นที่นี้ได้จากฟังก์ชันการแจกแจงสะสม (เพียงลบค่าในขอบทั้งสองของ 'ส่วน'
สำหรับลูกหลานโซลูชันของ Wolfgang ไม่ได้ผลสำหรับฉัน - ฉันพบข้อบกพร่องในintegrate
ฟังก์ชัน ดังนั้นฉันจึงรวมเข้ากับคำตอบของ Nick Staubbe เพื่อพัฒนาฟังก์ชั่นเล็ก ๆ น้อย ๆ ต่อไปนี้ ควรรวดเร็วและบั๊กกี้น้อยกว่าการใช้การรวมตัวเลข:
get_overlap_coef <- function(mu1, mu2, sd1, sd2){
xs <- seq(min(mu1 - 4*sd1, mu2 - 4*sd2),
max(mu1 + 4*sd1, mu2 + 4*sd2),
length.out = 500)
f1 <- dnorm(xs, mean=mu1, sd=sd1)
f2 <- dnorm(xs, mean=mu2, sd=sd2)
int <- xs[which.max(pmin(f1, f2))]
l <- pnorm(int, mu1, sd1, lower.tail = mu1>mu2)
r <- pnorm(int, mu2, sd2, lower.tail = mu1<mu2)
l+r
}
(l+r)/2
ไหม
นี่คือเวอร์ชัน Java, Apache Commons Mathematics Library :
import org.apache.commons.math3.distribution.NormalDistribution;
public static double overlapArea(double mean1, double sd1, double mean2, double sd2) {
NormalDistribution normalDistribution1 = new NormalDistribution(mean1, sd1);
NormalDistribution normalDistribution2 = new NormalDistribution(mean2, sd2);
double min = Math.min(mean1 - 6 * sd1, mean2 - 6 * sd2);
double max = Math.max(mean1 + 6 * sd1, mean2 + 6 * sd2);
double range = max - min;
int resolution = (int) (range/Math.min(sd1, sd2));
double partwidth = range / resolution;
double intersectionArea = 0;
int begin = (int)((Math.max(mean1 - 6 * sd1, mean2 - 6 * sd2)-min)/partwidth);
int end = (int)((Math.min(mean1 + 6 * sd1, mean2 + 6 * sd2)-min)/partwidth);
/// Divide the range into N partitions
for (int ii = begin; ii < end; ii++) {
double partMin = partwidth * ii;
double partMax = partwidth * (ii + 1);
double areaOfDist1 = normalDistribution1.probability(partMin, partMax);
double areaOfDist2 = normalDistribution2.probability(partMin, partMax);
intersectionArea += Math.min(areaOfDist1, areaOfDist2);
}
return intersectionArea;
}
ฉันคิดว่าสิ่งนี้อาจเป็นวิธีแก้ปัญหาใน MATLAB:
[overlap] = calc_overlap_twonormal(2,2,0,1,-20,20,0.01)
% numerical integral of the overlapping area of two normal distributions:
% s1,s2...sigma of the normal distributions 1 and 2
% mu1,mu2...center of the normal distributions 1 and 2
% xstart,xend,xinterval...defines start, end and interval width
% example: [overlap] = calc_overlap_twonormal(2,2,0,1,-10,10,0.01)
function [overlap2] = calc_overlap_twonormal(s1,s2,mu1,mu2,xstart,xend,xinterval)
clf
x_range=xstart:xinterval:xend;
plot(x_range,[normpdf(x_range,mu1,s1)' normpdf(x_range,mu2,s2)']);
hold on
area(x_range,min([normpdf(x_range,mu1,s1)' normpdf(x_range,mu2,s2)']'));
overlap=cumtrapz(x_range,min([normpdf(x_range,mu1,s1)' normpdf(x_range,mu2,s2)']'));
overlap2 = overlap(end);
[overlap] = calc_overlap_twonormal(2,2,0,1,-10,10,0.01)
อย่างน้อยฉันสามารถทำซ้ำค่า 0.8026 ด้านล่างรูปที่ 1 ในpdfนี้
คุณเพียงแค่ต้องปรับค่าเริ่มต้นและจุดสิ้นสุดและช่วงเวลาเพื่อให้แม่นยำเนื่องจากนี่เป็นเพียงวิธีแก้ปัญหาเชิงตัวเลข