Exemplo n.º 1
0
// LogL returns the per-instance log-likelihood.  Note that the log-likelihood
// of some instances might evaluate to NaN.  LogL will ignore such cases.
func LogL(corpus []*Instance, model *Model) float64 {
	logl := 0.0
	workers := runtime.NumCPU() - 1
	aggr := make(chan float64)
	inst := 0

	var wg sync.WaitGroup
	wg.Add(1)
	go func() {
		for l := range aggr {
			if !math.IsNaN(l) && l > 0 {
				logl += math.Log(l)
				inst++
			}
		}
		wg.Done()
	}()

	parallel.For(0, workers, 1, func(worker int) {
		for i := worker; i < len(corpus); i++ {
			aggr <- Likelihood(corpus[i], model)
		}
	})
	close(aggr)

	wg.Wait()
	if inst == 0 {
		log.Fatalf("All instances have log-likelihood evaluated to NaN.")
	}
	return logl / float64(inst)
}
Exemplo n.º 2
0
func Epoch(corpus []*Instance, N, C int, baseline *Model) *Model {
	estimate := NewModel(N, C)
	workers := runtime.NumCPU() - 1

	aggrγ1 := make(chan []float64)
	aggrΣγ := make(chan []float64)
	aggrΣξ := make(chan [][]float64)
	aggrΣγo := make(chan [][]*Multinomial)

	// TODO(wyi): Use WaitGroup here.
	go func() {
		for γ1 := range aggrγ1 {
			estimate.updateγ1(γ1)
		}
	}()
	go func() {
		for Σγ := range aggrΣγ {
			estimate.updateΣγ(Σγ)
		}
	}()
	go func() {
		for Σξ := range aggrΣξ {
			estimate.updateΣξ(Σξ)
		}
	}()
	go func() {
		for Σγo := range aggrΣγo {
			estimate.updateΣγo(Σγo)
		}
	}()

	parallel.For(0, workers, 1, func(worker int) {
		for i := worker; i < len(corpus); i += workers {
			β := β(corpus[i], baseline)
			γ1, Σγ, Σξ, Σγo := Inference(corpus[i], baseline, β)
			aggrγ1 <- γ1
			aggrΣγ <- Σγ
			aggrΣξ <- Σξ
			aggrΣγo <- Σγo
		}
	})
	close(aggrγ1)
	close(aggrΣγ)
	close(aggrΣξ)
	close(aggrΣγo)

	return estimate
}