Esempio n. 1
0
func (classifier *kNNClassifier) Classify(testRow row.Row) (slice.Slice, error) {
	trainingData := classifier.trainingData
	if trainingData == nil {
		return nil, knnerrors.NewUntrainedClassifierError()
	}

	numTestRowFeatures := testRow.NumFeatures()
	numTrainingDataFeatures := trainingData.NumFeatures()
	if numTestRowFeatures != numTrainingDataFeatures {
		return nil, knnerrors.NewRowLengthMismatchError(numTestRowFeatures, numTrainingDataFeatures)
	}

	testFeatures, ok := testRow.Features().(slice.FloatSlice)
	if !ok {
		return nil, knnerrors.NewNonFloatFeaturesTestRowError()
	}
	testFeatureValues := testFeatures.Values()

	nearestNeighbours := knnutilities.NewKNNTargetCollection(classifier.k)

	for i := 0; i < trainingData.NumRows(); i++ {
		trainingRow, _ := trainingData.Row(i)
		trainingFeatures, _ := trainingRow.Features().(slice.FloatSlice)
		trainingFeatureValues := trainingFeatures.Values()

		distance := knnutilities.Euclidean(testFeatureValues, trainingFeatureValues, nearestNeighbours.MaxDistance())
		if distance < nearestNeighbours.MaxDistance() {
			nearestNeighbours.Insert(trainingRow.Target(), distance)
		}
	}

	return nearestNeighbours.Vote(), nil
}
	"github.com/amitkgupta/goodlearn/data/slice"

	"math"

	. "github.com/onsi/ginkgo"
	. "github.com/onsi/gomega"
)

var _ = Describe("SortedTargetCollection", func() {
	Describe("Insert and MaxDistance", func() {
		var stc knnutilities.SortedTargetCollection
		var target slice.Slice
		var err error

		BeforeEach(func() {
			stc = knnutilities.NewKNNTargetCollection(2)
			target, err = slice.SliceFromRawValues(true, []int{}, []columntype.ColumnType{}, []float64{})
			Ω(err).ShouldNot(HaveOccurred())
		})

		Context("Before the collection is full", func() {
			It("The MaxDistance should be +Inf", func() {
				Ω(stc.MaxDistance()).Should(Equal(math.MaxFloat64))

				stc.Insert(target, 1.0)
				Ω(stc.MaxDistance()).Should(Equal(math.MaxFloat64))
			})
		})

		Context("When the collection is full", func() {
			initialMax := 3.0