test(backend): add matchmaking relevance and ranking tests
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
using TarninaHub.Application.Matchmaking;
|
||||
|
||||
namespace TarninaHub.Tests.Matchmaking;
|
||||
|
||||
/// <summary>
|
||||
/// Relevance test set for semantic matchmaking. Measures top-1 accuracy,
|
||||
/// precision@3 and recall@3 over a small synthetic corpus (matches the
|
||||
/// demo dataset vocabulary).
|
||||
/// </summary>
|
||||
public class MatchmakingQualityTests
|
||||
{
|
||||
private static readonly (string Id, string Text)[] Documents =
|
||||
[
|
||||
("klub", "klub sąsiedzki seniorzy spotkania samotność izolacja"),
|
||||
("praca", "praca wspierana niepełnosprawność zatrudnienie doradca"),
|
||||
("hostel", "hostel aktywizacyjny młodzież bezdomność usamodzielnianie"),
|
||||
("psych", "wsparcie psychiczne młodzież szkoła profilaktyka"),
|
||||
("ubostwo", "ubóstwo energetyczne żywność spizarnia seniorzy"),
|
||||
("integracja", "asysta kulturowa cudzoziemcy integracja język"),
|
||||
("rodzina", "rodzina zastępcza rodzeństwo piecza wsparcie"),
|
||||
("cyfryzacja", "cyfryzacja seniorzy internet szkolenie obsługa"),
|
||||
];
|
||||
|
||||
private static readonly (string Query, string Expected)[] Queries =
|
||||
[
|
||||
("seniorzy spotkania samotność", "klub"),
|
||||
("praca niepełnosprawność doradca", "praca"),
|
||||
("hostel młodzież bezdomność", "hostel"),
|
||||
("psychiczne młodzież szkoła", "psych"),
|
||||
("ubóstwo energetyczne spizarnia", "ubostwo"),
|
||||
("asysta kulturowa integracja", "integracja"),
|
||||
("rodzina zastępcza rodzeństwo", "rodzina"),
|
||||
("cyfryzacja seniorzy internet", "cyfryzacja"),
|
||||
];
|
||||
|
||||
[Fact]
|
||||
public void Matchmaking_MeetsRelevanceThresholds()
|
||||
{
|
||||
var provider = new HashingEmbeddingProvider();
|
||||
var vectors = Documents
|
||||
.Select(document => (document.Id, Vector: (IReadOnlyList<float>)provider.Embed(document.Text)))
|
||||
.ToList();
|
||||
|
||||
var top1Correct = 0;
|
||||
var recallAt3 = 0;
|
||||
var precisionSum = 0.0;
|
||||
|
||||
foreach (var (query, expected) in Queries)
|
||||
{
|
||||
var ranked = SemanticRanker.Rank(provider.Embed(query), vectors, topK: 3);
|
||||
|
||||
if (ranked.Count > 0 && ranked[0].Item == expected)
|
||||
{
|
||||
top1Correct++;
|
||||
}
|
||||
|
||||
if (ranked.Any(item => item.Item == expected))
|
||||
{
|
||||
recallAt3++;
|
||||
}
|
||||
|
||||
precisionSum += ranked.Count(item => item.Item == expected) / 3.0;
|
||||
}
|
||||
|
||||
var top1Accuracy = (double)top1Correct / Queries.Length;
|
||||
var recall = (double)recallAt3 / Queries.Length;
|
||||
var meanPrecision = precisionSum / Queries.Length;
|
||||
|
||||
Assert.True(top1Accuracy >= 0.75, $"top-1 accuracy was {top1Accuracy:P0}");
|
||||
Assert.True(recall >= 0.9, $"recall@3 was {recall:P0}");
|
||||
Assert.True(meanPrecision >= 0.3, $"precision@3 was {meanPrecision:P0}");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user