59 lines
1.4 KiB
Go
59 lines
1.4 KiB
Go
|
|
package knowledge
|
||
|
|
|
||
|
|
import (
|
||
|
|
"sort"
|
||
|
|
"strings"
|
||
|
|
)
|
||
|
|
|
||
|
|
// RankStringsByIntent sorts phrases by semantic proximity to product + research map.
|
||
|
|
func RankStringsByIntent(items []string, in PatrolTagInput) []string {
|
||
|
|
if len(items) <= 1 {
|
||
|
|
return append([]string{}, items...)
|
||
|
|
}
|
||
|
|
profile := BuildIntentProfile(in)
|
||
|
|
type scored struct {
|
||
|
|
text string
|
||
|
|
score int
|
||
|
|
}
|
||
|
|
scores := make([]scored, 0, len(items))
|
||
|
|
for _, item := range items {
|
||
|
|
item = strings.TrimSpace(item)
|
||
|
|
if item == "" {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
scores = append(scores, scored{
|
||
|
|
text: item,
|
||
|
|
score: ScoreIntentSimilarity(item, profile),
|
||
|
|
})
|
||
|
|
}
|
||
|
|
sort.SliceStable(scores, func(i, j int) bool {
|
||
|
|
if scores[i].score == scores[j].score {
|
||
|
|
return scores[i].text < scores[j].text
|
||
|
|
}
|
||
|
|
return scores[i].score > scores[j].score
|
||
|
|
})
|
||
|
|
out := make([]string, 0, len(scores))
|
||
|
|
for _, item := range scores {
|
||
|
|
out = append(out, item.text)
|
||
|
|
}
|
||
|
|
return out
|
||
|
|
}
|
||
|
|
|
||
|
|
// FilterPatrolKeywordsByIntent drops low-intent patrol keywords from research map output.
|
||
|
|
func FilterPatrolKeywordsByIntent(items []string, in PatrolTagInput, minScore int) []string {
|
||
|
|
if minScore <= 0 {
|
||
|
|
return RankStringsByIntent(items, in)
|
||
|
|
}
|
||
|
|
profile := BuildIntentProfile(in)
|
||
|
|
out := make([]string, 0, len(items))
|
||
|
|
for _, item := range items {
|
||
|
|
item = strings.TrimSpace(item)
|
||
|
|
if item == "" {
|
||
|
|
continue
|
||
|
|
}
|
||
|
|
if ScoreIntentSimilarity(item, profile) >= minScore {
|
||
|
|
out = append(out, item)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return out
|
||
|
|
}
|