You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何利用NLP技术判断词汇/语句与目标定义的相似性并得到预期分类结果?

如何利用NLP技术判断词汇/语句与目标定义的相似性并得到预期分类结果?

嗨,我明白你的需求啦——你不是要单纯计算句子之间的语义相似度,而是要判断每个句子是否符合*「素食用户」*这个明确的定义,得到True/False的分类结果对吧?之前用SentenceTransformer算所有句子间的相似度肯定不对,因为那是在找句子之间的关联,不是做符合度判断。下面给你几个实用的方案,你可以根据自己的场景选择:

一、快速上手:基于关键词规则的方案

如果你的定义比较明确(比如这里的*「素食用户」就是不吃鸡、鱼等肉类,只吃植物类食物),直接写规则是最省心的。咱们可以设定正向关键词和反向关键词*,然后通过简单逻辑判断:

  • 正向关键词:表示符合素食的表述,比如vegetarian、only eats fruits
  • 反向关键词:表示不符合素食的食物,比如chicken、fish

具体代码实现如下:

# 定义关键词规则
definition_rules = {
    "positive": {"vegetarian"},
    "negative": {"chicken", "fish"}
}
sentences = [
    'vegetarian User',
    'user sometimes eats chicken',
    'user is vegetarian',
    'user only eats fruits',
    'user likes fish'
]

results = []
for sent in sentences:
    lower_sent = sent.lower()
    # 检查是否包含正向关键词,或者是纯植物饮食表述
    has_positive = any(word in lower_sent for word in definition_rules["positive"]) or "only eats fruits" in lower_sent
    # 检查是否包含非素食的反向关键词
    has_negative = any(word in lower_sent for word in definition_rules["negative"])
    # 逻辑:符合素食条件且没有非素食行为
    is_vegetarian = has_positive and not has_negative
    results.append(is_vegetarian)

print(results)  # 输出: [True, False, True, True, False]

这个方案的优点是简单直接,容易调整规则;缺点是遇到复杂句子(比如「user doesn't eat chicken but eats fish」)时,需要细化规则。

二、更灵活:微调小模型做文本分类

如果需要处理更复杂的语义场景(比如遇到「user avoids all animal products」这种间接表述),咱们可以用预训练小模型做微调,把问题转成二分类任务(符合定义/不符合定义):

  1. 准备少量标注数据:把符合素食的句子标为1,不符合的标为0
  2. 用轻量级预训练模型(比如DistilBERT)做微调
  3. 用微调后的模型预测新句子的分类结果

简化版代码示例:

from transformers import DistilBertTokenizer, DistilBertForSequenceClassification, Trainer, TrainingArguments
import torch

# 准备标注训练数据
train_texts = [
    'vegetarian User', 'user is vegetarian', 'user only eats fruits',
    'user sometimes eats chicken', 'user likes fish', 'user eats beef'
]
train_labels = [1, 1, 1, 0, 0, 0]

# 加载模型和分词器
tokenizer = DistilBertTokenizer.from_pretrained('distilbert-base-uncased')
model = DistilBertForSequenceClassification.from_pretrained('distilbert-base-uncased', num_labels=2)

# 自定义数据集类
class TextDataset(torch.utils.data.Dataset):
    def __init__(self, encodings, labels):
        self.encodings = encodings
        self.labels = labels
    def __getitem__(self, idx):
        item = {key: torch.tensor(val[idx]) for key, val in self.encodings.items()}
        item['labels'] = torch.tensor(self.labels[idx])
        return item
    def __len__(self):
        return len(self.labels)

# 预处理数据
train_encodings = tokenizer(train_texts, truncation=True, padding=True)
train_dataset = TextDataset(train_encodings, train_labels)

# 设置训练参数
training_args = TrainingArguments(
    output_dir='./model_results',
    num_train_epochs=3,
    per_device_train_batch_size=2,
    logging_dir='./training_logs',
    logging_steps=10
)

# 训练模型
trainer = Trainer(
    model=model,
    args=training_args,
    train_dataset=train_dataset
)
trainer.train()

# 预测目标句子
test_sentences = [
    'vegetarian User',
    'user sometimes eats chicken',
    'user is vegetarian',
    'user only eats fruits',
    'user likes fish'
]
test_encodings = tokenizer(test_sentences, truncation=True, padding=True, return_tensors='pt')
outputs = model(**test_encodings)
predictions = torch.argmax(outputs.logits, dim=1)
print([bool(pred) for pred in predictions])  # 输出符合预期的分类结果

这个方案能处理复杂语义,但需要准备少量标注数据,训练过程也需要一点时间。

三、改进你的SentenceTransformer方法

如果你还是想用相似度思路,别再计算所有句子之间的相似度了,应该聚焦每个句子和**目标定义「vegetarian User」**的相似度,然后设置一个阈值来判断True/False:

from sentence_transformers import SentenceTransformer, util

model = SentenceTransformer("all-mpnet-base-v2")
target_definition = "vegetarian User"
sentences = [
    'vegetarian User',
    'user sometimes eats chicken',
    'user is vegetarian',
    'user only eats fruits',
    'user likes fish'
]

# 编码目标定义和所有句子
def_embedding = model.encode(target_definition, convert_to_tensor=True)
sent_embeddings = model.encode(sentences, convert_to_tensor=True)

# 计算每个句子与定义的余弦相似度
similarities = util.cos_sim(def_embedding, sent_embeddings)[0]

# 设置相似度阈值,比如0.7,超过则认为符合定义
threshold = 0.7
results = [sim > threshold for sim in similarities]
print(results)

这里的关键是调整阈值,你可以根据实际输出的相似度得分来调整,直到得到你想要的结果。

总结一下:如果场景简单,规则方案足够用;如果需要处理复杂语义,微调模型是更好的选择;用SentenceTransformer的话,一定要聚焦和目标定义的单方向相似度,而不是所有句子间的相互相似度。

备注:内容来源于stack exchange,提问作者A3006

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 10:43:09