You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Word2Vec计算句子与目标词相似度并实现文本归类的方法咨询

基于Word2Vec计算句子与目标词相似度并实现文本归类的方法咨询

嘿,你的思路其实挺靠谱的!针对你要把1000条投诉文本归类到4个核心词的需求,我来一步步帮你实现你想的方法,再给你补充几个更实用的替代方案。


一、实现你提出的「取TopN相似词求平均」方法

你的思路是对的:先算句子里每个词和目标词的相似度,取TopN最高的求平均,作为句子和目标词的匹配度。下面是具体的代码实现,结合你的示例数据:

1. 预处理与模型训练(先把基础工作做扎实)

先做些文本预处理(转小写、去标点),这能让模型效果更好:

import pandas as pd
from gensim.models import Word2Vec
import numpy as np

# 你的示例数据
data = {
    'text': [
        "The king sat on the throne with wisdom.",
        "A queen ruled the kingdom alongside the king.",
        "Knights were loyal to their king.",
        "The empire prospered under the rule of a wise monarch."
    ]
}
df = pd.DataFrame(data)

# 文本预处理:转小写、去标点、分词
df['text'] = df['text'].str.lower().str.replace('[^\w\s]', '').str.split()    

# 训练Word2Vec模型,这里可以根据你的数据调整参数
model = Word2Vec(df['text'], vector_size=100, window=2, min_count=1, workers=4)

2. 编写相似度计算函数

写一个通用函数,用来计算句子和目标词的TopN相似度平均值:

def calculate_topn_similarity(sentence_words, target_word, model, top_n=3):
    # 过滤掉模型不认识的词
    valid_words = [word for word in sentence_words if word in model.wv.key_to_index]
    if not valid_words:
        return 0.0  # 句子里没有模型识别的词时返回0
    
    # 计算每个有效词和目标词的相似度
    similarities = [model.wv.similarity(word, target_word.lower()) for word in valid_words]
    # 取TopN最高的相似度并求平均
    top_similarities = sorted(similarities, reverse=True)[:top_n]
    return np.mean(top_similarities)

3. 应用到DataFrame并归类

假设你的4个核心词是['king', 'castle', 'queen', 'monarch'],直接批量计算并找出每个句子最匹配的词:

target_words = ['king', 'castle', 'queen', 'monarch']

# 给每个目标词创建对应的相似度列
for word in target_words:
    df[word] = df['text'].apply(lambda x: calculate_topn_similarity(x, word, model, top_n=3))

# 找出每个句子最匹配的核心词
df['most_representative'] = df[target_words].idxmax(axis=1)

运行后你就能看到每个句子和4个核心词的匹配度,以及它最对应的类别啦。


二、更常用的替代方案:句子向量直接求相似度

其实还有一种更简洁的思路:先把整个句子转换成向量(用所有词向量的平均值),再和目标词的向量求余弦相似度,这样能更直接反映整个句子的语义和目标词的关联:

1. 编写句子向量与相似度计算函数

def get_sentence_vector(sentence_words, model):
    valid_vectors = [model.wv[word] for word in sentence_words if word in model.wv.key_to_index]
    if not valid_vectors:
        return np.zeros(model.vector_size)  # 无有效词时返回全0向量
    return np.mean(valid_vectors, axis=0)

# 计算每个句子的向量
df['sentence_vector'] = df['text'].apply(lambda x: get_sentence_vector(x, model))

# 用余弦相似度计算句子向量与目标词向量的匹配度
from sklearn.metrics.pairwise import cosine_similarity

for word in target_words:
    if word in model.wv.key_to_index:
        target_vec = model.wv[word].reshape(1, -1)
        df[f'{word}_vec_sim'] = df['sentence_vector'].apply(lambda x: cosine_similarity(x.reshape(1, -1), target_vec)[0][0])
    else:
        df[f'{word}_vec_sim'] = 0.0

# 找出最匹配的核心词
df['most_representative_vec'] = df[[f'{word}_vec_sim' for word in target_words]].idxmax(axis=1).str.replace('_vec_sim', '')

这种方法的优势是不需要手动选TopN,避免了个别极端相似词的干扰,结果更稳定。


三、一些优化小建议

  • 预处理要到位:除了转小写、去标点,还可以去掉停用词(比如the、on这类无意义的词),用nltk的停用词库就能轻松实现,能大幅提升模型效果。
  • 模型参数调整:如果你的数据量有1000条,可以把vector_size调到150-300,window调到5-10,min_count设为2-5,过滤掉出现极少的冷门词。
  • 处理OOV词:对于模型不认识的词(比如一些行业专属术语),可以用随机向量或者忽略,上面的函数已经处理了这种情况。

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

火山引擎 最新活动