为gensim FastText无监督模型预处理文本时返回单字符结果问题咨询
FastText训练返回单字符相似结果的解决方案
核心问题根因
你遇到的问题本质是语料迭代器的输出格式不符合gensim要求:
gensim的FastText接收的语料迭代器,每个返回值必须是分词后的单词列表,而你当前的代码直接yield整行字符串,Python字符串本身是可迭代对象,gensim会默认把单个字符作为独立的词处理,最终训练出的词表全部由单字符组成,查询相似词时自然返回单字符结果。
具体修改步骤
步骤1:调整语料迭代器输出格式
你手头的CSV每行是已经完成预处理的分词句子,默认是空格分隔,只需要在读到每行后调用split()拆分为单词列表即可,同时显式指定编码避免乱码问题。
修改后的训练代码如下:
from gensim.models import FastText from gensim.test.utils import get_tmpfile, datapath from gensim import utils import os import csv # 仅标准多列CSV需要导入 embedding_size = 200 window_size = 10 min_word = 5 down_sampling = 1e-2 modelpath = "替换为你的模型保存路径" csvpath = "替换为你的CSV文件路径" # 注意:修改代码后要先删除本地已存在的旧模型文件,否则会直接加载错误的旧模型 if os.path.isfile(modelpath): model1 = FastText.load(modelpath) else: class NWIter(): def __iter__(self): path = datapath(csvpath) # 情况1:CSV每行直接是空格分隔的分词结果,无其他额外列 with utils.open(path, 'r', encoding='utf-8') as fin: # 如果CSV有表头,取消下面一行的注释跳过表头 # next(fin) for line in fin: # 拆分成分词列表后返回 yield line.strip().split() # 情况2:标准多列CSV,预处理文本存储在指定列(比如content列),用下面的代码替换上面的读写逻辑 # with open(path, 'r', encoding='utf-8', newline='') as fin: # reader = csv.DictReader(fin) # for row in reader: # yield row['content'].strip().split() model1 = FastText(vector_size=embedding_size, window=window_size, min_count=min_word,sample=down_sampling,workers=4) model1.build_vocab(corpus_iterable=NWIter()) exs1=model1.corpus_count model1.train(corpus_iterable=NWIter(), total_examples=exs1, epochs=50) model1.save(modelpath)
步骤2:验证训练结果
训练完成后先执行以下代码确认词表正常:
# 查看词表总数量,正常应该远大于字母、符号的总数量 print("词表大小:", len(model1.wv.index_to_key)) # 查看查询的目标词是否在词表中 print("smart是否在词表中:", 'smart' in model1.wv) # 再查询相似词即可得到正常的词语结果 print('NonWhite: ',model1.wv.most_similar('smart', topn=10))
其他注意事项
- 如果修改后仍然有异常,先确认CSV的分词分隔符是否为空格,若为逗号、制表符等,修改
split()的参数即可,比如按逗号分隔改为split(',') min_count参数不要设置过高,避免大量有效词被过滤,可根据你的语料总大小适当调整
内容的提问来源于stack exchange,提问作者Michael Martin
相关产品推荐
相关产品推荐

