Example #1
0
func (l *LightLOF) add(v nearest.FeatureVector) ID {
	var nnID nearest.ID
	if len(l.kdists) <= l.maxSize {
		l.kdists = append(l.kdists, 0)
		l.lrds = append(l.lrds, 0)
		nnID = nearest.ID(len(l.kdists))
	} else {
		// unlearn
		nnID = nearest.ID(l.rg.Intn(l.maxSize)) + 1
		l.kdists[nnID-1] = 0
		l.lrds[nnID-1] = 0
	}
	l.nn.SetRow(nnID, v)

	neighbors := l.nn.NeighborRowFromID(nnID, l.rnnNum)

	nestedNeighbors := map[ID][]nearest.IDist{}
	for i := range neighbors {
		nnID := neighbors[i].ID
		id := ID(nnID)
		nnResult := l.nn.NeighborRowFromID(nnID, l.nnNum)
		nestedNeighbors[id] = nnResult
		l.kdists[id-1] = nnResult[len(nnResult)-1].Dist
	}

	for i := range neighbors {
		nnID := neighbors[i].ID
		id := ID(nnID)
		nn := nestedNeighbors[id]
		var lrd float32 = 1
		if len(nn) > 0 {
			length := minInt(len(nn), l.nnNum)
			var sumReachability float32
			for i := 0; i < length; i++ {
				sumReachability += maxFloat32(nn[i].Dist, l.kdists[nn[i].ID-1])
			}
			if sumReachability == 0 {
				lrd = inf32
			} else {
				lrd = float32(length) / sumReachability
			}
		}
		l.lrds[id-1] = lrd
	}

	return ID(nnID)
}
Example #2
0
func (l *LightLOF) collectLRDsByID(id ID) (float32, []float32) {
	nnID := nearest.ID(id)
	neighbors := l.nn.NeighborRowFromID(nearest.ID(id), l.nnNum+1)
	if len(neighbors) == 0 {
		return inf32, nil
	}
	for i := range neighbors {
		if neighbors[i].ID == nnID {
			copy(neighbors[1:i+1], neighbors[0:])
			neighbors = neighbors[1:]
			break
		}
	}
	if len(neighbors) > l.nnNum {
		neighbors = neighbors[:l.nnNum]
	}
	if len(neighbors) == 0 {
		return inf32, nil
	}

	return l.collectLRDsImpl(neighbors)
}