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

基于电影字幕的Genre预测:Word2Vec替代BOW的实现方案

用Word2Vec替代BOW做电影字幕Genre预测:可行!附实现步骤

当然可行!用Word2Vec替代BOW做字幕的Genre预测不仅完全可行,还能解决BOW的核心短板——BOW只统计词频,完全忽略了词与词之间的语义关联,而Word2Vec能把语义相似的词映射到向量空间中的相近位置,这对理解字幕里的对话语境、提升Genre预测的准确性帮助很大。下面我就一步步给你讲具体怎么实现:

一、核心思路梳理

之前你用BOW时,每个字幕样本是一个一维的词频向量;换成Word2Vec后,每个样本会变成由多个词向量组成的序列(因为字幕是一串连续的文本),或者你也可以把序列里的词向量做平均,得到一个固定维度的句向量。两种方式都能适配Keras模型,看你更关注序列上下文还是想简化模型。

二、具体实现步骤

1. 先把字幕文本重新预处理

你之前用的是已经转好的BOW向量,现在需要回到原始字幕文本,做基础的文本预处理:

  • 分词:英文用nltk.word_tokenize,中文用jieba这类工具,把每段字幕拆成单个词的序列
  • 清洗:去除停用词、标点、数字,把所有词统一成小写(英文)
  • 最终输出:每段字幕变成类似 ["hello", "there", "this", "is", "a", "thriller"] 的词序列列表

2. 训练或加载Word2Vec模型

你有两种选择,根据你的数据量来选:

选项1:用自己的字幕语料训练Word2Vec

如果你的字幕数据量足够(比如几千段以上),自己训练的模型会更贴合电影领域的语境,用gensim库就能轻松实现:

from gensim.models import Word2Vec

# corpus是所有字幕样本的词序列列表,比如corpus = [["i", "love", "action"], ["scary", "scene", "horror"], ...]
model = Word2Vec(
    sentences=corpus,
    vector_size=128,  # 词向量维度,一般选50-300,根据数据量调整
    window=5,         # 上下文窗口大小,即每个词会参考前后5个词的语义
    min_count=2,      # 忽略出现次数少于2的生僻词
    workers=4         # 多线程加速训练
)
# 保存模型,方便后续调用
model.save("movie_subtitle_word2vec.model")

选项2:用预训练的Word2Vec模型

如果你的字幕数据量很小,可以直接用公开的预训练模型(比如Google News的Word2Vec模型),加载后就能直接获取词向量,不用自己训练。

3. 把字幕样本转换成Word2Vec向量序列

现在要把每个词序列转换成对应的词向量序列,同时处理长度不一致的问题:

from keras.preprocessing.sequence import pad_sequences
import numpy as np

# 加载训练好的模型
model = Word2Vec.load("movie_subtitle_word2vec.model")
word_vec_dim = model.vector_size  # 比如128

def word_seq_to_vec_seq(word_seq):
    # 把每个词转换成向量,不在词表里的词用全0向量替代
    vec_seq = []
    for word in word_seq:
        if word in model.wv:
            vec_seq.append(model.wv[word])
        else:
            vec_seq.append(np.zeros(word_vec_dim))
    return vec_seq

# 假设所有预处理后的字幕词序列存在texts列表里
X_vec_seqs = [word_seq_to_vec_seq(seq) for seq in texts]

# 统一序列长度:取所有字幕长度的95分位数,或者固定一个最大值
max_seq_len = 100
X_padded = pad_sequences(X_vec_seqs, maxlen=max_seq_len, dtype="float32")

4. 重构Keras模型

现在输入变成了三维张量(样本数 × 序列长度 × 词向量维度),你可以选两种模型结构:

结构1:用LSTM捕捉序列上下文(推荐)

因为字幕是连续的对话,用循环神经网络(LSTM/GRU)能捕捉上下文的语义关联,更适合Genre预测:

from keras.models import Sequential
from keras.layers import LSTM, Dense, Dropout

model = Sequential()
# 输入形状是(None, max_seq_len, word_vec_dim)
model.add(LSTM(64, input_shape=(max_seq_len, word_vec_dim)))
model.add(Dropout(0.3))  # 防止过拟合
model.add(Dense(32, activation="relu"))
# 输出是4种Genre的独热编码,用softmax激活
model.add(Dense(4, activation="softmax"))

# 编译模型,和你之前用BOW时的配置一致即可
model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"])

结构2:词向量平均成句向量,用全连接层(简化版)

如果不想用复杂的序列模型,可以把每个字幕的所有词向量做平均,得到一个固定维度的句向量,然后用全连接层训练:

# 把每个样本的词向量做平均
X_avg_vecs = np.array([np.mean(vec_seq, axis=0) for vec_seq in X_vec_seqs])

# 构建全连接模型
model = Sequential()
model.add(Dense(64, activation="relu", input_shape=(word_vec_dim,)))
model.add(Dropout(0.3))
model.add(Dense(32, activation="relu"))
model.add(Dense(4, activation="softmax"))

model.compile(optimizer="adam", loss="categorical_crossentropy", metrics=["accuracy"])

5. 训练模型

这部分和你之前用BOW的流程完全一致,把处理好的输入(X_padded或X_avg_vecs)和独热编码标签y输入模型即可:

# 假设y是你的独热编码标签数组,形状为(样本数, 4)
history = model.fit(
    X_padded, y,
    epochs=100,
    batch_size=32,
    validation_split=0.2  # 用20%的数据做验证
)

三、额外小贴士

  • 如果自己训练Word2Vec,语料量越大效果越好,要是你的字幕数据不多,可以找一些公开的电影剧本语料来扩充训练集。
  • 对比BOW和Word2Vec的效果时,尽量保持其他参数(比如epochs、batch_size、全连接层结构)一致,这样对比结果才公平。
  • 也可以试试预训练词向量微调:把预训练的词向量作为Keras Embedding层的初始权重,设置trainable=True,让模型在训练时根据你的数据微调词向量,这往往能得到更好的效果。

内容的提问来源于stack exchange,提问作者Arun Prakash

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:27:21