0 背景
1 VSM向量空間模型
2 TFIDF應用到文本分類
TFIDF的核心思想是,一篇文章中的某個詞出現的頻率很高,而在其它文章中出現的頻率相對很低,那麼就說明這個詞具有很好的區分能力,應該給其賦以較高的權重值。
對於某一篇文章來說,某個詞term的TFIDF值爲:
上面公式中TF的意義是:term在本篇文章中的重要性。只有term的詞頻是不足以表徵term在本篇的重要性的,比如term在一篇總詞數爲100詞的文章中出現3詞,在另一篇總詞數爲500詞的文章中出現3詞,term肯定在前篇文章中更加重要。
IDF的公式的意義是:包含term的文章是不是比較集中,即包含term的文章是不是相對比較少。IDF越大,就是包含term的文章數比較集中,就說明具備分類的能力比較強。
在CHI檢驗提取特徵詞的時候,總文檔數和包含每一個詞的文檔數都可以統計出來。所以在TFIDF計算的過程,我們就只可以統計TF相關的值了。多說一句,其實是只有在訓練集訓練分類模型的時候,纔會用到特徵詞提取的方法,在測試集的時候並不會用到CHI,因爲特徵詞都已經提取出來了。在給測試集分類的時候,我們只使用TFIDF計算權重值就好了。
補充部分: 本篇文章中的總詞數是原始文章的總詞數呢?還是特徵詞提取之後的總詞數?我分別對這兩種情況進行了實驗,發現使用原始文章的總詞數準確率會更高一些。我覺得是因爲原始文章的總詞數更能表現文章的真實性,即沒有一點降維,但是使用特徵詞的總詞數也就是使用了經過降維處理後的文章,真實性肯定會有所下降。但是,我只是實驗了我的程序,可能還不具太大的參考性。讀者可以自行實驗。
3 程序附錄
<span style="font-size:18px;">//第一個參數爲提取證詞後的文件路徑,第二個參數爲目的文件,第三個爲特徵詞集合,第四個爲VSM向量表示
public void computeTFIDF(String path, String desFile, VSM v, HashMap<String,Double> afterCHI){
String artTmp="";
//讀出這篇文章
File file = new File(path);
String str = "";
//System.out.println(path);
try {
FileInputStream in = new FileInputStream(file);
int size = in.available();
byte[] buffer = new byte[size];
in.read(buffer);
in.close();
str = new String(buffer, "UTF-8");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
String[] strline = str.split(" ");
//totalNum = strline.length-1;
totalNum = Integer.parseInt(strline[strline.length-1]);
//統計這篇文章中的特徵詞頻
for (int i = 0; i < strline.length-1; i++) {
if(v.vsm.contains(strline[i])){
vsmOne.put(strline[i], vsmOne.get(strline[i])+1);
}
}
//計算這篇文章的每個特徵詞的TFIDF值
Iterator<String> it = v.vsm.iterator();
while(it.hasNext()){
String tmp = it.next();
vsmOne.put(tmp, (vsmOne.get(tmp)/totalNum)*afterCHI.get(tmp));
}
//把這篇文章的計算出的IFIDF寫入文件
try {
FileWriter fw=new FileWriter(desFile,true);
String[] absuPath = path.split("\\\\");
if(absuPath[absuPath.length-2].equals("C000008")){ //C000008爲一個類別
artTmp = toString(1);
}
if(absuPath[absuPath.length-2].equals("C000009")){
artTmp = toString(2);
}
if(absuPath[absuPath.length-2].equals("C000010")){
artTmp = toString(3);
}
if(absuPath[absuPath.length-2].equals("C000011")){
artTmp = toString(4);
}
if(absuPath[absuPath.length-2].equals("C000012")){
artTmp = toString(5);
}
if(absuPath[absuPath.length-2].equals("C000013")){
artTmp = toString(6);
}
if(absuPath[absuPath.length-2].equals("C000014")){
artTmp = toString(7);
}
if(absuPath[absuPath.length-2].equals("C000015")){
artTmp = toString(8);
}
if(absuPath[absuPath.length-2].equals("C000016")){
artTmp = toString(9);
}
fw.write(artTmp);
fw.flush();
fw.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}</span>
上面的源文件是的一篇文章的特徵詞集,目的文件的格式什麼呢?因爲我採用的分類器是SVM,所以用的是林志仁教授的LibSVM,所以目的文件的格式是LibSVM需要的數據格式。在下一篇文章中將會記錄LibSVM是怎麼樣使用的。