Class CommonalityRankingStrategy
- All Implemented Interfaces:
AnnotationSearchRankingStrategy
This asks a different question from UsageWeightedRankingStrategy. A usage count is
about the TERM — how much does Gemma use this URI at all — and answers "which compound is
meant". The per-string prior is about the STRING: of everyone who actually wrote the words being
searched for, how many meant each candidate. On the production corpus a search for dmso
finds that 508 experiments writing "DMSO" meant the compound and 16 meant
reference substance role, which separates them even though both are legitimate hits and
both terms are well used in their own right.
Score: rankWeight * (1 / (1 + originalRank)) + priorWeight * priorScore(prior, maxPrior)
- shapeWeight * designationPenalty(label). Higher sorts earlier; ties resolve by original
Lucene rank ascending, so the strategy is stable and never reorders hits it cannot separate.
The prior is scored relative to the strongest candidate in the same result set — see
priorScore(int, int) for why an absolute scale cannot work here.
Two constraints the measurement imposed
- It is a frequency comparison, not a preference for synonyms. The tempting
shortcut — prefer whichever string is a synonym rather than the preferred label — is wrong:
DMSO(508) beats the labeldimethyl sulfoxide, butEtOH(38) LOSES to the labelethanol(65). Only the counts can tell those apart, so only the counts are consulted. - A compound nobody has curated scores zero everywhere. Corpus frequency is
silent on a drug the corpus has never seen — the case that matters most when annotating
something for the first time. Rather than let a zero-information tie fall through to URI
string order,
designationPenalty(String)demotes labels shaped like systematic chemical names, which nobody writes when they mean the drug.
Purely numeric query strings never reach here with a populated prior: a count of 24
pools unrelated doses, timepoints and replicate numbers, so the tally is refused at the DAO.
The prior is corpus curation history, so it reflects whatever is in the database, escrowed
experiments included. That is the same footing as ?rank=usage and fine for ordering a
live search; it is NOT a held-out signal and must not be treated as one when measuring a
resolver against an escrow.
-
Field Summary
Fields -
Constructor Summary
ConstructorsConstructorDescriptionCommonalityRankingStrategy(double rankWeight, double priorWeight) Convenience constructor pinning the shape weight to the production default.CommonalityRankingStrategy(double rankWeight, double priorWeight, double shapeWeight) -
Method Summary
Modifier and TypeMethodDescriptiongetName()Short stable name used as the value of the?rank=query parameter and as the bean name in the strategy registry.rank(String originalQuery, List<CharacteristicValueObject> rawHits, Map<String, Integer> usageCountsByUri) Re-orderrawHitsaccording to this strategy.rank(String originalQuery, List<CharacteristicValueObject> rawHits, Map<String, Integer> usageCountsByUri, Map<String, Integer> stringPriorByUri) Re-orderrawHitswith the per-string corpus prior available in addition to the usage counts.booleanWhether this strategy reads thestringPriorByUrimap duringAnnotationSearchRankingStrategy.rank(String, List, Map).Methods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface AnnotationSearchRankingStrategy
rank, requiresUsageCounts
-
Field Details
-
NAME
- See Also:
-
-
Constructor Details
-
CommonalityRankingStrategy
@Autowired public CommonalityRankingStrategy(@Value("${gemma.rest.annotationSearch.commonality.rankWeight:0.35}") double rankWeight, @Value("${gemma.rest.annotationSearch.commonality.priorWeight:0.65}") double priorWeight, @Value("${gemma.rest.annotationSearch.commonality.shapeWeight:0.25}") double shapeWeight) -
CommonalityRankingStrategy
public CommonalityRankingStrategy(double rankWeight, double priorWeight) Convenience constructor pinning the shape weight to the production default. For tests and callers that only care about the rank/prior balance.
-
-
Method Details
-
rank
public List<CharacteristicValueObject> rank(String originalQuery, List<CharacteristicValueObject> rawHits, Map<String, Integer> usageCountsByUri) Description copied from interface:AnnotationSearchRankingStrategyRe-orderrawHitsaccording to this strategy.- Specified by:
rankin interfaceAnnotationSearchRankingStrategy- Parameters:
originalQuery- the original query string the user typed; whitespace-tokenised and lowercased by token-coverage strategies; may be blank.rawHits- the Lucene-ordered hits; index in this list is the "original rank" used by rank-aware strategies. Must not be mutated.usageCountsByUri- per-URI count of distinct experiments referencing the URI; may be empty.- Returns:
- a new list of the same hits in the desired display order.
-
rank
public List<CharacteristicValueObject> rank(String originalQuery, List<CharacteristicValueObject> rawHits, Map<String, Integer> usageCountsByUri, Map<String, Integer> stringPriorByUri) Description copied from interface:AnnotationSearchRankingStrategyRe-orderrawHitswith the per-string corpus prior available in addition to the usage counts.Callers should invoke this overload; it defaults to the three-argument
AnnotationSearchRankingStrategy.rank(String, List, Map)so a strategy that has no use for the prior needs no changes. Only strategies that returntruefromAnnotationSearchRankingStrategy.requiresStringPrior()receive a populated map.- Specified by:
rankin interfaceAnnotationSearchRankingStrategy- Parameters:
stringPriorByUri- per-URI count of distinct experiments on which a prior curator wrote the query string itself as the annotation's original value; may be empty. Distinct fromusageCountsByUri, which counts every use of the URI regardless of what was written.
-
getName
Description copied from interface:AnnotationSearchRankingStrategyShort stable name used as the value of the?rank=query parameter and as the bean name in the strategy registry. Lowercase, single word.- Specified by:
getNamein interfaceAnnotationSearchRankingStrategy
-
requiresStringPrior
public boolean requiresStringPrior()Description copied from interface:AnnotationSearchRankingStrategyWhether this strategy reads thestringPriorByUrimap duringAnnotationSearchRankingStrategy.rank(String, List, Map). Defaultfalse;CommonalityRankingStrategyoverrides totrue.Kept separate from
AnnotationSearchRankingStrategy.requiresUsageCounts()rather than folded into one "needs corpus stats" flag because the two queries have different costs and answer different questions: a strategy that wants the per-string prior should not be made to pay for the usage scan, or the other way round.- Specified by:
requiresStringPriorin interfaceAnnotationSearchRankingStrategy
-