用 C# 调用 NLP 模型做关键词提取,本质是调外部服务或轻量模型
纯 .NET 自带库(如
Microsoft.ML)不直接支持端到端的文档关键词抽取;你得要么对接 REST API(如 Azure AI Language、spaCy+FastAPI),要么集成轻量级 ONNX 模型。硬靠
Regex或 TF-IDF 手写规则,效果差、泛化弱,别试。
实操建议:
优先走 Azure AI Language 的ExtractKeyPhrasesAPI:稳定、多语言、免训练,
HttpClient发个 POST 就行,返回 JSON 里直接有
keyPhrases数组 若必须离线:用 ONNX Runtime + 预训练小模型(如
distilbert-base-uncased-finetuned-conll03-english改造成关键词抽取头),但需自己处理 tokenization 和 span 映射——
Microsoft.ML.OnnxRuntime可加载,
Tokenizer得额外引入
HuggingFace.Tokenizers别碰
Microsoft.ML的
TextFeaturizer+
OneHotEncoding堆 TF-IDF:它输出的是向量,不是可读关键词,还得自己逆映射词表,极易错位
“自动打标签”不是分词,是语义聚类或分类任务
用户说的“标签”,往往指业务维度的归类(如“合同”“报销单”“发票”),不是技术意义上的词性标注。这和关键词提取是两回事:前者要文档级预测,后者是短语级抽取。
实操建议:
如果已有标注数据:用Microsoft.ML的
MultiClassLogisticRegression或
SdcaMaximumEntropy训练文本分类器,输入是
TextLoader读取的文档正文,输出是
PredictedLabel没标注数据?别强行无监督聚类(如
KMeanson TF-IDF):C# 生态缺好用的语义向量库,
ML.NET的
WordEmbedding已废弃,结果不可信 折中方案:用 Azure AI 的
ClassifyDocument(需预定义类别),或把文档喂给
text-embedding-3-smallAPI,再在本地用
Flann或
BallTree(需 P/Invoke 或调 Python)做相似度匹配——但这就不是纯 C# 了
常见错误:把 string.Split()
或停用词过滤当 NLP
看到“提取关键词”就写个
Split(' ', '.', '!') + 去停用词 + 统计频次,结果满屏“的”“是”“我”,还配个 OrderByDescending——这不是 NLP,这是字符串练习。
典型翻车点:
StopWords表用中文就抄英文列表,导致“的”“了”“在”全放过 没做词形还原(如“running”“ran”“runs”算三个词),英文文档频次统计失真 直接对 PDF 提取的原始文本跑分析,没清理页眉页脚、OCR 错字(如“1”当“I”,“O”当“0”),关键词变成“合I同”“报N销” 用
File.ReadAllText读大文件进内存再处理,几百 MB 文档直接 OOM,得用
StreamReader分块或流式解析
性能与兼容性:别低估文本预处理开销
NLP 瓶颈从来不在模型推理,而在文本清洗和编码。C# 默认 UTF-8,但很多老文档是 GB2312 或 ANSI,
File.ReadAllText(path)不指定
Encoding会乱码,关键词全歪。
关键控制点:
PDF 解析不用iTextSharp(已停更、.NET 6+ 兼容差),换
QuestPDF或
SkiaSharp提取文本,或调系统
pdftotext命令行(需部署依赖) 长文档别一次性送整个
string给 API:Azure 限制单请求 5120 字符,得切段(按句号/换行)、去重、合并结果,注意跨段关键词断裂(如“人工智能”被切成“人工”“智能”) 并发调 API 时,
HttpClient必须复用实例,别每个请求 new 一个——否则快速触发
SocketException: Too many open files
真正卡住人的,永远是编码识别不准、PDF 文本结构错乱、API 限流策略不透明,而不是模型本身。先确保输入干净,再谈“智能”。
