如何计算data.frame内字符串行的两两相似度并生成带PTA名称的矩阵?
单个DataFrame内字符串行的两两相似度计算方案
嘿,其实你提到的stringdist完全可以处理单个data.frame内的两两字符串相似度计算,只是你可能没用到它的核心函数——stringdistmatrix(),它专门用来生成单个字符向量的两两距离矩阵,正好匹配你的需求!下面我给你两种常用的实现方案,你可以根据文本长度和需求选择:
方案一:用stringdist快速计算(适合短文本/编辑距离类相似度)
假设你的pta_corpus包含两列:pta_name(存储PTA的名称,用于标记矩阵)和pta_content(存储协定文本内容),步骤如下:
- 加载并准备数据
# 加载包 library(stringdist) # 提取文本向量和名称向量 text_content <- pta_corpus$pta_content pta_names <- pta_corpus$pta_name
- 计算两两距离矩阵,转换为相似度
stringdistmatrix()支持多种距离计算方法(比如Jaccard、Levenshtein、Cosine等),这里以Jaccard为例(适合文本集合相似度):
# 计算Jaccard距离矩阵(Jaccard距离 = 1 - Jaccard相似度) dist_matrix <- stringdistmatrix(text_content, method = "jaccard") # 转换为相似度矩阵 sim_matrix <- 1 - dist_matrix
- 为矩阵添加PTA名称标签
# 设置行名和列名为PTA名称 rownames(sim_matrix) <- pta_names colnames(sim_matrix) <- pta_names # 查看结果(可选) head(sim_matrix[, 1:3])
注意:如果用Levenshtein(编辑距离)这类非归一化的距离,需要先做归一化处理才能得到0-1之间的相似度,比如除以每行字符串的最大长度:
# 归一化Levenshtein距离为相似度 max_len <- max(nchar(text_content)) lev_dist <- stringdistmatrix(text_content, method = "lv") lev_sim <- 1 - (lev_dist / max_len)
方案二:用text2vec计算基于词频的相似度(适合长文本)
如果你的PTA内容是较长的文本,更适合用基于TF-IDF的余弦相似度,text2vec包在这方面效率很高:
- 加载包并预处理文本
library(text2vec) # 创建迭代器,预处理文本(转小写、分词) text_iterator <- itoken(pta_corpus$pta_content, preprocessor = tolower, tokenizer = word_tokenizer) # 创建词汇表并过滤低频词 vocab <- create_vocabulary(text_iterator) vocab <- prune_vocabulary(vocab, term_count_min = 1) # 保留至少出现1次的词
- 生成文档-词矩阵(DTM)并计算相似度
# 创建向量器 vectorizer <- vocab_vectorizer(vocab) # 生成DTM dtm <- create_dtm(text_iterator, vectorizer) # 计算余弦相似度矩阵 sim_matrix <- sim2(dtm, method = "cosine", norm = "l2") # 添加PTA名称标签 rownames(sim_matrix) <- pta_corpus$pta_name colnames(sim_matrix) <- pta_corpus$pta_name
两种方案最终都会得到一个以PTA名称为行/列名的相似度矩阵,矩阵中的值就是对应两行文本的相似度啦!
内容的提问来源于stack exchange,提问作者willwang
相关产品推荐
相关产品推荐

