简介
有时候有必要对一个英文语料进行统计,以便发现其中的规律。例如,统计词频从而知道哪些词使用得比较频繁。本文实现了三个函数完成英文语料的统计功能,重点研究在什么条件下能够使语料中90%单词能被人读懂。
数据集
本文使用MASC数据集,下载地址:https://www.anc.org/data/masc/
该数据集是一个开放的社区资源,从更大的语料集Open American National Corpus (OANC)上抽取而成, 由500,000多个单词组成。
统计代码
代码由js写成。对数据集中的每一个文本文档进行分词、去停词处理,统计出现过的每个单词的词频数。最后把统计结果输出到一个文件。
const fs = require('fs');
const { resolve } = require('path');
/**
* 统计结果,是一个map
*/
let words = new Array();
/**
* 总词数
*/
let total = 0;
/**
* 统计一个文件
* @param {string} filename 文件的文件名
*/
function readFile(filename){
console.log("正在处理:" + filename);
var data = fs.readFileSync(filename, 'utf-8');
var str = data.toString();
var tokens = str.split(/\W+/) //分词
.filter((token)=>{return token != '' && ! /^(\w|\d+)$/.test(token)}) // 去停词
.map((token)=>{return token.toLowerCase()});
for(let token of tokens){
if(words[token] === undefined){
words[token] = 1;
}else{
words[token] += 1;
}
total += 1;
}
}
/**
* 统计一个目录下的所有文件
* @param {string} path 目录的路径
*/
function readAllFiles(path){
const files = fs.readdirSync(path);
for(let file of files){
var filePath = resolve(path, file);
var stat = fs.statSync(filePath);
if (stat.isFile()) {
readFile(filePath);
} else if (stat.isDirectory()) {
readAllFiles(filePath)
}
}
}
/**
* 把统计结果写到文件中
* @param {string} filename 文件的文件名
*/
function wirteCSV(filename){
//根据词频由大到小排序
var wordList = []
for(let word in words){
if(typeof(words[word]) == 'number')
wordList.push({word: word, count: words[word]})
}
wordList.sort((a, b)=>{
if(a.count < b.count) {
return 1;
}else if(a.count == b.count){
return 0;
}else{
return -1;
}
})
// 写文件
let fWrite = fs.createWriteStream(filename);
fWrite.write("词");
fWrite.write(",")
fWrite.write("频数");
fWrite.write(",");
fWrite.write("频率");
fWrite.write(",");
fWrite.write("累计百分比");
fWrite.write('\n')
let accumulate = 0;
for(let obj of wordList){
accumulate += obj.count;
fWrite.write(obj.word);
fWrite.write(",")
fWrite.write(obj.count + "");
fWrite.write(",");
fWrite.write(obj.count * 100 / (total + 1) + "%");
fWrite.write(",");
fWrite.write(accumulate * 100 / (total + 1) + "%");
fWrite.write('\n')
}
fWrite.close();
}
readAllFiles('./spoken');
readAllFiles('./written');
wirteCSV('./wordcout.csv');
console.log("处理完毕");
结果分析
统计结果如下。左边主要是各个单词在语料中的出现频数、频率,并按照词频由大到小排序。
如右边上方的图,我们可以发现,词频大小呈指数级下降,很好的符合“长尾理论”。
如右边下方的图,可知,2300左右的词汇量即可覆盖语料中80%的单词。6500左右的词汇量可覆盖语料中90%的单词。因此
,如果人类掌握了上图中前6500词,则能读懂语料中90%词汇。
展望
该语料集比较小,可能不能很好的反应规律。如果能够在更大语料集中统计,并且如果语料是日常语料,则可统计外国人日常的英文词频。我们则可以有的放矢地去记忆单词。
本文的词频统计方法与语料规模无关,可直接用于更大的语料。
关注我,学习更多编程小技巧!