github.com/agnivade/levenshtein 是 golang 中计算字符串编辑距离最省事、轻量无依赖的方案;需归一化得相似度,空字符串和预处理(trim、小写)易出错;中文推荐 gse 分词 + cosine 向量化,注意词典一致性与向量转换。

用 github.com/agnivade/levenshtein 算字符串编辑距离最省事
Levenshtein 距离是文本相似度最基础、最稳的起点,Golang 没原生函数,但 github.com/agnivade/levenshtein 这个包轻量、无依赖、API 干净。别自己手写——边界处理和性能优化容易出错。
常见错误是直接拿返回的整数当“相似度”用:levenshtein.Compute("abc", "ab") 返回 1,但这不是百分比。得归一化:
- 相似度 ≈
1.0 - float64(dist) / float64(max(len(a), len(b)))(适用于等长或近似长度) - 更稳妥用 Jaro-Winkler 或 Cosine 前,先确认是否真需要编辑距离——比如校验用户输错的命令名、拼写纠错,它够用;但比新闻标题语义,就力不从心了
- 注意:空字符串参与计算时,
levenshtein.Compute("", "a")返回1,没问题;但若没预处理(如 trim 空格、转小写),"Go "和"go"会算出距离 2,实际应为 0
中文分词后用 cosine.Similarity 算向量余弦相似度
纯字符级编辑距离对中文很不友好——"苹果手机" 和 "iPhone" 编辑距离大,但语义接近。必须先分词再向量化。
推荐用 github.com/go-ego/gse 分词 + github.com/nlpodyssey/cosine 算相似度。关键点不在“怎么装”,而在“怎么分得准”:
-
gse.New("zh")默认词典对科技名词覆盖弱,建议加载自定义词典:seg.LoadDict("mydict.txt"),里头加iPhone 10、ChatGPT 5这类新词 - 不要直接对原始句子向量化——先去停用词(
的、了、在)、小写化、过滤标点。否则"Python 很好用!"和"python很好用"向量差异会被噪音放大 -
cosine.Similarity输入是两个[]float64,不是字符串。得把分词结果转成词频向量(TF)或 TF-IDF,别漏了这步——否则传进去的是词列表,运行时报panic: cannot convert []string to []float64
遇到 runtime error: index out of range 多半是没检查切片长度
无论是用 levenshtein 还是自己实现 Jaccard,只要涉及索引访问(比如取 str[0] 或遍历 rune 切片),Golang 就会严格报这个错。它不像 Python 那样容忍空字符串。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
典型场景和解法:
- 用户输入为空或全是空格:
strings.TrimSpace(input)后必须判空,不能直接runes := []rune(input)然后runes[0] - 分词返回空切片:
seg.Cut(" ")可能返回[]string{},后续做for _, w := range words没问题,但若写了words[0]就崩 - 对比两个文本前,统一做
if len(a) == 0 || len(b) == 0 { return 0.0 },别指望相似度函数内部兜底
性能敏感时别用 strings.FieldsFunc 做分词预处理
有人图快,用 strings.FieldsFunc(text, unicode.IsPunct) 想一步去掉标点,结果发现比 gse.Cut 还慢。原因:它按 rune 逐个调用回调函数,而 gse 是基于双数组 Trie 的批量匹配。
实测对比(1KB 中文文本):
-
strings.FieldsFunc(..., unicode.IsPunct):平均 85μs -
regexp.MustCompile(`[^\p{Han}\p{Latin}\p{Digit}]+`).Split(text, -1):平均 62μs -
gse.Cut(带默认词典):平均 110μs,但产出的是有意义的词,不是碎片
所以选哪个,取决于你要的是“干净字符串”还是“可计算的语义单元”。如果只是清洗后喂给编辑距离,用正则;如果要进 TF-IDF,老老实实用 gse,别省那几十微秒,换来的是结果可用性。
真正容易被忽略的,是分词和向量化的上下文一致性——训练时用 A 词典,线上用 B 词典,或者大小写处理不统一,相似度数字再高也没意义。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










