设为首页收藏本站

EPS数据狗论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 1752|回复: 0

使用SAS计算Word Mover的距离

[复制链接]

19

主题

162

金钱

253

积分

入门用户

发表于 2019-8-9 14:55:32 | 显示全部楼层 |阅读模式

Word Mover的距离(WMD)是用于衡量两个文档之间差异的距离度量,它在文本分析中的应用是由华盛顿大学的一个研究小组在2015年引入的。该小组的论文“ 从Word嵌入到文档距离”发表了在第32届国际机器学习大会(ICML)上。在本文中,他们证明了WMD度量导致8个真实世界文档分类数据集中前所未有的低k-最近邻文档分类错误率。

他们利用单词嵌入和WMD对文档进行分类,这种方法相对于传统方法的最大优点是它能够将单个单词对(例如总统和奥巴马)之间的语义相似性合并到文档距离度量中。以传统方式,操纵语义相似单词的一种方法是提供同义词表,以便算法在测量文档距离之前可以将具有相同含义的单词合并到代表性单词中,否则您将无法获得准确的相异性结果。然而,维护同义词表需要人类专家的不断努力,因此耗时且非常昂贵。此外,单词的语义含义取决于域,而通用同义词表不适用于不同的域。

Word Mover距离的定义
WMD是两个文档之间的距离,作为将所有单词从一个文档移动到另一个文档所需的最小(加权)累积成本。通过解决以下线性程序问题来计算距离。

T ij表示文档d中的单词i在文档d '中移动到单词j的多少;

c(i; j)表示从文件d中的单词i到文件d '中的单词j“行进”的费用; 这里的成本是word2vec嵌入空间中的两个词'欧几里德距离;

如果字我出现Ç 我在文档d次,我们记

WMD是地球移动器距离度量(EMD)的一个特例,这是一个众所周知的运输问题。

如何用SAS计算地球移动器的距离?
SAS / OR是解决运输问题的工具。图1显示了一个带有四个节点和节点之间距离的传输示例,我从这个Earth Mover的Distance文档中复制了这些节点。目标是找出从{x1,x2}到{y1,y2}的最小流量。现在让我们看看如何使用SAS / OR解决这个运输问题。

节点的权重和节点之间的距离如下。
1.png
图-1运输问题

  1. datax_set;input_node_ $ _sd_;datalines;x10.74x20.26;datay_set;input_node_ $ _sd_;datalines;y10.23y20.51;dataarcdata;input_tail_ $ _head_ $ _cost_;datalines;x1 y1155.7x1 y2252.3x2 y1292.9x2 y2198.2;proc optmodel;setxNODES;num w{xNODES};setyNODES;num u{yNODES};set ARCS;num arcCost{ARCS}; readdatax_setintoxNODES=[_node_]w=_sd_;readdatay_setintoyNODES=[_node_]u=_sd_;readdataarcdataintoARCS=[_tail_ _head_]arcCost=_cost_;varflow{inARCS}>=0;impvar sumY =sum{jinyNODES}u[j];minobj =(sum{inARCS}arcCost[i,j]* flow[i,j])/sumY;con con_y{jinyNODES}:sum{inARCS}flow[i,j]= u[j];con con_x{iinxNODES}:sum{<(i),j>inARCS}flow[i,j]<= w[i]; solve with lp / algorithm=ns scale=none logfreq=1;print flow;quit;
复制代码

SAS / OR的解决方案如表-1所示,EMD是目标值:203.26756757。
2.png
表-1 EMD用SAS / OR计算

我用SAS / OR表2得到的流量数据显示如下,与上述地球移动器距离文档中公布的图表相同。
3.png
表-2 SAS / OR的流量数据
4.png
图-2运输问题流程图


如何用SAS计算Word Mover的距离
本文从Word嵌入到文档距离,通过删除WMD的第二个约束来减少计算,提出了一个名为Relaxed Word Mover Distance(RWMD)的新度量。由于我们需要读取文字嵌入数据,因此我将向您展示如何使用SAS Viya计算两个文档的RWMD。
  1. /* start CAS server */cas casauto host="host.example.com"port=5570;libnamesascas1 cas;/* load documents into CAS */datasascas1.documents;infiledatalines delimiter='|'missover;lengthtext varchar(300);inputtext$ did;datalines;Obama speaks to the mediainIllinois.|1The President greets the pressinChicago.|2;run;/* create stop list*/datasascas1.stopList;infiledatalines missover;lengthterm $20;inputterm$;datalines;thetoin;run;/* load word embedding model */proc cas;loadtable path='datasources/glove_100d_tab_clean.txt'caslib="CASTestTmp"importOptions={fileType="delimited",delimiter='\t',getNames=True,guessRows=2.0,varChars=True}casOut={name='glove'replace=True};run;quit;%macrocalculateRWMD(textDS=documents,documentID=did,text=text,language=English,stopList=stopList,word2VectDS=glove,doc1_id=1,doc2_id=2);/* text parsing and aggregation */proc cas;textParse.tpParse/table={name="&textDS",where="&documentID=&doc1_id or &documentID=&doc2_id"}docId="&documentID",language="&language",stemming=False,nounGroups=False,tagging=False,offset={name="outpos",replace=1},text="&text";run; textparse.tpaccumulate/parent={name="outparent1",replace=1}language="&language",offset='outpos',stopList={name="&stoplist"},terms={name="outterms1",replace=1},child={name="outchild1",replace=1},reduce=1,cellweight='none',termWeight='none';run;quit;/* terms of the two test documents */proc cas;loadactionset"fedsql";execdirect casout={name="doc_terms",replace=true}query="

  2. select outparent1.*,_term_

  3. from outparent1

  4. left join outterms1

  5. on outparent1._termnum_ = outterms1._termnum_

  6. where _Document_=&doc1_id or _Document_=&doc2_id;

  7. ";run;quit;/* term vectors and counts of the two test documents */proc cas;loadactionset"fedsql";execdirect casout={name="doc1_termvects",replace=true}query="

  8. select word2vect.*

  9. from &word2VectDS word2vect, doc_terms

  10. where _Document_=&doc2_id and lowcase(term) = _term_;

  11. ";run; execdirect casout={name="doc1_terms",replace=true}query="

  12. select doc_terms.*

  13. from &word2VectDS, doc_terms

  14. where _Document_=&doc2_id and lowcase(term) = _term_;

  15. ";run; simple.groupBy /table={name="doc1_terms"}inputs={"_Term_","_Count_"}aggregator="n"casout={name="doc1_termcount",replace=true};run;quit;proc cas;loadactionset"fedsql";execdirect casout={name="doc2_termvects",replace=true}query="

  16. select word2vect.*

  17. from &word2VectDS word2vect, doc_terms

  18. where _Document_=&doc1_id and lowcase(term) = _term_;

  19. ";run; execdirect casout={name="doc2_terms",replace=true}query="

  20. select doc_terms.*

  21. from &word2VectDS, doc_terms

  22. where _Document_=&doc1_id and lowcase(term) = _term_;

  23. ";run; simple.groupBy /table={name="doc2_terms"}inputs={"_Term_","_Count_"}aggregator="n"casout={name="doc2_termcount",replace=true};run;quit;/* calculate Euclidean distance between words */datadoc1_termvects;setsascas1.doc1_termvects;run;datadoc2_termvects;setsascas1.doc2_termvects;run;proc iml;use doc1_termvects;read allvar_char_intolterm;read allvar_num_intox;closedoc1_termvects; use doc2_termvects;read allvar_char_intorterm;read allvar_num_intoy;closedoc2_termvects; d = distance(x,y); lobs=nrow(lterm);robs=nrow(rterm);d_out=j(lobs*robs, 3, ' ');doi=1to lobs;doj=1to robs;d_out[(i-1)*robs+j,1]=lterm[i];d_out[(i-1)*robs+j,2]=rterm[j];d_out[(i-1)*robs+j,3]=cats(d[i,j]);end;end;createdistancefromd_out;appendfromd_out;closedistance;run;quit;/* calculate RWMD between documents */datax_set;setsascas1.doc1_termcount;rename_term_=_node_;_weight_=_count_;run;datay_set;setsascas1.doc2_termcount;rename_term_=_node_;_weight_=_count_;run;dataarcdata;setdistance;renamecol1=_tail_;renamecol2=_head_;length_cost_8;_cost_= col3;run;proc optmodel;setxNODES;num w{xNODES};setyNODES;num u{yNODES};set ARCS;num arcCost{ARCS}; readdatax_setintoxNODES=[_node_]w=_weight_;readdatay_setintoyNODES=[_node_]u=_weight_;readdataarcdataintoARCS=[_tail_ _head_]arcCost=_cost_;varflow{inARCS}>=0;impvar sumY =sum{jinyNODES}u[j];minobj =(sum{inARCS}arcCost[i,j]* flow[i,j])/sumY;con con_y{jinyNODES}:sum{inARCS}flow[i,j]= u[j];/* con con_x {i in xNODES}: sum {<(i),j> in ARCS} flow[i,j] <= w[i];*/solve with lp / algorithm=ns scale=none logfreq=1;callsymput('obj', strip(put(obj,best.)));createdataflowDatafrom[i j]={inARCS: flow[i,j].sol >0}col("cost")=arcCost[i,j]col("flowweight")=flow[i,j].sol;run;quit;%putRWMD=&obj;%mendcalculateRWMD; %calculateRWMD(textDS=documents,documentID=did,text=text,language=English,stopList=stopList,word2VectDS=glove,doc1_id=1,doc2_id=2);



  24. proc printdata=flowdata;run;quit;
复制代码


WMD方法不仅可以测量文档的相似性,还可以通过可视化流数据来解释为什么这两个文档是相似的。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

客服中心
关闭
在线时间:
周一~周五
8:30-17:30
QQ群:
653541906
联系电话:
010-85786021-8017
在线咨询
客服中心

意见反馈|网站地图|手机版|小黑屋|EPS数据狗论坛 ( 京ICP备09019565号-3 )   

Powered by BFIT! X3.4

© 2008-2028 BFIT Inc.

快速回复 返回顶部 返回列表