处理两个分词结果的不一致

昨天遇到了一个编程难题,要求从两种分词结果中找出不一致的部分进行校对,难点主要在要对校对的部分进行做标记,而这些不一致的部分,可能是A包含B的,也可能是B包含A的,比如:


这里是一个示例,两个结果中,红框框起来的部分就是不一不一致的部分,如何将这些不一致的部分标记出来。


在这里采用这个方案:

1.首先遍历,如果一致,那么继续下一条,以A为准,一致的部分把它添加到新集合中;

2.遇到不一致的情况

1)如果A大于B,那么B指针后移,一直到两者一致为止;

2)如果B大于A,那么A指针后移,一直到两者一致为止;

这里的问题是,A指针后移的时候,也要注意把它的元素添加到新集合中。这两部分都放在while循环中,一直到一致时结束循环。在这个while循环里,首先添加一次A元素。


        private void checked()
        {
            textBox4.Text = "";
            // systemTxtResult和manualTxtResult分别保存读进来的两个文件的集合
            List<string> systemTxtResult = new List<string>(ReadStringFromTxt(textBox1.Text+textBox2.Text));
            List<string> manualTxtResult = new List<string>(ReadStringFromTxt(textBox1.Text+textBox3.Text));
            // resultToFind是保存两个文件不一致的条目,带编号,并且保存结果文件,共三列
            // onlyResult保存只有结果文件
            // onlySystemWrithIndex只保存系统文件的列表,并且带序号
            // onlySystemWithoutIndex只保存系统文件的列表,不带序号,这个主要是为了和结果文件进行一个返回检查
            List<string> resultToFind = new List<string>();
            List<string> onlyResult = new List<string>();
            List<string> onlySystemWithIndex = new List<string>();
            List<string> onlySystemWithOutIndex = new List<string>();

            for (int i = 0; i < systemTxtResult.Count; i++)
            {
                textBox4.AppendText(i.ToString() + "\r\n");
                // 两个文件某个词条不一致发现
                if (systemTxtResult[i] != manualTxtResult[i])
                {
                    //给定一个初始循环变量
                    int m = 0, s = 0;
                    // tempResultManual保存的是每个音节组成的集合,最后要组成一个完整词条,再赋值给resultToFind
                    List<string> tempResultManual = new List<string>();
                    string resultStr = "";

                    // 将不一致的两个词条split成数组
                    string[] arrayM = manualTxtResult[i].Split('/');
                    string[] arrayS = systemTxtResult[i].Split('/');
                    while (s < arrayS.Count() && m<arrayM.Count())
                    {
                        // 如果数组第一个元素是互相相同的,那么进行while循环,一直循环到找到不一样的数组元素为止
                        if (arrayM[m] == arrayS[s])
                        {
                            while (arrayM[m] == arrayS[s] && m < arrayM.Count() && s < arrayS.Count())
                            {
                                // 如果数组第一个元素是互相相同的,那么进行while循环,一直循环到找到不一样的数组元素为止
                                // 每循环一次,要把系统文件这一个数组元素添加到新的集合中
                                tempResultManual.Add(arrayS[s] + "/");
                                m++;
                                s++;
                                if (m >= arrayM.Count() - 1 || s >= arrayS.Count() - 1)
                                    break;
                            }
                        }
                        else
                        {
                            //如果发现不同,首先添加一个初始标记 ,S
                            tempResultManual.Add("S");
                            //获取到现在不同的两个音节
                            string tempManualStr = arrayM[m];
                            string tempSystemStr = arrayS[s];
                            //先把现在的系统文件的音节添加到新集合
                            tempResultManual.Add(arrayS[s] + "/");
                            //循环进行词组next组合,一直组合到系统文件和人工标注一样为止
                            while (tempManualStr != tempSystemStr && m<arrayM.Count() && s<arrayS.Count())
                            {
                                // 如果系统音节的长度小于人工标注的长度,那么系统音节下标加1,再组合再对比。
                                if (tempSystemStr.Length < tempManualStr.Length)
                                {
                                    s++;
                                    //这时候因为系统下标变化了,所以系统音节要添加到新集合中
                                    tempResultManual.Add(arrayS[s] + "/");
                                    tempSystemStr += arrayS[s];
                                }
                                // 如果人工标注的长度小于系统音节的长度,那么人工标注下标加1,再组合再对比。
                                if (tempSystemStr.Length > tempManualStr.Length)
                                {
                                    m++;
                                    tempManualStr += arrayM[m];
                                }
                            }
                            // 对比结束,找到两边都一致的最后一个边界,那么最后加一个E标记
                            tempResultManual.Add("E");
                            //下标分别再加1
                            m++;
                            s++;
                        }
                    }
                    foreach (string str in tempResultManual)
                    {
                        resultStr += str;
                    }
                    resultToFind.Add(resultStr);
                }
            }
            WriteStringFromTxt( textBox1.Text+ textBox5.Text, resultToFind);
        }



如果分词结果对应的正确答案数量不一样,就需要使用不同的评价指标来计算准确率、召回率和 F1 值等指标。 假设我们有两个分词结果和对应的正确答案: ```python result1 = ['我', '爱', '自然', '语言', '处理'] answer1 = ['我', '爱', '自然语言', '处理'] result2 = ['自然', '语言', '处理', '是', '一', '门', '非常', '有用', '的', '技能'] answer2 = ['自然语言处理', '是', '一门', '非常', '有用', '的', '技能'] ``` 我们可以定义以下函数来计算准确率、召回率和 F1 值: ```python def compute_precision(result, answer): count = 0 for word in result: if word in answer: count += 1 return count / len(result) def compute_recall(result, answer): count = 0 for word in answer: if word in result: count += 1 return count / len(answer) def compute_f1(result, answer): precision = compute_precision(result, answer) recall = compute_recall(result, answer) return 2 * precision * recall / (precision + recall) ``` 在上面的代码中,我们定义了三个函数,分别用于计算准确率、召回率和 F1 值。在这些函数中,我们分别计算分词结果和正确答案中相同的词的数量,然后根据公式计算准确率、召回率和 F1 值。 接下来,我们可以使用这些函数来计算每个分词结果的准确率、召回率和 F1 值: ```python # 计算结果1的评价指标 precision1 = compute_precision(result1, answer1) recall1 = compute_recall(result1, answer1) f1_1 = compute_f1(result1, answer1) # 计算结果2的评价指标 precision2 = compute_precision(result2, answer2) recall2 = compute_recall(result2, answer2) f1_2 = compute_f1(result2, answer2) # 输出结果 print('结果1的准确率:', precision1) print('结果1的召回率:', recall1) print('结果1的F1值:', f1_1) print('结果2的准确率:', precision2) print('结果2的召回率:', recall2) print('结果2的F1值:', f1_2) ``` 需要注意的是,这种方法只适用于分词结果和正确答案数量不一致的情况。如果分词结果和正确答案数量一致,可以使用更简单的评价指标,如正确率(accuracy)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

极地语音工作室

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值