利用Stanford Parser进行中文行为抽取

来源:互联网 发布:菠菜代源码论坛 编辑:程序博客网 时间:2024/05/22 10:23

转自twenz

利用Stanford Parser进行中文行为抽取(Action mining)

问题

所谓的行为抽取就是从开源文本中获取关于给定的某个人/组织的行为,主要包括主语、谓语和宾语。其中主语是给定的一些词表示了需要抽取的信息对象(人、组织或团体)。谓语和宾语则表示了行为。

例如,我们要抽取关于“塔利班”的行为,则给定句子“塔利班制造了这起爆炸。”的抽取结果为“塔利班:制造爆炸”。如果塔利班还有其他的别称(比如基地组织)或者我们有关于塔利班里面重要成员的可以代表塔利班行为的人等,则应把它们作为主语的行为也一并抽取出。

方法

这种关于行为抽取的显然是在句子层面上的工作,用统计机器学习方法可能效果不会很好(个人感觉)。

1.选择数据(数据源,如新闻等)

2.划分句子

3.筛选相关句子(找出含有识别对象的句子,直接匹配)

4.分词(把那些目标对象的词语加入到词典中,采用ICTCLAS)

5.语法分析(Stanford Parser)

6.抽取行为 (查找规律,利用规则匹配等方法,这里面应该有很多方法优化。我这里只是给出了一个简单的匹配搜索)

代码

public class Dependency {    LexicalizedParser lp = new LexicalizedParser("xinhuaFactored.ser.gz");    Tree parser;    TreebankLanguagePack tlp = new ChineseTreebankLanguagePack();    GrammaticalStructureFactory gsf = tlp.grammaticalStructureFactory();    GrammaticalStructure gs;        public Dependency(){}    public void parserToTree(String sent[]){        parser = lp.apply(Arrays.asList(sent));    }    public void getGrammaticalStructure(){        gs = gsf.newGrammaticalStructure(parser);    }    public void outputRalation(){        Collection tdl = gs.typedDependenciesCollapsedTree();        System.out.println(tdl);    }    private boolean relationSubj(String rel){        if(rel.contains("subj"))return true;        if(rel.contains("advmod"))return true;        if(rel.contains("nn"))return true;          return false;    }    private boolean relationObj(String rel){        if(rel.contains("obj"))return true;        if(rel.contains("comp"))return true;        return false;    }    public void extractAction(String agent)    {        Collection tdl = gs.typedDependenciesCollapsedTree();        int act = -1;        for(int i = 0;i < tdl.size();i ++)        {            //TypedDependency(GrammaticalRelation reln, TreeGraphNode gov, TreeGraphNode dep)             TypedDependency td = (TypedDependency)tdl.toArray()[i];            String age = td.dep().toString();            if(age.contains(agent) && relationSubj(td.reln().toString())){                act = td.gov().index();                System.out.print(agent+":");                String verb = td.gov().value();                System.out.print(verb+":");                break;            }            //System.out.println(td.gov().toString()+td.reln().toString()+td.dep().toString());        }        if(act == -1)return;        for(int i = 0;i < tdl.size();i ++)        {            //TypedDependency(GrammaticalRelation reln, TreeGraphNode gov, TreeGraphNode dep)             TypedDependency td = (TypedDependency)tdl.toArray()[i];            if(td.gov().index() == act)            {                if(relationObj(td.reln().toString()))                    System.out.print(td.dep().value());            }        }        System.out.println();    }    public void extractAction(String sentence,String agent){        String sent[] = sentence.split(" ");        System.out.println(sent.length);        if(sent.length > 55)return;        this.parserToTree(sent);        this.getGrammaticalStructure();        this.extractAction(agent);    }    public static void main(String args[]){        Dependency dep = new Dependency();        //String sentence = "塔利班 制造 了 这 起 爆炸 。";        String sentence = "昨日 , 圣元 又 遭 网友 质疑 , 称 其 利用 专家 之 名 , 制造 奶粉 安全 的 舆论 。";        String sent[] = sentence.split(" ");        dep.parserToTree(sent);        dep.getGrammaticalStructure();        dep.outputRalation();        dep.extractAction("网友");    }}


这里代码只是第5步和第6步的,经测试:能够抽取出一些简单的规范的行为。如果要提高准确率或召回率还需要不断地对规则进行修改。

分析

1.Stanford parser句法树分析时候占用内存可能较大,所以要调整eclipse虚拟内存空间,方法是在“运行——运行——自变量——VM自变量中填上-Xms256M -Xmx800M”,大小就要看实际情况和机子性能。另外还经常出现异常,还未找到有效办法解决。如句子较长出现“FactoredParser: exceeded MAX_ITEMS work limit [200000 items]; aborting.”解决办法参考:http://blog.amelielee.com/archives/140。在上面代码的构造函数中加上 Test.MAX_ITEMS = 3000000;

2.依赖关系树错误率很高,影响实际结果。据说哈工大的句法分析效果还不错,可以尝试。

3.因为句法分析的效果不佳,所以抽取的行为的依赖关系也不仅仅是 subj 和obj的主谓和渭滨关系,这就要进一步探索。另外还有很多的隐藏的行为、被动行为等都需要去改进。如“塔利班遭受政府军的严厉打击。”;“发动了这次袭击的塔利班武装分子撤出了阿富汗”隐含有行为“发动袭击”。

0 0
原创粉丝点击