博文转载请注明作者和出处(作者:finallyliuyu :出处博客园)

附:《卡方特征词选择算法》

  《DF特征词选择算法》

一.数学背景

将数学知识、数学理论以及数学思想迁移到实际工程问题中,经常会促进工程问题的圆满解决。

可是如何将数学知识引入工程问题中呢?首先需要有“数学思维”例如理解数学公式所刻画的内涵;其次需要有“建模”能力:从不同的视角来看待同一个问题,最后抽象出的数学模型也可能会差别很大。比如有的数学模型有现成的解决方案可用,然而有的数学模型没有现成的解决方案可用;或者有的模型比其他模型能更好地刻画和表示实际问题。如果把在头脑中搜索适合待解决实际问题的数学工具定义为“数学思维”,把将实际问题抽象成数学模型的能力定义为"”数学建模”的话,只有这两种能力配合“默契”才能更好地解决实际问题。或许我们从文本分类问题中的各种特征词选择方法能够看到些端倪。

首先先来看一些公式的含义

注意:上面的互信息公式有些错误,做如下更正:

平均互信息:(或叫做信息增益)

下面开开始介绍平均互信息与互信息在文本分类特征词选择算法中的应用

为了避免引起混淆,互信息在文本分类特征词选择中被称为point-wise MI;平均互信息被称作IG(Information Gain)。

参照 Manning《信息检索导论》p189页(王斌译作)的定义:

IG 公式为:

point-wise MI公式为

二.下面给出实现这两种算法的代码C++代码

point-wise MI 声明代码

double CalPointWiseMI(double N11,double N10,double N01,double N00);//计算pointwise MI;

vector<pair<string,double> >PointWiseMIFeatureSelectionForPerclass(DICTIONARY& mymap,CONTINGENCY& contingencyTable,string classLabel);

void PointWiseMIFeatureSelection(vector<string > classLabels,DICTIONARY& mymap,CONTINGENCY& contingencyTable,int N,char * address);

计算pointwiseMI的值

/************************************************************************/
/* 计算pointwiseMI的值                                                                     */
/************************************************************************/
double Preprocess:: CalPointWiseMI(double N11,double N10,double N01,double N00)
{
    double pointwiseMI=0;
    if(N11>0)
    {
        pointwiseMI=log(N11+N10+N01+N00)+log(N11)-log(N11+N10)-log(N11+N01);
    }
    return pointwiseMI;
}

计算每个词对每个类别的pointwiseMI

/************************************************************************/
/* 计算每个词对每个类别的pointwiseMI                                                                     */
/************************************************************************/
vector<pair<string,double> > Preprocess:: PointWiseMIFeatureSelectionForPerclass(DICTIONARY& mymap,CONTINGENCY& contingencyTable,string classLabel)
{
    int N=endIndex-beginIndex+1;//总共的文章数目
    vector<string>tempvector;//词袋子中的所有词
    vector<pair<string,double> > MIInfo;
    for(map<string,vector<pair<int,int>>>::iterator it=mymap.begin();it!=mymap.end();++it)
    {
        tempvector.push_back(it->first);
    }
    //计算卡方值
    for(vector<string>::iterator ittmp=tempvector.begin();ittmp!=tempvector.end();ittmp++)
    {
        int N1=mymap[*ittmp].size();
        pair<string,string> compoundKey=make_pair(*ittmp,classLabel);
        double N11=double(contingencyTable[compoundKey].first);
        double N01=double(contingencyTable[compoundKey].second);
        double N10=double(N1-N11);
        double N00=double(N-N1-N01);
        double miValue=CalPointWiseMI(N11,N10,N01,N00);
        MIInfo.push_back(make_pair(*ittmp,miValue));

}
    //按照卡方值从大到小将这些词排列起来
    stable_sort(MIInfo.begin(),    MIInfo.end(),isLarger);
    return MIInfo;

}

point-wise MI特征词选择法

/************************************************************************/
/* point-wise MI特征词选择法                                                                     */
/************************************************************************/
void Preprocess:: PointWiseMIFeatureSelection(vector<string > classLabels,DICTIONARY& mymap,CONTINGENCY& contingencyTable,int N,char * address)
{
    clock_t start,finish;
    double totaltime;
    int totalTraingingCorpus=endIndex-beginIndex+1;//训练语料库总共的文章数目
    set<string>finalKeywords;//存放最终遴选出的特征词
    vector<pair<string,double>>MIInfo;
    start=clock();
    for(vector<string>::iterator it=classLabels.begin();it!=classLabels.end();it++)
    {
        //训练语料库中某个类别的文章数目
        int N_subClassCnt=getCategorizationNum(*it,"TrainingCorpus");
        //threshold决定每个类别遴选多少个特征词
        int threshold=N_subClassCnt*N/totalTraingingCorpus;
        MIInfo=PointWiseMIFeatureSelectionForPerclass(mymap,contingencyTable,*it);
        for(vector<pair<string,double> >::size_type j=0;j<threshold;j++)
        {
            finalKeywords.insert(MIInfo[j].first);

}
        MIInfo.clear();

}

ofstream outfile(address);
    int finalKeyWordsCount=finalKeywords.size();
    for (set<string>::iterator it=finalKeywords.begin();it!=finalKeywords.end();it++)
    {
        outfile<<*it<<endl;

}
    outfile.close();
    cout<<"最后共选择特征词"<<finalKeyWordsCount<<endl;
    finish=clock();
    totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
    cout<<"遴选特征词共有了"<<totaltime<<endl;

}

信息增益特征词选择算法

double CalInformationGain(double N11,double N10,double N01,double N00);//计算IG值
vector<pair<string,double> >InformationGainFeatureSelectionForPerclass(DICTIONARY& mymap,CONTINGENCY& contingencyTable,string classLabel);
void InformationGainFeatureSelection(vector<string > classLabels,DICTIONARY& mymap,CONTINGENCY& contingencyTable,int N,char * address);

计算IG值

/************************************************************************/
/* 计算IG值                                                                     */
/************************************************************************/
double Preprocess::CalInformationGain(double N11,double N10,double N01,double N00)
{
    double IG=0;
    double Ntotal=N11+N10+N01+N00;
    double N1_=N11+N10;
    double N0_=N01+N00;
    double N_0=N10+N00;
    double N_1=N11+N01;
    if(N11>0)
    {
        IG+=N11/Ntotal*log(Ntotal*N11/(N1_*N_1));
    }
    if(N10>0)
    {
        IG+=N10/Ntotal*log(Ntotal*N10/(N1_*N_0));

}
    if(N01>0)
    {
        IG+=N01/Ntotal*log(Ntotal*N01/(N0_*N_1));
    }
    if(N00>0)
    {
        IG+=N00/Ntotal*log(Ntotal*N00/(N0_*N_0));
    }

return IG;
}

计算每个单词,对于某个类别的IG值,并排序

************************************************************************/
/* 计算每个单词,对于某个类别的IG值,并排序                                                                  */
/************************************************************************/
vector<pair<string,double> > Preprocess:: InformationGainFeatureSelectionForPerclass(DICTIONARY& mymap,CONTINGENCY& contingencyTable,string classLabel)
{
    int N=endIndex-beginIndex+1;//总共的文章数目
    vector<string>tempvector;//词袋子中的所有词
    vector<pair<string,double> > IGInfo;
    for(map<string,vector<pair<int,int>>>::iterator it=mymap.begin();it!=mymap.end();++it)
    {
        tempvector.push_back(it->first);
    }
    //计算卡方值
    for(vector<string>::iterator ittmp=tempvector.begin();ittmp!=tempvector.end();ittmp++)
    {
        int N1=mymap[*ittmp].size();
        pair<string,string> compoundKey=make_pair(*ittmp,classLabel);
        double N11=double(contingencyTable[compoundKey].first);
        double N01=double(contingencyTable[compoundKey].second);
        double N10=double(N1-N11);
        double N00=double(N-N1-N01);
        //double chiValue=CalChiSquareValue(N11,N10,N01,N00);
        double igValue=CalInformationGain(N11,N10,N01,N00);
        IGInfo.push_back(make_pair(*ittmp,igValue));

}
    //按照卡方值从大到小将这些词排列起来
    stable_sort(IGInfo.begin(),IGInfo.end(),isLarger);
    return IGInfo;

}

信息增益特征词选择算法

/************************************************************************/
/*    信息增益特征词选择算法                                                                         */
/************************************************************************/
void Preprocess::InformationGainFeatureSelection(vector<string > classLabels,DICTIONARY& mymap,CONTINGENCY& contingencyTable,int N,char * address)
{
    clock_t start,finish;
    double totaltime;
    int totalTraingingCorpus=endIndex-beginIndex+1;//训练语料库总共的文章数目
    set<string>finalKeywords;//存放最终遴选出的特征词
    vector<pair<string,double>>IGInfo;
    start=clock();
    for(vector<string>::iterator it=classLabels.begin();it!=classLabels.end();it++)
    {
        //训练语料库中某个类别的文章数目
        int N_subClassCnt=getCategorizationNum(*it,"TrainingCorpus");
        //threshold决定每个类别遴选多少个特征词
        int threshold=N_subClassCnt*N/totalTraingingCorpus;
        IGInfo=InformationGainFeatureSelectionForPerclass(mymap,contingencyTable,*it); 
        for(vector<pair<string,double> >::size_type j=0;j<threshold;j++)
        {
            finalKeywords.insert(IGInfo[j].first);

}
        IGInfo.clear();

}

ofstream outfile(address);
    int finalKeyWordsCount=finalKeywords.size();
    for (set<string>::iterator it=finalKeywords.begin();it!=finalKeywords.end();it++)
    {
        outfile<<*it<<endl;

}
    outfile.close();
    cout<<"最后共选择特征词"<<finalKeyWordsCount<<endl;
    finish=clock();
    totaltime=(double)(finish-start)/CLOCKS_PER_SEC;
    cout<<"遴选特征词共有了"<<totaltime<<endl;

}

附: DF特征词选择算法

转载于:https://www.cnblogs.com/finallyliuyu/archive/2010/10/04/1841820.html

从文本分类问题中的特征词选择算法追踪如何将数学知识,数学理论迁移到实际工程中去...相关推荐

  1. 文本分类中的特征词选择算法系列科普(前言AND 一)

    (转载请注明出处,作者:finallyliuyu) 前言: 经了解,园子里有很多已经工作,但是对信息检索和自然语言处理感兴趣的同仁,也有很多相关领域的从业者.目前本人正在从事文本特征选择方面的研究.所 ...

  2. 文本特征选择 java代码_文本分类入门(十)特征选择算法之开方检验

    前文提到过,除了分类算法以外,为分类文本作处理的特征提取算法也对最终效果有巨大影响,而特征提取算法又分为特征选择和特征抽取两大类,其中特征选择算法有互信息,文档频率,信息增益,开方检验等等十数种,这次 ...

  3. 文本分类入门(十)特征选择算法之开方检验

    前文提到过,除了分类算法以外,为分类文本作处理的特征提取算法也对最终效果有巨大影响,而特征提取算法又分为特征选择和特征抽取两大类,其中特征选择算法有互信息,文档频率,信息增益,开方检验等等十数种,这次 ...

  4. word2vec词向量 文本分类实现(TensorFlow版,算法TextCNN)

    之前也写过word2vec词向量文本分类实现,不过那是基于Keras. 今天来写下tensoflow版的代码. 再来感受下它的魅力. tensorflow比Keras更接近底层,可以更方便让我们理解W ...

  5. ACL 2020 | 消除文本分类问题中歧视现象的研究

    ©PaperWeekly 原创 · 作者|张冠华.白冰 研究机构|哈工大/腾讯 研究方向|自然语言处理 导语 文本分类问题是自然语言处理中的一个基础问题,旨在根据语义预测一句话的标签.常见的文本分类任 ...

  6. 达观数据携手CCF举办第五届“达观杯”自然语言处理文本分类竞赛 ,开赛报名中!

    作为国内领先的智能文本处理企业,达观数据主办发起"达观杯"人工智能算法竞赛,每年一届,至今已成功举办四届.2021年,在CCF(中国计算机学会)自然语言处理专业委员会的特别支持下, ...

  7. 文本分类step by step(二)

    (注:如有转载请标明作者:finallyliuyu, 和出处:博客园) <文本分类 step by step(一)> 在<文本分类step by step(一)>中,我们从处理 ...

  8. 菜鸟进阶: C++实现KNN文本分类算法

    作者:finallyliuyu(转载请注明原作者和出处) (代码暂不发布源码下载版,以后会发布) KNN文本分类算法又称为(k nearest neighhor).它是一种基于事例的学习方法,也称懒惰 ...

  9. 详解CNN实现中文文本分类过程

    摘要:本文主要讲解CNN实现中文文本分类的过程,并与贝叶斯.决策树.逻辑回归.随机森林.KNN.SVM等分类算法进行对比. 本文分享自华为云社区<[Python人工智能] 二十一.Word2Ve ...

最新文章

  1. 虚拟化--YESLAB DC Vphere5 上课PDF
  2. Containerpilot 配置文件reload
  3. springmvd接收参数问题
  4. otn系统中常用的电层_自动化系统中常用的液位计
  5. php 手机屏幕,90hz和60hz手机屏幕差别大吗
  6. 十大办法帮助传统产业数字化转型
  7. 马哥学习----李洋个人笔记----安全和加密
  8. Linux驱动认知简明导论③ —— 修改树莓派引脚文件pin4Driver.c操作IO口
  9. 重磅!中国三大数学奖全揭榜,8位数学大神获奖
  10. 2019.03.07【APIO2018】【洛谷P4630】【BZOJ5463】铁人两项(圆方树)(树形DP)
  11. Vue3学习笔记(B站李南江)
  12. 重置IE:专治IE疑难杂症的“万精油”(转)
  13. 微软雅黑字体包替换XP的宋体
  14. php guzzle并发,使用Guzzle并发请求接口
  15. 山科大数字高程模型(朱红春版)复习 2021
  16. 图像处理之简单综合实例(大米计数)
  17. element中设置5栏布局
  18. linux命令详解及软件安装(全)
  19. 《软件测试---你必须掌握的100个问题》
  20. mapreduce面试问题_MapReduce问题与解答第1部分

热门文章

  1. LeetCode 1961. 检查字符串是否为数组前缀
  2. LeetCode 1704. 判断字符串的两半是否相似
  3. LeetCode 1039. 多边形三角剖分的最低得分(区间DP)
  4. 往java里输入坐标值_java.让用户输入x坐标,和y坐标。当用户输入完x坐标(比如200),敲enter,...
  5. 【Python基础知识-pycharm版】第四节-元组
  6. 排序:插入排序与希尔排序
  7. c 语言银行排队系统,C++实现银行排队系统
  8. MYSQL快速导入大量数据
  9. centos mysql jar 驱动包_JDBC连接MySQL的数据库
  10. 【萌味】小夕说,不了解动态空间增长的程序喵都是假喵(上)