`
nnwq
  • 浏览: 209216 次
社区版块
存档分类
最新评论

基于统计的无词典的高频词抽取(三)——子串归并

 
阅读更多

由于最近换了工作,需要熟悉新的工作环境,工作内容也比较多,所以一直没有更新文章,趁着今晚有空,就继续写写这系列的文章。

前面两篇,我们已经实现了后缀数组的排序,高频字串的抽取,也初有成效,如下图:

接下来,我们就继续对结果进行进一步的精确化,使用子串归并来实现:

首先,我先举一个可能不大适合的例子来大概解释一下什么叫做子串归并。假设,某个语料库中,统计到“你”出现了100次,而“你好”也刚好出现了100次,那么,我们舍弃“你”这个结果,保留“你好”;我们为什么这样做呢?从这个简单的例子可以看出,出现“你”子的时候,一定会出现“你好”,那么根据成词的规则,我们保存长的子串(一般来说,子串选取长度在[2,4]这个区间内)。

好了,现在,我们再从上面的规则中进行加深:

① 我们先限定抽取串的长度在[2,4]中,以避免抽取过长的字符串;

② 当字符串S被抽取(其中S的长度为L,L≥2,S出现的次数为 t),且S的后缀sfx(i)(其中i∈(0,L))在文本中出现的次数也等于t时(S的后缀出现的次数可能大于t,但不会小于t,这是很好理解的,例如,“中国人”出现次数为10,则其一个后缀“国人”仅在这个字符串中出现的次数就为10,而假设还有一个字符串“美国人”出现5次,那么“国人”这个字符串就出现了15次,大于10),S的后缀sfx(i)将不再被抽取;

③ 当然仅仅当母串的次数等于子串次数作为归并的条件,这限定太过苛刻,我们将可以调整归并的策略,引入阀值t,t根据语料库的大小进行调整(t取[0.1,0.3]较为合理;语料库越大时,应适当调低;文本越小时,应适当调高);假设字符串S1是S2的前缀,S1出现的次数t1,S2出现的次数为t2。当(t- t)/t2 <t 时,舍弃,S1不作高频串抽取;

我们将过程进行细化和限定,处理过程看起来稍微合理,下面,我使用C#将此过程转换为程序语言(注,由于时间关系,该代码未做任何优化,性能欠佳,大家可以对代码进行优化或自己实现)

 1 public static void RemoveSubString(List<StringFrequency> stringFrequency, string str, int[] pat, int[] lcp)
 2 {
 3     var _STACK = new Stack<StringFrequency>();
 4     var _PSTACK = new Stack<int>();
 5     var isContinu = true;
 6     var p = 0;
 7     var count = stringFrequency.Count();
 8     for (var i = 0; i < count; i++)
 9     {
10         isContinu = _PSTACK.Contains(i) ? false : true;
11         if (isContinu)
12         {
13             p = i;
14             var tmp = str.Substring(pat[stringFrequency[i].Position], lcp[stringFrequency[i].Position]);
15             for (var j = i + 1; j < count; j++)
16             {
17                 if (!_PSTACK.Contains(j))
18                 {
19                     var cur = str.Substring(pat[stringFrequency[j].Position], lcp[stringFrequency[j].Position]);
20                     if (Convert.ToSingle((stringFrequency[i].Times - stringFrequency[j].Times) / stringFrequency[j].Times)>0.3f)
21                         break;
22                     if (tmp.Contains(cur))
23                     {
24                         _STACK.Push(stringFrequency[j]);
25                         _PSTACK.Push(j);
26                     }
27                     else if (cur.Contains(tmp))
28                     {
29                         tmp = cur;
30                         _STACK.Push(stringFrequency[i]);
31                         _PSTACK.Push(i);
32                     }
33                 }
34             }
35         }
36     }
37     while (_STACK.Count() > 0)
38     {
39         stringFrequency.Remove(_STACK.Pop());
40     }
41 }

上面代码指向前,我们需要使用一个根据出现次数排序的 List<StringFrequency> stringFrequency 集合:

1 var sortList = stringFquency.OrderByDescending(x => x.Times).ToList();
2 //str为语料库,a为字符串的后缀数组,lcpList为LCP扫描结果,详见上一篇
3 RemoveSubString(sortList, str, a, lcpList);

如果不出所料,上面的代码执行效率是不尽人意的,即使上面做了一定程度上的减少扫描次数,但是大体上的时间复杂度要达O(n2),效率奇低;而如果使用基于散列表的算法(将所有重复串及其频次存放于散列表中,然后依次去判断表中的每一项的所有可能子串是否存在,存在且频次相同,则归并,理论上可达O(n),但是次算法空间开销太大,容易造成内存泄露,大家可以参考《基于散列的子串归并算法》这篇论文)。。。我们可以结合上一篇文章中扫描LCP的过程,并在此过程中完成子串归并的动作;这篇文章仅仅描述子串归并的原理,此处就不再详述解决的过程;

好了,第三部分就先讲到这里,如果觉得文章对您有用或者对其他人有帮助,请帮忙点文章下面的“推荐”;如果文章有任何纰漏,欢迎指正,谢谢!

1
1
分享到:
评论
1 楼 ansjsun 2013-07-19  
额!!!没找到你的1,2,,,,

相关推荐

    论文研究-一种基于独立性统计的子串归并算法.pdf

    通过动态增量的方法,在基于密度和自适应密度可达聚类算法的基础上,根据BIRCH算法中聚类特征的概念,利用簇特征设计与实现了一种新的动态增量聚类算法,解决了大型数据库聚类的有效性以及空间和时间复杂度问题。...

    论文研究-面向CDN网络的高效海量数据分发机制研究.pdf

    现行的子串归并算法都...通过分析这些无意义子串和众多父串之间的这种一对多关系,提出了一种基于独立性统计的子串归并算法。最后将该子串归并算法应用在中文术语抽取系统中,使得系统的准确率从91.3%提升到了93.32%。

    删除子串删除子串删除子串删除子串,只要是原串中有相同的子串就删掉,不管有多少个

    在编程领域,删除字符串中的重复子串是一个常见的字符串处理问题。这个问题的核心是找出字符串中的所有重复子串,并将它们从原始字符串中移除。这里提到的解决方案采用了逆序判断的思路,结合了KMP(Knuth-Morris-...

    查找最长公共子串

    本话题聚焦于一个经典的算法问题——“查找最长公共子串”。这是一道典型的字符串算法题,主要考察对字符串操作和动态规划的理解。 首先,我们需要明确什么是“公共子串”。如果一个字符串s是另一个字符串t的子串,...

    把符串中的一子串替换为另一子串

    ### 把字符串中的一子串替换为另一子串——VB技术实现 在计算机编程领域,字符串操作是一项非常基础且重要的技能。特别是在Visual Basic (VB)这样的语言中,字符串处理经常被用于各种应用场合,比如文本处理、数据...

    输出最长子串的代码

    在编程领域,"最长子串"通常是指在一个或多个字符串中找到共享的、最长的连续字符序列。这个概念广泛应用于文本处理、数据挖掘以及算法竞赛等场景。在本例中,我们将探讨如何编写一个程序来找出给定字符串集合中的...

    词典变位词检索系统.rar

    词典变位词检索系统是一种基于计算机编程技术的软件应用,主要用于帮助用户查找和分析具有相同意义但形式不同的词汇,通常在语言学习和文本处理领域中广泛应用。在这个项目中,我们关注的是一个由C语言实现的词典...

    双回文子串的相关解法

    #### 三、Bzoj2565 最长双回文子串 ##### 1. 题目描述 Bzoj2565要求找出字符串中最长的由两个回文子串组成的子串,即这两个子串连接起来形成的串仍然是回文串。 ##### 2. 解决方案 - **预处理最长回文子串**:类似...

    找出子串位置.doc

    通过这段代码,我们可以学习到如何在Java中有效地处理字符串,包括查找子串、统计出现次数以及定位子串的所有出现位置。这些知识在处理文本数据时非常有用,尤其是在文本分析、搜索算法或数据处理场景中。

    寻找最长不重复子串

    寻找最长不重复子串 python代码

    基于树型结构和加权熵的中文高频词提取算法 (2011年)

    因此,基于统计的中文高频词提取方法开始受到越来越多的重视。 本研究提出了一个基于树型结构和加权熵的中文高频词提取算法。该算法的核心在于运用树型结构来构建中文文本的语义空间,并引入加权信息熵的概念,以...

    无重复字符的最长子串1

    无重复字符的最长子串是字符串中一个特殊的子串,其中没有任何字符重复。这是一个常见的编程问题,经常出现在面试和算法竞赛中,例如LeetCode上的题目。解决这个问题的关键在于使用滑动窗口的概念,这是一种用于处理...

    PTA 7-29 删除字符串中的子串

    PTA 7-29 删除字符串中的子串

    动态规划——最长公共子序列和最长公共子串之Python实现

    用Python实现动态规划中最长公共子序列和最长公共子串问题!

    删除子串 vb

    不过,在这个案例中,因为没有指定第三个参数(替换次数),它只会替换第一个匹配的子串。 总结,VB提供了多种方法来删除字符串中的子串,可以根据实际需求选择合适的方法。理解并熟练运用这些函数是VB编程中的基础...

    VB 编写删除子串过程

    在VB(Visual Basic)编程中,删除子串是一项常见的字符串操作任务,主要用于处理文本数据,例如清理、格式化或修改用户输入。以下将详细介绍如何在VB中编写删除子串的过程,以及相关的知识点。 首先,我们需要了解...

    求最长的公共子串

    两个字符串里求最长的公共子串

    字符串的子串删除问题

    字符串的子串删除问题 在本文中,我们探讨了Codeforces Round #452 (Div. 2) F题的两种解决方案。该问题的关键点在于字符串的子串删除问题。 1. 问题描述 给定一个长度为n的字符串和m次操作,每次操作给出两个...

Global site tag (gtag.js) - Google Analytics