74 lines
2.8 KiB
C#
74 lines
2.8 KiB
C#
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}");
|
|
}
|
|
}
|