You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ML.NET+C#提取关键词异常:返回全部关键词而非匹配项

ML.NET提取匹配关键词返回全部列表的问题排查与解决

常见问题原因

  1. 文本未归一化:土耳其语包含特殊变音符号(如İ/i、ş/s)和大小写差异,若未统一处理,可能导致匹配逻辑失效,或错误触发全量匹配。
  2. 匹配逻辑错误:未实现完整短语匹配,仅做单个词的包含判断,导致只要关键词中的某个词出现在标题中,就判定整个关键词匹配。
  3. ML.NET组件误用:错误选择了不适合短语匹配的文本处理组件(如简单词袋模型),未针对短语级匹配做配置。

解决步骤与代码示例

1. 文本归一化处理

先统一标题和关键词的大小写与变音符号,确保匹配的一致性。针对土耳其语,使用CultureInfo进行规范化:

using System.Globalization;

public static string NormalizeTurkishText(string text)
{
    var turkishCulture = new CultureInfo("tr-TR");
    // 转小写 + 规范化变音符号
    return text.ToLower(turkishCulture).Normalize(NormalizationForm.FormD);
}

2. 定义ML.NET数据模型与匹配逻辑

创建输入输出模型,通过自定义转换实现完整短语匹配:

using Microsoft.ML;
using Microsoft.ML.Data;

// 输入模型:文章标题
public class TitleInput
{
    [LoadColumn(0)]
    public string Title { get; set; }
}

// 输出模型:匹配的关键词列表
public class KeywordMatchOutput
{
    [ColumnName("MatchedKeywords")]
    public string[] MatchedKeywords { get; set; }
}

public class KeywordMatcher
{
    private readonly MLContext _mlContext;
    private readonly ITransformer _model;
    private readonly string[] _normalizedKeywords;
    private readonly string[] _originalKeywords;

    public KeywordMatcher(string[] keywords)
    {
        _mlContext = new MLContext();
        _originalKeywords = keywords;
        // 归一化关键词列表
        _normalizedKeywords = keywords.Select(k => NormalizeTurkishText(k)).ToArray();

        // 创建ML管道:自定义转换实现短语匹配
        var pipeline = _mlContext.Transforms.CustomMapping<TitleInput, KeywordMatchOutput>(
            (input, output) =>
            {
                var normalizedTitle = NormalizeTurkishText(input.Title);
                // 匹配完整短语:检查归一化后的标题是否包含归一化后的关键词
                output.MatchedKeywords = _normalizedKeywords
                    .Select((normKey, idx) => new { NormKey = normKey, OriginalKey = _originalKeywords[idx] })
                    .Where(item => normalizedTitle.Contains(item.NormKey))
                    .Select(item => item.OriginalKey)
                    .ToArray();
            }, contractName: null);

        // 训练模型(此处无训练数据,仅构建管道)
        var emptyData = _mlContext.Data.LoadFromEnumerable(new List<TitleInput>());
        _model = pipeline.Fit(emptyData);
    }

    public string[] GetMatchedKeywords(string title)
    {
        var input = new TitleInput { Title = title };
        using var predictionEngine = _mlContext.Model.CreatePredictionEngine<TitleInput, KeywordMatchOutput>(_model);
        return predictionEngine.Predict(input).MatchedKeywords;
    }
}

3. 调用示例

// 原始关键词列表
var keywords = new[] { "işçilik alacakları", "kısmi dava", "belirsiz alacak davası", "diğer anahtar kelime" };
// 文章标题
var title = "İşçilik Alacaklarında Kısmi Dava ve Belirsiz Alacak Davası Müesseselerinin İşletilmesi";

var matcher = new KeywordMatcher(keywords);
var matched = matcher.GetMatchedKeywords(title);

// 输出结果:["işçilik alacakları", "kısmi dava", "belirsiz alacak davası"]
foreach (var key in matched)
{
    Console.WriteLine(key);
}

额外注意事项

  • 若关键词存在短语重叠(如"alacak"和"işçilik alacakları"),需调整匹配顺序(优先匹配长短语),避免短短语先匹配导致长短语被忽略。
  • 若需更精准的匹配(如避免子串误匹配),可使用正则表达式的单词边界规则,修改自定义转换中的判断逻辑:
output.MatchedKeywords = _normalizedKeywords
    .Select((normKey, idx) => new { NormKey = normKey, OriginalKey = _originalKeywords[idx] })
    .Where(item => Regex.IsMatch(normalizedTitle, $@"\b{Regex.Escape(item.NormKey)}\b"))
    .Select(item => item.OriginalKey)
    .ToArray();

内容的提问来源于stack exchange,提问作者Johnny Wind

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 10:41:12