Quanteda无法移除文本及n-grams中脏话的问题求助
问题分析与解决方案
嘿Chris,我发现了你的代码里的核心问题:你是在句子层面尝试移除脏词,而不是词层面,这直接导致不管是1-gram还是n-gram里的脏词都没被正确清理。下面给你详细拆解并修正:
核心错误点
你的makeSentences函数用了tokens(input, what = "sentence"),这意味着生成的每个token都是完整句子。后续的tokens_remove(output, getProfanityWords())只会移除那些完全等于某个脏词的句子(比如只有一个脏词的短句),但句子里的脏词会被完整保留。之后你用这些带脏词的句子生成n-gram,自然会把脏词包含进去。
而对于已经生成的2/3-gram,你尝试用单个脏词去移除组合后的token(比如"dirty_word"),但tokens_remove和dfm的remove参数只会匹配完全一致的字符串,单个脏词根本匹配不到组合后的n-gram,所以毫无效果。
修正后的代码
我们调整流程,先清理词级别的tokens,再基于干净的词生成n-gram,从根源上避免脏词出现:
getProfanityWords <- function() { profanityFileName <- "profanity.txt" if (!file.exists(profanityFileName)) { profanity.url <- "https://raw.githubusercontent.com/shutterstock/List-of-Dirty-Naughty-Obscene-and-Otherwise-Bad-Words/master/en" download.file(profanity.url, destfile = profanityFileName, method = "curl") } # 简化判断逻辑,用exists更清晰 if (!exists("profanity")) { profanity <- read.csv(profanityFileName, header = FALSE, stringsAsFactors = FALSE)$V1 # 移除原文件末尾的空行 profanity <- profanity[-length(profanity)] } return(profanity) } # 新增:专门处理词级tokens,移除脏词 cleanWordTokens <- function(input_corpus) { # 拆分成单个词,转小写(匹配脏词列表的小写格式),移除无关元素 word_tokens <- tokens(input_corpus, what = "word", remove_numbers = TRUE, remove_punct = TRUE, remove_separators = TRUE, remove_twitter = TRUE, remove_symbols = TRUE, lowercase = TRUE) # 移除脏词 clean_tokens <- tokens_remove(word_tokens, getProfanityWords()) return(clean_tokens) } # 修改生成n-gram的函数:基于干净的词级tokens生成 makeNGrams <- function(clean_tokens, n = 1L) { if (n == 1) { return(clean_tokens) } else { # 用tokens_ngrams直接从干净词生成n-gram return(tokens_ngrams(clean_tokens, n = n)) } } # 主流程 corpora <- corpus(textData) # 先得到完全干净的词级tokens clean_tokens <- cleanWordTokens(corpora) # 生成各n-gram和对应的dfm ngram1 <- makeNGrams(clean_tokens, 1) dfm1 <- dfm(ngram1) ngram2 <- makeNGrams(clean_tokens, 2) dfm2 <- dfm(ngram2) ngram3 <- makeNGrams(clean_tokens, 3) dfm3 <- dfm(ngram3)
关键改进说明
- 词级清理优先:先把文本拆成单个词,转小写后移除脏词,这样所有包含脏词的单个token都会被删掉,后续生成的n-gram自然不会包含脏词。
- n-gram生成逻辑修正:从干净的词级tokens生成n-gram,而不是从原句子生成后再尝试清理,这才是处理n-gram脏词的正确思路——因为组合后的n-gram无法用单个脏词匹配移除。
- 大小写统一:加入
lowercase=TRUE确保文本里的大写/混合大小写脏词能和小写的脏词列表匹配。
这样调整后,不管是1-gram还是2/3-gram里的脏词都会被彻底移除啦!
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

