TF-IDF(term frequency–inverse document frequency)是一种用于资讯检索与资讯探勘的常用加权技术。TF-IDF是一种统计方法,用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。TF-IDF加权的各种形式常被搜寻引擎应用,作为文件与用户查询之间相关程度的度量或评级。除了TF-IDF以外,因特网上的搜寻引擎还会使用基于连结分析的评级方法,以确定文件在搜寻结果中出现的顺序。
TFIDF的主要思想是:如果某个词或短语在一篇文章中出现的频率TF高,并且在其他文章中很少出现,则认为此词或者短语具有很好的类别区分能力,适合用来分类。TFIDF实际上是:TF * IDF,TF词频(Term Frequency),IDF反文档频率(Inverse Document Frequency)。TF表示词条在文档d中出现的频率。IDF的主要思想是:如果包含词条t的文档越少,也就是n越小,IDF越大,则说明词条t具有很好的类别区分能力。如果某一类文档C中包含词条t的文档数为m,而其它类包含t的文档总数为k,显然所有包含t的文档数n=m+k,当m大的时候,n也大,按照IDF公式得到的IDF的值会小,就说明该词条t类别区分能力不强。但是实际上,如果一个词条在一个类的文档中频繁出现,则说明该词条能够很好代表这个类的文本的特征,这样的词条应该给它们赋予较高的权重,并选来作为该类文本的特征词以区别与其它类文档。这就是IDF的不足之处.
这里我将会用JAVA 来介绍一下 TF-IDF的算法. 这里得先计算TF(term freguency). 词频 (term frequency, TF) 指的是某一个给定的词语在该文件中出现的次数。这个数字通常会被归一化,以防止它偏向长的文件。(同一个词语在长文件里可能会比短文件有更高的词频,而不管该词语重要与否。)
这个程序需要从源文件里读取文档, 而且同时需要删除停词(Stop words). 因此这里需要写扫描程序.
class ReadStopWord
{
ArrayList<String> stopwordlist = new ArrayList<String>();
public ReadStopWord(){}
public ArrayList<String> readstopword()
{
try
{
Scanner in = new Scanner(new File("C:/MSC_Lectures/Information Retrieval and Web Search/Assignment1/files/stopwords.txt"));
while(in.hasNext())
{
String str = in.next();
stopwordlist.add(str);
}
in.close();
}
catch(IOException e){}
return stopwordlist;
}
}
class ReadSource
{
ArrayList<ArrayList<String>> Mainlist = new ArrayList<ArrayList<String>>();
ArrayList<String> Sublist = new ArrayList<String>();
boolean scan;
//create stopword object
ReadStopWord stopwordlist = new ReadStopWord();
ArrayList<String> removestopword = new ArrayList<String>();
public ReadSource(){}
public ArrayList<ArrayList<String>> readsource()
{
try
{
Scanner input = new Scanner(new File("C:/MSC_Lectures/Information Retrieval and Web Search/Assignment1/files/cranfield_collection.txt"));
int numbers = -1;
removestopword = stopwordlist.readstopword();
while(input.hasNext())
{
String str = input.next();
str = str.replace(",","").replace("/","");
if(str.equals(".I"))
{
//Add sub arraylist to main arraylist
Mainlist.add(new ArrayList<String>());
numbers = numbers + 1;
scan = false;
}
else if(str.equals(".W"))
{
scan = true;
}
else if(scan == true && str != ".W")
{
if(!removestopword.contains(str)&&!str.equals("."))
{
Sublist = Mainlist.get(numbers);
Mainlist.remove(Sublist);
Sublist.add(str);
Mainlist.add(numbers,Sublist);
}
}
}
input.close();
}
catch(IOException e){}
return Mainlist;
}
}