统计单字字频的方法
统计单字字频的方法
语言学中经常用统计数据对语言现象进行定量描写,主要用来支持语言的自动分析,其中字频和词频是最基本的统计单位,其中运用的原理主要是概率论。本文主要讨论对于单个文本文件的单字字频统计,其任务是:给定一批语料,统计其中有多少个不同的汉字(即词形,Word Type),每个汉字各出现多少次(即字频,Word Frequency)(由于汉字出现的总次数是一定的,因此可以直接用其出现的次数来代替词频)。如果语料规模足够大并且分布均匀,就可以根据字频来估计每个汉字的出现概率。(注:本文的论述基于GB2312-80)
处理这个问题的基本思想是,建立一个动态数组,数组中的每一个元素当作一种结构,其存储的数据是某个汉字出现的频率,同时,还需建立其字频和汉字的关联,这个问题用数组的下标能很容易实现。那么怎样来建立汉字和数组下标的关联呢?由上一篇对于汉字编码的分析可以得出如下的计算公式:
设ID是汉字对应的下标,C1、C2是汉字的两个字节的ASCII码,有
ID=(C1-176)*94+(C2-161)
从这个公式,我们便可以建立汉字到下标的转换。同样,我们还需要建立从下标到汉字的转换,公式如下:
C1=ID/94+176 (先取模后求和)
C2=ID%94+161(先取余后求和)
利用这个原理,便可以利用机器自动的进行字频统计了。
下面的java程序实现了统计单个文本文件中的字频的功能,最后在目标文件中存储了汉字及对应的字聘和ASCII编码。
import java.io.*;
public class SingleWordFreq {
public static void main(String args[])throws IOException{
File newDir=new File("d://java//test2");
File newFileR=new File(newDir,"source.txt");
File newFileW=new File(newDir,"wordFre.txt");
newFileW.createNewFile();
RandomAccessFile fileR=new RandomAccessFile(newFileR,"r");
RandomAccessFile fileW=new RandomAccessFile(newFileW,"rw");
long fileLength=newFileR.length();//获取文件的字节长度
int[] wordF=new int[6768];
for(int i=0;i<fileLength;i++)
{
int c1=fileR.read();
if (c1<128)continue;
if(c1<176){int c2=fileR.read();continue;}
int c2=fileR.read();
int id=(c1-176)*94+(c2-161);
wordF[id]++;
};
int n=0;
for(int m=0;m<6768;m++){
if (wordF[m]!=0)n++;//计算出现的不同的字的数量.
};
for(int id=0;id<6768;id++){
if (wordF[id]>0)
{
int d1=(id/94)+176;
int d2=(id%94)+161;
String word1=Integer.toString(d1, 2);
String word2=Integer.toString(d2, 2);
String word=word1+word2;
long wordAsc=Long.parseLong(word,2);//将二进制字符串转换为ASCII码
fileW.writeLong(wordAsc);//输出汉字字符
fileW.writeChars(wordF[id]+" "+wordAsc);// 输出字频及ASCII编码
fileW.writeBytes("/r/n");//换行
}
};
fileW.writeLong(1088 );
System.out.println(n);//输出总的字形数(即有多少个符合要求的不同的字)
}
}