注意:这里描述的是Lucene 2.1的Field Info。如果您正在使用其它版本的Lucene最好参考一下该发行版的docs/fileformats.html文件。
如果您没有阅读过Lucene Compound Files,建议您先阅读一下,因为这里和那里使用的是一个示例。
图中加蓝色细下划线的部分为Compound File所包含的_2yl.fnm文件的内容。我们先来看一下Field Info的定义,然后在来解释_2yl.fnm文件内容的含义。
FieldInfos(.fnm) --> FieldsCount, <FieldName, FieldBits> FieldsCount
FieldsCount --> VInt
FieldName --> String
FieldBits --> Byte
文件_2yl.fnm的内容如下:
FieldsCount为0x03,即有三个<FieldName, FieldBits>,分别为:
最后让我们来解释一下FieldBits,这是一个Byte,有8位,各位的位置如下图:
因为上面三个Field的FieldBits都为01,所以它们都为indexed field。
注意:这里描述的是Lucene 2.1的Compound Files。如果您正在使用其它版本的Lucene最好参考一下该发行版的docs/fileformats.html文件。
Compound File是一个简单的容器,可以包含*.fnm,*.frq,*.prx,*.fdx,*.fdt,*.tii,*.tis,*.nrm等文件,但是不包含*.del文件。
Compound File的定义为:
Compound (.cfs) --> FileCount, <DataOffset, FileName> FileCount , FileData FileCount
FileCount --> VInt
DataOffset --> Long
FileName --> String
FileData --> raw file data,指上面FileName所对应的文件的内容。
让我们结合一个示例来看看这个定义,其中VInt,Long,String的定义可以查阅之前提到的docs/fileformats.html文件。这个示例使用了一个名为_2yl.cfs的真实文件,以十六进制打开,由于内容过长所以省略了那些没有意义的数据。
文件的开始是FileCount,以红色矩形框表示,值为0x08,表明这里有8个<DataOffset, FileName> 和8个FileData。
DataOffset以绿色矩形框表示,共64位,长度固定;FileName以桔红色矩形框表示,长度不定,细节可以参考String的定义。这里共有8对<DataOffset, FileName>,分别对应着_2yl.fnm,_2yl.frq,_2yl.prx,_2yl.fdx,_2yl.fdt,_2yl.tii,_2yl.tis,_2yl.nrm8个文件和它们内容的偏移量。
图中右边的数字N表示第N个DataOffset对应的内容的开始所在的行,开始位置由蓝色粗下划线标出。
我也是刚刚开始学习Weka,第一课先来翻译一下该项目的首页,水平有限,呵呵。如果您想阅读原文请直接到Weka Machine Learning Project。
在计算机科学领域,一项令人激动的和具有潜在深远影响的开发活动是机器学习方法的发明和应用。这些使得计算机程序能够自动分析大的数据集,决定什么信息是最有意义的。然后这些信息可以用来自动进行预测,或帮助用户更加快速和准确的做出决策。
我们整体的目标是为开发机器学习技术和解决真实世界中数据挖掘问题提供便利。我们的团队已经合并了一些机器学习技术到"workbench"软件包中,这个包被称为WEKA。使用它,一些特殊的领域能够使用机器学习来从手工无法处理的大量数据中推导有用的知识。Weka的用户是机器学习领域的研究者和工业界的科学家,但是Weka也被广泛的用于教学。
我们的目标是:
我们的机器学习包是公开可用的,包含有一个解决真实世界中数据挖掘问题的算法集合。这个软件包全部用Java写成并且包含一个标准机器学习技术的统一接口。请到处随便浏览一下。
[翻译完]
最后给出Weka的论坛和邮件类表,有兴趣的朋友可以去看看。
Weka 3: Data Mining Software in Java
Weka is a collection of machine learning algorithms for data mining tasks. The algorithms can either be applied directly to a dataset or called from your own Java code. Weka contains tools for data pre-processing, classification, regression, clustering, association rules, and visualization. It is also well-suited for developing new machine learning schemes.
Weka is open source software issued under the GNU General Public License.
Pentaho's live forum for Weka
The open-source BI software company Pentaho has become major sponsor of Weka development and will take over the administration of Weka's Sourceforge site in the near future. Pentaho also provides a live forum for interaction among Weka project community members.
The Weka mailing list
Please post Weka-related questions, comments, and bug reports to the Weka mailing list (don't forget to check out the online documentation first, before posting to the list). There is also the searchable mailing list archive (Mirrors: news.gmane.org, Nabble). Please do not email individual members of our research group about Weka problems.
Also, please have in mind that your message will be sent to several thousand people, so please post according to the Mailing List Etiquette. The administrator also removes members from the mailing list in case their mailboxes run full, since they apparently don't read their emails anymore.
关联规则发现最初的形式是货蓝分析,通过货蓝分析发现顾客的购买习惯,帮助零售商制定销售策略。
关联规则领域有两个颇具影响力的算法,Apriori算法和FP-Growth 算法。
相关的内容可以参考推荐系统:关联规则(1)、推荐系统:关联规则(2)和推荐系统:关联规则(3)。在我写这个话题的时候clickstone还没有发布推荐系统:关联规则(3)。他是我认识的推荐系统领域的大牛,呵呵!
我下面涉及的内容基于Apriori算法,详细内容可参考Fast Algorithms for Mining Association Rules。
首先让我来做一个假设有10个人到超市购买自己需要的商品,形成了10个事务记录,如下(其中用A、B等大写字母代表不同的商品):
| 事务ID | 商品列表 |
| 1 | A,B,C |
| 2 | A,C,D |
| 3 | C,D,E |
| 4 | A,B,C,E |
| 5 | B,D,E |
| 6 | B,C,D |
| 7 | A,B |
| 8 | B,C,D,E |
| 9 | B,C,E |
| 10 | A,C,E |
从商品列表中我们很容易发现这10个事务记录中只涉及到5中商品,分别是A,B,C,D和E。
下面通过Apriori算法寻找频繁集的过程,其中省略了概念的介绍,如果有疑问可以参考上面给出的关于Apriori算法的资料。
我们取最小支持度(min support)为0.5,从而最小支持数(support count)为0.5x10=5。
C1为(C1是一个候选集,其定义可以查阅Apriori算法的相关资料,以后涉及到的其它概念同,不再赘述):
| itemset |
| {A} |
| {B} |
| {C} |
| {D} |
| {E} |
通过扫描事务记录集计算支持数后有:
| itemset | support count |
| {A} | 5 |
| {B} | 7 |
| {C} | 8 |
| {D} | 5 |
| {E} | 6 |
依据最小支持数过滤后形成的L1为:
| itemset | support count |
| {A} | 5 |
| {B} | 7 |
| {C} | 8 |
| {D} | 5 |
| {E} | 6 |
L1链接产生C2为:(计算了支持数)
| itemset | support count |
| {A,B} | 3 |
| {A,C} | 4 |
| {A,D} | 1 |
| {A,E} | 2 |
| {B,C} | 5 |
| {B,D} | 3 |
| {B,E} | 4 |
| {C,D} | 4 |
| {C,E} | 5 |
| {D,E} | 3 |
依据最小支持数过滤后形成的L2为:
| itemset | support count |
| {B,C} | 5 |
| {C,E} | 5 |
L2链接产生C3为:
| itemset |
| 空 |
因为C3为空所以算法结束,我们找到了所有的频繁集L1和L2。至此我们完成了Apriori算法的最关键的部分:找出所有满足最小支持度的所有频繁集。下面我们来完成 Apriori算法的另一部分:找出满足最小可信度的所有关联规则。
我们以L2中的频繁集{B,C}为例来描述这个过程,假设最小可信度为70%。
B=>C的可信度为{B,C}的支持数/{B}的支持数,即5/7,约为71.4%
C=>B的可信度为{B,C}的支持数/{C}的支持数,即5/8,为62.5%
注意:这两个结果和我们对10个事务记录的初步观察感觉是一致的,即购买了商品B的顾客多半也会购买商品C,购买了商品C的顾客也会购买商品B,但是后者的比率比前者要少一些。如果事务记录数比较大的话我们就不可能通过观察来得到对关联规则的一些感觉了,这时必须依靠算法。
与最小可信度70%相比只有B=>C满足要求,所以我们得到关联规则B=>C。
这个规则告诉我们有7成以上购买商品B的顾客会同时购买商品C。
MMSeg只是实现了Chih-Hao Tsai的MMSEG算法,这是一个来源于网络的分词算法。我照抄了算法开始的部分:
MMSEG: A Word Identification System for Mandarin Chinese Text Based on Two Variants of the Maximum Matching Algorithm
Published: 1996-04-29
Updated: 1998-03-06
Document updated: 2000-03-12
License: Free for noncommercial use
Copyright 1996-2006 Chih-Hao Tsai (Email: hao520 at yahoo.com )
您可以在Chih-Hao Tsai's Technology Page找到算法的原文。
我将依据自己的理解来简述MMSeg分词算法的基本原理,如有错误请不吝赐教。
首先来理解一下chunk,它是MMSeg分词算法中一个关键的概念。Chunk中包含依据上下文分出的一组词和相关的属性,包括长度(Length)、平均长度(Average Length)、标准差的平方(Variance)和自由语素度(Degree Of Morphemic Freedom)。我在下面列出了这4个属性的计算方法:
| 属性 | 含义 | 代码位置 |
| 长度(Length) | chuck中各个词的长度之和 | org.solol.mmseg.internal.Chunk.getLength() |
| 平均长度(Average Length) | 长度(Length)/词数 | org.solol.mmseg.internal.Chunk.getAverageLength() |
| 标准差的平方(Variance) | 同数学中的定义 | org.solol.mmseg.internal.Chunk.getVariance() |
| 自由语素度(Degree Of Morphemic Freedom) | 各单字词词频的对数之和 | org.solol.mmseg.internal.Chunk.getDegreeOfMorphemicFreedom() |
注意:表中的含义列可能有些模糊,最好参照MMSeg的源代码进行理解,代码所在的函数已经给出了。
Chunk中的4个属性采用Lazy的方式来计算,即只有在需要该属性的值时才进行计算,而且只计算一次。
其次来理解一下规则(Rule),它是MMSeg分词算法中的又一个关键的概念。实际上我们可以将规则理解为一个过滤器(Filter),过滤掉不符合要求的chunk。MMSeg分词算法中涉及了4个规则:
这4个规则分别位于org.solol.mmseg.internal.MMRule.java、org.solol.mmseg.internal.LAWLRule.java、org.solol.mmseg.internal.SVWLRule.java和org.solol.mmseg.internal.LSDMFOCWRule.java4个源文件中。之所以这样来处理是因为我们可以方便的增加规则和修改应用规则的顺序。
这4个规则符合汉语成词的基本习惯。
再次来理解一下两种匹配方式,简单最大匹配(Simple maximum matching)和复杂最大匹配(Complex maximum matching)。
简单最大匹配仅仅使用了规则1。
复杂最大匹配先使用规则1来过滤chunks,如果过滤后的结果多于或等于2,则使用规则2继续过滤,否则终止过滤过程。如果使用规则2得到的过滤结果多于或等于2,则使用规则3继续过滤,否则终止过滤过程。如果使用规则3得到的过滤结果多于或等于2,则使用规则4继续过滤,否则终止过滤过程。如果使用规则4得到的过滤结果多于或等于2,则抛出一个表示歧义的异常,否则终止过滤过程。
最后通过一个例句--研究生命起源来简述一下复杂最大匹配的分词过程。MMSeg分词算法会得到7个chunk,分别为:
| 编号 | chunk | 长度 |
| 0 | 研_究_生 | 3 |
| 1 | 研_究_生命 | 4 |
| 2 | 研究_生_命 | 4 |
| 3 | 研究_生命_起 | 5 |
| 4 | 研究_生命_起源 | 6 |
| 5 | 研究生_命_起 | 5 |
| 6 | 研究生_命_起源 | 6 |
使用规则1过滤后得到2个chunk,如下:
| 编号 | chunk | 长度 |
| 4 | 研究_生命_起源 | 6 |
| 6 | 研究生_命_起源 | 6 |
计算平均长度后为:
| 编号 | chunk | 长度 | 平均长度 |
| 4 | 研究_生命_起源 | 6 | 2 |
| 6 | 研究生_命_起源 | 6 | 2 |
使用规则2过滤后得到2个chunk,如下:
| 编号 | chunk | 长度 | 平均长度 |
| 4 | 研究_生命_起源 | 6 | 2 |
| 6 | 研究生_命_起源 | 6 | 2 |
计算标准差的平方后为:
| 编号 | chunk | 长度 | 平均长度 | 标准差的平方 |
| 4 | 研究_生命_起源 | 6 | 2 | 0 |
| 6 | 研究生_命_起源 | 6 | 2 | 4/9 |
使用规则3过滤后得到1个chunk,如下:
| 编号 | chunk | 长度 | 平均长度 | 标准差的平方 |
| 4 | 研究_生命_起源 | 6 | 2 | 0 |
匹配过程终止。最终取“研究”成词,以相同的方法继续处理“生命起源”。
分词效果:
Simple ->研究生_命_起源_
Complex->研究_生命_起源_
Simple ->研究生_教育_
Complex->研究生_教育_
注意:Simple表示简单最大匹配的分词效果,Complex表示复杂最大匹配的分词效果。