前提:首先说明一下TFIDF的部分是借用
http://www.cnblogs.com/ywl925/archive/2013/08/26/3275878.html
这篇博文写的代码,因为工作需要在后面加上了使用信息增益的方法进行特征降维。
TFIDF的介绍在此就不赘述了,直接将公式摆出来。
TF公式:
以上式子中 是该词在文件中的出现次数,而分母则是在文件中所有字词的出现次数之和。
IDF公式:
- |D|:语料库中的文件总数
- :包含词语的文件数目(即的文件数目)如果该词语不在语料库中,就会导致被除数为零,因此一般情况下使用
然后
信息增益
其公式为:
假如有变量X,其可能的取值有n种,每一种取到的概率为Pi,那么X的熵就定义为
也就是说X可能的变化越多,X所携带的信息量越大,熵也就越大。对于文本分类或聚类而言,就是说文档属于哪个类别的变化越多,类别的信息量就越大。所以特征T给聚类C或分类C带来的信息增益为
IG(T)=H(C)-H(C|T)
H(C|T)包含两种情况:一种是特征T出现,标记为t,一种是特征T不出现,标记为t'。所以
H(C|T)=P(t)H(C|t)+P(t')H(C|t‘)
本例属于文本分类其p(t)为该词在所有分类中出现的概率,H(C|t)该词出现的条件下分类的熵。
本例的数据为自行搜索的不良信息中的两类,暴力和反动。提供两种筛选方式一种设立阈值另一种是进行排序后选取前多少个为特征值。
涉及的文件
停用词表和分词jar包:http://files.cnblogs.com/files/mansiisnam/%E6%96%87%E4%BB%B6.zip
代码如下
package TIDF; import java.io.*; import java.util.*; import org.wltea.analyzer.lucene.IKAnalyzer; /** * 分词-TFIDF-信息增益 * @author LJ * * @datetime 2015-6-15 */ public class TestTfIdf { public static final String stopWordTable = "C:/Users/zzw/Desktop/sc_ot-tingyongzhongwen_hc/stopWordTable.txt"; // 加载停用词库 private static ArrayList<String> FileList = new ArrayList<String>(); // 文件列表 // 递归读取该路径下文件返回文件列表 public static List<String> readDirs(String filepath) throws FileNotFoundException, IOException { try { File file = new File(filepath); if (!file.isDirectory()) { System.out.println("输入的[]"); System.out.println("filepath:" + file.getAbsolutePath()); } else { String[] flist = file.list(); for (int i = 0; i < flist.length; i++) { File newfile = new File(filepath + "\\" + flist[i]); if (!newfile.isDirectory()) { FileList.add(newfile.getAbsolutePath()); } else if (newfile.isDirectory()) { readDirs(filepath + "\\" + flist[i]); } } } } catch (FileNotFoundException e) { System.out.println(e.getMessage()); } return FileList; } // 读入文件 public static String readFile(String file) throws FileNotFoundException, IOException { StringBuffer strSb = new StringBuffer(); InputStreamReader inStrR = new InputStreamReader(new FileInputStream( file), "gbk"); BufferedReader br = new BufferedReader(inStrR); String line = br.readLine(); while (line != null) { strSb.append(line).append("\r\n"); line = br.readLine(); } return strSb.toString(); } // 分词处理 public static ArrayList<String> cutWords(String file) throws IOException { ArrayList<String> fenci = new ArrayList<String>(); ArrayList<String> words = new ArrayList<String>(); String text = TestTfIdf.readFile(file); IKAnalyzer analyzer = new IKAnalyzer(); fenci = analyzer.split(text); // 分词处理 BufferedReader StopWordFileBr = new BufferedReader( new InputStreamReader(new FileInputStream(new File( stopWordTable)))); // 用来存放停用词的集合 Set<String> stopWordSet = new HashSet<String>(); // 初如化停用词集 String stopWord = null; for (; (stopWord = StopWordFileBr.readLine()) != null;) { stopWordSet.add(stopWord); } for (String word : fenci) { if (stopWordSet.contains(word)) { continue