textrank 在 c# 无成熟官方库,需自主实现文本清洗、句子切分、相似度建图与迭代打分,核心难点在于准确识别句子边界。

TextRank 在 C# 里没现成库,别直接搜 TextRank NuGet 包
官方生态里没有被广泛维护、支持中文分词和句子图构建的成熟 TextRank 实现。你搜到的几个小众包要么只处理英文单词级,要么依赖过时的 Microsoft.ML 预处理流水线,对 PDF/Word 文件里的真实文本结构(段落断裂、换行符污染、标题混入)完全无感。
- 真正能用的路径是:自己控制文本清洗 → 句子切分 → 相似度建图 → 迭代打分
- 核心难点不在算法公式,而在“什么算一句”——比如
"答:\n1. 是。\n2. 否。"这种,正则Split(@"[。!?;]+")会把“答:”单独劈成一句,带权重拉低整段得分 - 建议先用
Regex.Split(text, @"(? 做初步句切,再人工过滤掉长度
LexRank 更适合文件摘要,但必须替换默认相似度计算
LexRank 理论上比 TextRank 少一个参数(不用调 damping),但它默认用 TF-IDF + 余弦相似度,对技术文档这种术语密集、句式重复率高的内容效果差——两段都含“ArgumentNullException”和“throw new”,相似度虚高,关键操作步骤反而被压下去。
- 换成 Jaccard 相似度更稳:
Jaccard(A, B) = |A ∩ B| / |A ∪ B|,对词干重合敏感,对停用词不敏感 - 句子向量化前务必做:小写化 + 去停用词(用
System.Collections.Generic.HashSet<string></string>存中文停用词表)+ 保留动词/名词(可用Stanford.NLP.CoreNLP的ChineseSegmenter,但注意它不支持 .NET 6+ 直接引用,得走 Java interop 或换LacSharp) - 矩阵稀疏性很重要:句子数 > 200 时,别用
double[,]存全连接矩阵,改用SparseMatrix(来自MathNet.Numerics)
从文件读取到关键句输出,三步不能跳
很多人卡在第一步:以为 File.ReadAllText(path) 能直接喂给算法。实际 PDF/DOCX 里藏了大量干扰字符(零宽空格、软回车、OLE 对象残留),不清理就跑 LexRank,等于拿噪声训练模型。
- PDF:用
QuestPDF或IronPdf(后者免费版有水印但 API 干净),别用iTextSharp—— 它的PdfTextExtractor对中文字体嵌入处理极差,常抽成乱码 - DOCX:用
DocumentFormat.OpenXml,重点处理Paragraph和Run的Text属性,跳过Footnote和Comment节点 - 统一后处理:用
Regex.Replace(text, @"[\u200B-\u200D\uFEFF]", "")清零宽字符,再用Regex.Replace(text, @"\s+", " ")合并空白,最后.Trim()
关键句排序后,别直接返回 raw 文本
原始句子可能包含不完整主语(如“见上文配置”)、指代不明(“该方法”“此参数”),或者带冗余格式(“注意:请勿……”)。直接返回会降低可读性。
- 提取后做一次上下文补全:查该句在原文中的位置,往前取最多 1 个完整句(用同样句切逻辑),拼成“上下文 + 关键句”二元组
- 过滤掉含“详见”“如下所示”“参见附录”的句子——它们本身不承载信息,只是导航
- 输出时保留原始段落编号(如有):
"第3.2节:初始化时需校验 <code>connectionString是否为空",比纯文本更有定位价值
实际最难的不是打分,是让算法理解“这句话为什么重要”。比如一段日志配置说明里,“LogLevel.Debug 会输出所有 SQL 参数”这句权重一定高于“日志级别有五种”,因为前者解决具体问题。这种语义优先级,目前还得靠规则兜底,不是纯图算法能自动学出来的。










