如何对Semantic-Segment-Anything输出的相似标注进行语义归组?
语义化归组标注语义变体的方案
针对你提到的Semantic-Segment-Anything输出TSV中类别列的语义变体问题(如building/a building/a tall building),以下是比骰子系数、模糊字符串匹配更语义化的归组方法:
1. 预训练语义嵌入聚类
- 利用Sentence-BERT、BERT这类预训练模型,将每个类别名称转换为语义嵌入向量——这类模型能捕捉文本的深层语义关联,所有围绕
building的变体向量会高度相似。 - 搭配K-Means、DBSCAN等聚类算法对向量分组,自动将语义接近的类别归为同一组,之后可选取组内出现频次最高的名称作为统一类别标签。
- 示例代码:
from sentence_transformers import SentenceTransformer from sklearn.cluster import KMeans import pandas as pd # 读取TSV数据 df = pd.read_csv("your_file.tsv", sep="\t") categories = df["类别名称"].tolist() # 生成语义嵌入 model = SentenceTransformer('all-MiniLM-L6-v2') embeddings = model.encode(categories) # 聚类(根据实际类别数量调整n_clusters) kmeans = KMeans(n_clusters=5, random_state=42) df["簇标签"] = kmeans.fit_predict(embeddings) # 为每个簇分配统一类别名 df["统一类别"] = df.groupby("簇标签")["类别名称"].transform(lambda x: x.value_counts().index[0])
2. 核心名词提取
- 用spaCy、NLTK等NLP工具做词性标注和名词短语提取,剥离冠词(a/an/the)、形容词(tall/large)等修饰成分,提取最核心的实体名词作为统一类别。
- 这种方法直接抓住类别表述的核心,适合修饰词不改变核心语义的场景。
- 示例代码(spaCy):
import spacy import pandas as pd nlp = spacy.load("en_core_web_sm") df = pd.read_csv("your_file.tsv", sep="\t") def get_core_noun(text): doc = nlp(text) # 提取所有名词,取最后一个(通常是核心实体) nouns = [token.text for token in doc if token.pos_ == "NOUN"] return nouns[-1] if nouns else text df["统一类别"] = df["类别名称"].apply(get_core_noun)
3. 零样本分类匹配
- 先定义一套标准类别清单(如
["building", "road", "vegetation"]),使用零样本分类模型(如facebook/bart-large-mnli)将每个变体文本匹配到最贴合的标准类别。 - 无需标注数据,完全依赖模型的语义理解能力,适合变体复杂但标准类别明确的场景。
- 示例代码:
from transformers import pipeline import pandas as pd classifier = pipeline("zero-shot-classification", model="facebook/bart-large-mnli") standard_classes = ["building", "road", "vegetation"] df = pd.read_csv("your_file.tsv", sep="\t") def match_standard_class(text): result = classifier(text, candidate_labels=standard_classes) return result["labels"][0] df["统一类别"] = df["类别名称"].apply(match_standard_class)
4. 自定义语义规则引擎
- 结合领域知识编写正则或逻辑规则,直接匹配核心关键词。比如只要文本包含
building(不区分大小写),就统一归为building类别。 - 实现简单、运行高效,适合变体模式固定的场景。
- 示例代码:
import re import pandas as pd df = pd.read_csv("your_file.tsv", sep="\t") def normalize_label(text): lower_text = text.lower() if re.search(r"\bbuilding\b", lower_text): return "building" # 其他类别规则可以依次添加 return text df["统一类别"] = df["类别名称"].apply(normalize_label)
内容的提问来源于stack exchange,提问作者Shalqam
相关产品推荐
相关产品推荐

