验证一下Bayes

来源:互联网 发布:q系列plc编程 编辑:程序博客网 时间:2024/06/10 04:50

以前学概率的时候也没有很在意这个理论,在wiki上看的一个例子,大体的意思是这样的,有一种毒品检验的仪器有百分之一的误差(感觉还可以),也就是,一百个阳性结果中有一个是错误的,一百个阴性的结果中也有一个是错误的,漏网之鱼吧,现在有个公司里面的有千分之五的人是吸毒的(什么公司?),然后用这个仪器挨个检查,根据Bayes的理论,检出阳性的人中应该有百分之六十六是冤枉的。

开始感觉这个数字也太大了,百分之十几二十嘛,还说得过去,于是写了简单的测试程序,结果当然是吻合的,否则人家也不会被写进教科书。

 

 

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class TestBayes {
 public static void main(String[] args){
  
  Company c = new Company(1000000, 5000);
  DrugTester dt = new DrugTester(100, 80);
  dt.test(c);
  c.report();

  System.out.println("Bayes' result: 0.3322");
  
 }
}

class Company{
 int total;
 int user;
 List<Employee> employees;
 
 public Company(int total, int user){
  this.total = total;
  this.user = user;
  
  employees = new ArrayList<Employee>();
  for(int i=0; i<total; i++){
   employees.add(new Employee());
  }
  Random r = new Random(System.currentTimeMillis()*this.hashCode());
  for(int i=0; i<user; i++){
   int lucky = r.nextInt(total);

   if(employees.get(lucky).user == true)i--;
   employees.get(lucky).user = true;
  }
 }
 
 public List<Employee> getEmployees(){
  return employees;
 }
 
 public void report(){
  int userP = 0;
  int noneP = 0;
  
  int userN = 0;
  int noneN = 0;
  
  int P = 0;
  int N = 0;
  
  for(Employee e : employees){
   if(e.result){
    P++;
    if(e.user){
     userP++;  //逮住
    }else{
     noneP++;  //冤枉
    }
   }else{
    N++;
    if(e.user){
     userN ++; //漏网
    }else{
     noneN ++;
    }
   }
  }

  System.out.println("userP: " + userP);
  System.out.println("noneP: " + noneP);
  System.out.println("userN : " + userN);
  System.out.println("noneN: " + noneN);
  System.out.println("P: " + P);
  System.out.println("N: " + N);
  double x = userP;
  
  System.out.println("userP/P: " + x/P);
 }
}


class DrugTester{
 
 int seed = 45;
 int acu = 100;
 
 public DrugTester(int acu ,int seed){
  this.seed = seed;
  this.acu = acu;
 }
 
 public void test(Employee e){
//  Random r = new Random();
  Random r = new Random(System.currentTimeMillis()*e.hashCode());
  
  if(e.user){
   if(seed==r.nextInt(acu)){
    e.result = false;
   }else{
    e.result = true;
   }
   
  }else{
   if(seed==r.nextInt(acu)){
    e.result = true;
   }else{
    e.result = false;
   }
  }
 }

 public void test(Company c){
  for(Employee e : c.getEmployees()){
   test(e);
  }
 }
}

class Employee{
 public boolean user =  false;
 public boolean result = false;
}

 

 

 

运行的结果:

userP: 4941
noneP: 9961
userN : 59
noneN: 985039
P: 14902
N: 985098
userP/P: 0.3315662327204402
Bayes' result: 0.3322

 

事实上问题在于,这个机器百分之一的误差是双向的,它本身就会冤枉好人,一万次检测就有100次是错的,而其中95次是在冤枉好人。

什么时候有空去算算抽烟和肺癌的关系。