Skip to content

Commit ff4916d

Browse files
committed
calculating affinities accounting for some of the wide variance seen
1 parent 8ae7787 commit ff4916d

File tree

1 file changed

+17
-7
lines changed

1 file changed

+17
-7
lines changed

server/src/main/java/org/elasticsearch/search/vectors/AbstractIVFKnnVectorQuery.java

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -173,12 +173,18 @@ public Query rewrite(IndexSearcher indexSearcher) throws IOException {
173173
.mapToDouble(Double::doubleValue)
174174
.toArray();
175175

176-
double averageAffinity = Arrays.stream(affinityScores).average().orElse(Double.NaN);
177-
// max affinity for decreasing visited ratio
178-
double maxAffinity = Arrays.stream(affinityScores).max().orElse(Double.NaN);
179-
double lowerAffinity = (maxAffinity + averageAffinity) * 0.5;
180-
double cutoffAffinity = lowerAffinity * 0.1; // minimum affinity score for a segment to be considered
181-
double affinityThreshold = (maxAffinity + lowerAffinity) * 0.66; // min affinity for increasing visited ratio
176+
177+
double[] filteredAffinityScores = Arrays.stream(affinityScores).filter(x -> Double.isNaN(x) == false &&
178+
Double.isInfinite(x) == false).toArray();
179+
180+
final double averageAffinity = Arrays.stream(filteredAffinityScores).average().orElse(0.0);
181+
double variance = Arrays.stream(filteredAffinityScores).map(x -> (x-averageAffinity) * (x-averageAffinity)).sum() /
182+
filteredAffinityScores.length;
183+
double stdDev = Math.sqrt(variance);
184+
185+
double maxAffinity = averageAffinity + 50 * stdDev;
186+
double cutoffAffinity = averageAffinity - 50 * stdDev;
187+
double affinityThreshold = averageAffinity + stdDev;
182188

183189
float maxAdjustments = visitRatio * 1.5f;
184190

@@ -190,7 +196,11 @@ public Query rewrite(IndexSearcher indexSearcher) throws IOException {
190196
} else {
191197
tasks = new ArrayList<>(segmentAffinities.size());
192198
double scoreVectorsSum = segmentAffinities.stream()
193-
.map(segmentAffinity -> segmentAffinity.affinityScore * segmentAffinity.context.reader().numDocs())
199+
.map(segmentAffinity -> {
200+
double affinity = Double.isNaN(segmentAffinity.affinityScore) ? maxAffinity : segmentAffinity.affinityScore;
201+
affinity = Math.clamp(affinity, 0.0, maxAffinity);
202+
return affinity * segmentAffinity.context.reader().numDocs();
203+
})
194204
.mapToDouble(Double::doubleValue)
195205
.sum();
196206

0 commit comments

Comments
 (0)