从理论上讲,特征维度越多,需要的样本就越多,否则计算出来的分类模型和一个普通
的线性模型差不多。比如在采用 svm 进行分类的时候,如果维度大而样本少,其结果和不
采用任何非线性核函数的结果差不多。另外一方面,如果纬度太多,任何算法的计算速度都
会下降很严重。特征简约(feature reduce)是一种常见的降维技术(即减少特征维度),它
通常有如下几种技术:
1111)df df df df:根据特征在文档中出现的频率
2222)IG: IG: IG: IG: 根据信息增益
3333)MI: MI: MI: MI:
4444)CHI: CHI: CHI: CHI:
5555)SD: SD: SD: SD: 标准差
6666)DF*IDF DF*IDF DF*IDF DF*IDF
7777)DF*IDF*SD DF*IDF*SD DF*IDF*SD DF*IDF*SD
本文编写了一段代码,试图用一些简单的例子来证明哪种技术更好。此代码的思路如下:
1111)构造一个样本矩阵
举例来说,现在已知有 4 个类,而现在 4 个词语。把每个类包含的词语个数向量组合在
一起,构造一个矩阵,
假设为:
1111 1111 1111 1111
2222 2222 1111 1111
1111 1111 0000 0000
1111 0000 0000 0000
1111 1111 1111 0000
这里,第一行表示第一个词语在每个类中都出现了一次,
第二行表示第二个词语在前面 2 个类中出现了 2 次,在后面 2 个类中各出现了 1 次。
2222)人工分析
直观上面来说,我们根据上面的矩阵,可以了解到如下信息:
1、第一个词语没有任何分离度,它不包含啥有效信息;因为它在每个类中出现的次数
一样;
我们给它的参考分值为 0;
2、第二个词语有一定分离度,它具有明显的偏向性。
我们给它的参考分值为 0.4;
3、第三个词语分离度较高,可以把 4 个类划分为 2 部分。
我们给它的参考分值为 0.45;第 2页
4、第四个词语区分度很高,有它存在的文档几乎可以认为就是属于第一个分类了。
我们给它的参考分值为 0.8;
5、第五个词语的分离度也很高,没有它的时候,有一定概率属于第 4 个分类。
我们给它的参考分值为 0.45;
3333)实际检验
用程序跑一遍,看看效果和自己人工分析的是否一致。
代码如下:
/**
* 测试特征简约的各种算法效果
* 结果分析:
*
*- CHI 和 DF*IDF*SD 的效果好于其他算法
- *
* 参考文献:
*
*- [97][Yiming Yang, Jan O. Pedersen] A comparative study on feature
* selection in text categorization - *
- [08][熊忠阳, 黎刚, 陈小莉, 陈伟] 文本分类中词语权重计算方法的改进与应用
- *
*
* @author goodzhu
*
*/
public class TestFeatureReduce {
static double one = 10; // 每个类的文档个数
static double total = one * 4; // 总文档个数
static int[][] tfss = {
{ 1, 1, 1, 1 }, // 每个类里面包含本词语的文档个数。建议分数:0
{ 2, 2, 1, 1 }, // 建议分数:0.4
{ 1, 1, 0, 0 }, // 建议分数:0.45
{ 1, 0, 0, 0 }, // 建议分数:0.8
{ 1, 1, 1, 0 } // 建议分数:0.5
};
// df
public static void testDF() {
System.out.println(“df: “);
for (int[] tfs : tfss) {
double pt = 0; // p(t)
for (int tf : tfs) {第 3页
if (tf == 0)
continue;
pt += tf;
}
System.out.println(pt / total);
}
}
// ig
public static void testIG() {
System.out.println(“ig: “);
for (int[] tfs : tfss) {
double pt = 0; // p(t)
double pct = 0;
double pnotct = 0;
for (int tf : tfs) {
if (tf == 0)
continue;
pt += tf;
pct += tf / one * Math.log(tf / one);
pnotct += (1 - tf / one) * Math.log(1 - tf / one);
}
double p = 1 + pt / total * pct + (1 - pt / total) * pnotct;
System.out.println(p);
}
}
// mi
public static void testMI() {
System.out.println(“mi: “);
for (int[] tfs : tfss) {
double pt = 0; // p(t)
for (int tf : tfs)
pt += tf;
double avgItc = 0;
for (int tf : tfs) {第 4页
if (tf == 0)
continue;
double itc = Math.log(tf / one / (pt / total * one / total));
// double itc = Math.log(tf * total / one * pt);
avgItc += itc * (one / total);
}
System.out.println(avgItc);
}
}
// chi
public static void testCHI() {
System.out.println(“chi: “);
for (int[] tfs : tfss) {
double pt = 0; // p(t)
for (int tf : tfs)
pt += tf;
double avgX2tc = 0;
for (int tf : tfs) {
double A = tf;
double B = pt - tf;
double C = one - tf;
double D = total - (pt - tf) - one;
double N = total;
avgX2tc += N * (A * D - C * B) * (A * D - C * B)
/ ((A + C) * (B + D) * (A + B) * (C + D))
* (one / total);
}
System.out.println(avgX2tc);
}
}
// sd 标准差
public static void testSD()
{
System.out.println(“sd: “);
for (int[] tfs : tfss) {第 5页
double avg = 0;
for (int tf : tfs)
avg += tf;
avg /= tfs.length;
double st = 0;
for (int tf : tfs) {
st += (tf - avg) * (tf - avg);
}
st = Math.sqrt(st / (tfs.length - 1) );
System.out.println(st);
}
}
// df * idf
public static void testDFIDF()
{
System.out.println(“df * idf: “);
for (int[] tfs : tfss) {
double df = 0;
for (int tf : tfs)
{
if(tf > 0)
df ++;
}
double dfidf = df * Math.log(tfs.length / df + 0.1);
System.out.println(dfidf);
}
}
// df * idf * sd
public static void testDFIDFSD()
{
System.out.println(“df * idf * sd: “);
for (int[] tfs : tfss) {
double df = 0;
for (int tf : tfs)
{
if(tf > 0)第 6页
df ++;
}
double dfidf = df * Math.log(tfs.length / df + 0.1);
double avg = 0;
for (int tf : tfs)
avg += tf;
avg /= tfs.length;
double sd = 0;
for (int tf : tfs) {
sd += (tf - avg) * (tf - avg);
}
sd = Math.sqrt(sd / (tfs.length - 1) );
double dfidfsd = dfidf * sd;
System.out.println(dfidfsd);
}
}
public static void main(String[] args) {
testDF();
testIG();
testMI();
testCHI();
testSD();
testDFIDF();
testDFIDFSD();
}
}
实际结论:CHI 和 DF*IDF*SD 的效果好于其他算法。
参考文献:
[97][Yiming Yang, Jan O. Pedersen] A comparative study on feature selection in text
categorization
[08][熊忠阳, 黎刚, 陈小莉, 陈伟] 文本分类中词语权重计算方法的改进与应用