Spaces:
Running
Running
// _ _ | |
// __ _____ __ ___ ___ __ _| |_ ___ | |
// \ \ /\ / / _ \/ _` \ \ / / |/ _` | __/ _ \ | |
// \ V V / __/ (_| |\ V /| | (_| | || __/ | |
// \_/\_/ \___|\__,_| \_/ |_|\__,_|\__\___| | |
// | |
// Copyright © 2016 - 2024 Weaviate B.V. All rights reserved. | |
// | |
// CONTACT: [email protected] | |
// | |
package sempath | |
import ( | |
"context" | |
"testing" | |
"github.com/stretchr/testify/assert" | |
"github.com/stretchr/testify/require" | |
"github.com/weaviate/weaviate/entities/search" | |
txt2vecmodels "github.com/weaviate/weaviate/modules/text2vec-contextionary/additional/models" | |
) | |
func TestSemanticPathBuilder(t *testing.T) { | |
t.Skip("go1.20 change") | |
c11y := &fakeC11y{} | |
b := New(c11y) | |
b.fixedSeed = 1000 // control randomness in unit test | |
input := []search.Result{ | |
{ | |
ID: "7fe919ed-2ef6-4087-856c-a307046bf895", | |
ClassName: "Foo", | |
Vector: []float32{1, 0.1}, | |
}, | |
} | |
searchVector := []float32{0.3, 0.3} | |
c11y.neighbors = []*txt2vecmodels.NearestNeighbors{ | |
{ | |
Neighbors: []*txt2vecmodels.NearestNeighbor{ | |
{ | |
Concept: "good1", | |
Vector: []float32{0.5, 0.1}, | |
}, | |
{ | |
Concept: "good2", | |
Vector: []float32{0.7, 0.2}, | |
}, | |
{ | |
Concept: "good3", | |
Vector: []float32{0.9, 0.1}, | |
}, | |
{ | |
Concept: "good4", | |
Vector: []float32{0.55, 0.1}, | |
}, | |
{ | |
Concept: "good5", | |
Vector: []float32{0.77, 0.2}, | |
}, | |
{ | |
Concept: "good6", | |
Vector: []float32{0.99, 0.1}, | |
}, | |
{ | |
Concept: "bad1", | |
Vector: []float32{-0.1, -3}, | |
}, | |
{ | |
Concept: "bad2", | |
Vector: []float32{-0.15, -2.75}, | |
}, | |
{ | |
Concept: "bad3", | |
Vector: []float32{-0.22, -2.35}, | |
}, | |
{ | |
Concept: "bad4", | |
Vector: []float32{0.1, -3.3}, | |
}, | |
{ | |
Concept: "bad5", | |
Vector: []float32{0.15, -2.5}, | |
}, | |
{ | |
Concept: "bad6", | |
Vector: []float32{-0.4, -2.25}, | |
}, | |
}, | |
}, | |
} | |
res, err := b.CalculatePath(input, &Params{SearchVector: searchVector}) | |
require.Nil(t, err) | |
expectedPath := &txt2vecmodels.SemanticPath{ | |
Path: []*txt2vecmodels.SemanticPathElement{ | |
{ | |
Concept: "good5", | |
DistanceToNext: ptFloat32(0.00029218197), | |
DistanceToQuery: 0.13783735, | |
DistanceToResult: 0.011904657, | |
}, | |
{ | |
Concept: "good2", | |
DistanceToNext: ptFloat32(0.014019072), | |
DistanceToPrevious: ptFloat32(0.00029218197), | |
DistanceToQuery: 0.12584269, | |
DistanceToResult: 0.015912116, | |
}, | |
{ | |
Concept: "good3", | |
DistanceToNext: ptFloat32(4.9889088e-05), | |
DistanceToPrevious: ptFloat32(0.014019072), | |
DistanceToQuery: 0.21913117, | |
DistanceToResult: 6.0379505e-05, | |
}, | |
{ | |
Concept: "good6", | |
DistanceToNext: ptFloat32(0.0046744347), | |
DistanceToPrevious: ptFloat32(4.9889088e-05), | |
DistanceToQuery: 0.2254098, | |
DistanceToResult: 5.364418e-07, | |
}, | |
{ | |
Concept: "good1", | |
DistanceToNext: ptFloat32(0.00015383959), | |
DistanceToPrevious: ptFloat32(0.0046744347), | |
DistanceToQuery: 0.16794968, | |
DistanceToResult: 0.004771471, | |
}, | |
{ | |
Concept: "good4", | |
DistanceToPrevious: ptFloat32(0.00015383959), | |
DistanceToQuery: 0.17780781, | |
DistanceToResult: 0.003213048, | |
}, | |
}, | |
} | |
require.Len(t, res, 1) | |
require.NotNil(t, res[0].AdditionalProperties) | |
semanticPath, semanticPathOK := res[0].AdditionalProperties["semanticPath"] | |
assert.True(t, semanticPathOK) | |
semanticPathElement, semanticPathElementOK := semanticPath.(*txt2vecmodels.SemanticPath) | |
assert.True(t, semanticPathElementOK) | |
assert.Equal(t, expectedPath, semanticPathElement) | |
} | |
type fakeC11y struct { | |
neighbors []*txt2vecmodels.NearestNeighbors | |
} | |
func (f *fakeC11y) MultiNearestWordsByVector(ctx context.Context, vectors [][]float32, k, n int) ([]*txt2vecmodels.NearestNeighbors, error) { | |
return f.neighbors, nil | |
} | |
func ptFloat32(in float32) *float32 { | |
return &in | |
} | |