THUCTC源码解读(三)

来源:互联网 发布:现在windows出到几了 编辑:程序博客网 时间:2024/06/07 12:48

Term类

Term也是一个非常简单的类,是文档向量(DocumentVector)的基本组成部分,一个Term表示词典中的一个词。
存储的变量只有id和weight, id表示该Term代表的词在词典中的id,而weight表示该词在文档向量中的权重。此外,Term的内部类TermIdComparator还实现了Comparator接口,使得java能够对Term数组进行排序。

public class Term {    public int id;    public double weight;    public static class TermIdComparator implements Comparator<Term>, Serializable {        public int compare(Term o1, Term o2) {            return o1.id - o2.id;        }    }    public static class TermWeightComparator implements Comparator<Term> {        public int compare(Term o1, Term o2) {            return Double.compare(o2.weight, o1.weight);        }    }}

TermWeighter类

TermWeighter是一个抽象类,需要继承类实现对Term计算权重的功能。由于在THUCTC中使用了TF-IDF的权重计算方式,所以该类需要词典来提供一个词的TF和IDF值。

public abstract class TermWeighter implements Serializable{    protected Lexicon lexicon;    public TermWeighter( Lexicon l ) {        lexicon = l;    }    abstract public double weight ( int id, double tf, int doclen);}

DocumentVector类

DocumentVector,就是将一篇文档向量化表示。文档向量的长度即为词典中单词数目,向量中第i个term表示词典中的第i个词在该文档向量中的权重。
DocumentVector本身并不存储向量内容,而是向外界提供了生成文档向量的方法。DocumentVector类中只有2个变量,分别是TermWeighter和Term.TermIdComparator对象,分别实现计算权重和term数组的排序功能。
除了构造方法外,该类只有两个方法,分别是build和dotProduct,前者负责将Word数组形式的文档转化成文档向量(Term数组),后者负责两个向量的内乘,这里主要看build方法

public Term [] build( Word [] doc, boolean normalized) {        // Term 为 id-weight 表示形式        Hashtable<Integer, Term> terms = new Hashtable<Integer, Term>();        // 这部分是统计各terms出现次数        for ( Word w : doc ) {            Term t = terms.get(w.id);            if ( t == null ) {                t = new Term();                t.id = w.id;                t.weight = 0;                terms.put(t.id, t);            }            t.weight += 1;  // 出现次数+1        }        // 这部分是将hashtable转化成数组并使用TermWeighter计算权重        Term [] vec = new Term[terms.size()];        Enumeration<Term> en = terms.elements();//使用迭代的方法遍历,类似于Python中的迭代器        int i = 0;        double normalizer = 0;        while ( en.hasMoreElements() ) {            vec[i] = en.nextElement();            vec[i].weight =                 weighter.weight( vec[i].id, vec[i].weight, doc.length);            normalizer += vec[i].weight * vec[i].weight;            i++;        }        if ( normalized ) {  //如果normalized=true,则进行正则化计算            normalizer = Math.sqrt(normalizer);            for ( Term t : vec ) {                t.weight /= normalizer;            }        }        Arrays.sort(vec, idcomp); //这里通过TermIdComparator来实现对term数组的排序        return vec;    }

LinearBigramChineseClassifier类

这个类在Demo中出现过。虽然在demo中分类器是由BasicTextClassifier创建的,但是毫无疑问LinearBigramChineseClassifier是分类器的核心,BasicTextClassifier只是在此基础上的一层封装,实现了模型的导入导出,参数初始化等一些交互功能。

这个类继承自LiblinearTextClassifier,大部分内容由LiblinearTextClassifier实现,LiblinearTextClassifier是一个抽象类,因为其中有一个抽象的方法initWordSegment,而LinearBigramChineseClassifier实现了这个方法。

public class LinearBigramChineseTextClassifier extends LiblinearTextClassifier{  public LinearBigramChineseTextClassifier(int nclasses) {    super(nclasses);  }  public LinearBigramChineseTextClassifier(int nclasses, WordSegment seg ) {    super(nclasses, seg);  }  @Override  protected WordSegment initWordSegment() {    return new BilingualBigramWordSegment(); // 实现了父类中的抽象方法  }}
0 0
原创粉丝点击