LSI潜在语义空间基本原理与代码实现Word文档格式.docx
- 文档编号:22178024
- 上传时间:2023-02-02
- 格式:DOCX
- 页数:13
- 大小:412KB
LSI潜在语义空间基本原理与代码实现Word文档格式.docx
《LSI潜在语义空间基本原理与代码实现Word文档格式.docx》由会员分享,可在线阅读,更多相关《LSI潜在语义空间基本原理与代码实现Word文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
4
SVD分解[2]
SVD分解作为掌握LSA的基础知识,我单独把它作为一篇文章,可以在这里找到。
5LSA技术细节[1][3]
本节主要讨论LSA技术细节的理论部分,具体代码层面分析和实践在第7节讨论。
LSA的步骤如下:
1.分析文档集合,建立Term-Document矩阵。
2.对Term-Document矩阵进行奇异值分解。
3.对SVD分解后的矩阵进行降维,也就是奇异值分解一节所提到的低阶近似。
4.使用降维后的矩阵构建潜在语义空间,或重建Term-Document矩阵。
下面是IntroductiontoLatentSemanticAnalysis里面的一个例子,描述了完整的LSA步骤,例子后面有我的补充:
假设文档集合如下:
原始的Term-Document矩阵如下:
对其进行奇异值分解:
然后对分解后的矩阵降维,这里保留{S}的最大两个奇异值,相应的{W}{P}矩阵如图,注意{P}在公式中需要转置。
到了这一步后,我们有两种处理方法,论文IntroductiontoLatentSemanticAnalysis是将降维后的三个矩阵再乘起来,重新构建了{X}矩阵如下:
观察{X}矩阵和{X^}矩阵可以发现:
{X}中human-C2值为0,因为C2中并不包含human单词,但是{X^}中human-C2为0.40,表明human和C2有一定的关系,为什么呢?
因为C2:
”Asurveyofuseropinionofcomputersystemresponsetime”中包含user单词,和human是近似词,因此human-C2的值被提高了。
同理还可以分析其他在{X^}中数值改变了的词。
以上分析方法清晰的把LSA的效果显示出来了,也就是在{X^}中呈现出了潜在语义,然后希望能创建潜在语义空间,并在该空间中检索信息。
这里以比较两个单词为例:
设奇异值分解形式为:
X=TSDT,T代表term,s代表singlevalue矩阵,D代表Document,DT表示D的转置。
X的两个行向量点乘(内积)的值代表了两个词在文档中共同出现的程度。
比如T1在D1中出现10词,T2在D1中出现5次,T3在D1中出现0词,那么只考虑在D1维度上的值,T1(dot)T2=50,T1(dot)T2=0,显然T1与T2更相似,T1与T3就不那么相似。
那么用矩阵X(dot)XT就可以求出所有词与词的相似程度。
而由奇异值分解的公式的:
X(dot)XT
=T(dot)S2(dot)TT
=TS(dot)(TS)T
上面公式表明了,我们想求X(dot)XT的(i,j)个元素时,可以点乘TS矩阵的第i和j列来表示。
因此我们可以把TS矩阵的行看作是term的坐标,这个坐标就是潜在语义空间的坐标。
同理我们还可以推出XT(dot)X=D(dot)S2(dot)DT,从而DS的行表示了文档的坐标。
这样,我们就获得了所有文档和单词在潜在语义空间的坐标,这时我们就可以通过向量间的夹角来判断两个对象的相似程度,方法和传统向量空间模型相同。
接下来主要讨论下检索文本的步骤。
用户输入的检索语句被称为伪文本,因为它也是有多个词汇构成,和文本相似。
所以很自然的想法就是将该伪文本转换为文档坐标,然后通过比较该伪文档与每个文档的空间夹角,检索出该伪文本的相关文档。
设Xq表示伪文本的列向量,其中该列代表文档集合的索引词,该列的值代表伪文本中该索引词出现的次数。
比如一个文档集合有索引词{T1,T2,T3},伪文本为t1,t3,t2,t1,则Xq={2,1,1}。
获得Xq后,通过公式
Dq
=XqT
TS-1
计算伪文档的文档坐标。
其中T和S分别代表奇异分解中得到的矩阵(S=TSDT).注意上面的公式中S-1代表S的逆矩阵。
Dq计算出来后,就可以迭代比较Dq和文档集合中所有所有文档,计算两者个cosine夹角
6LSA实践
本节主要讨论LSA的实现,编程语言使用C++,环境Linuxgcc,使用了GNUScientificLibrary[5]。
本节代码可以在
1.创建Term-Document矩阵
LSA是基于向量空间模型的,因此首先需要创建一个MxN的Term-Document矩阵,其中行表示每一个词,列表示每一个文档。
而矩阵的值等于相应词的TF*IDF值。
待检索的文档集合放在程序根目录下的corpus文件夹,每一个文档一个文件。
首先需要创建语料的单词列表,作为T-D矩阵的列向量,每一个单词对应一个id。
[code=cpp]
CreateVectorSpace.cc
FunctionintCreateKeyWordMap()
//循环读入每个文档
while((ent=readdir(currentDir))!
=NULL)
{
//omit.and..
if((strcmp(ent->
d_name,"
.&
quot
==0)||(strcmp(ent->
..&
==0))
continue;
else
//readeachfileindirectory'
corpus'
stringfilename="
./corpus/"
;
filename+=ent->
d_name;
ifstreamin(filename.c_str());
//checkiffileopensucceeded
if(!
in)
cout<
<
"
error,cannotopeninputfile"
endl;
return-1;
}
Parse();
//分析单词
[/code]
在循环的过程中,识别每一个单词,并判断该单词是否为stopword。
英文的stopword可以在ftp:
//ftp.cs.cornell.edu/pub/smart/english.stop找到。
FunctionParse()
//readonechareachtime
//thenrecognizeawordandcheckifitisinthestoplist
voidParse(ifstream*in,int*wordIndex)
stringpendingWord;
charch;
while
(1)
……
LETTER(ch))/*afterrecognizedaword*/
stoplist.count(pendingWord))
/*ifnotexistinthelist*/
if(wordList.find(pendingWord)==wordList.end())
wordList.insert(make_pair(pendingWord,*wordIndex));
(*wordIndex)++;
接下来需要处理单词,由于英文单词有前缀和后缀,如单词的单复数(book->
books),过去时(like->
liked),这些词虽然形式不同但含义相同,因此要将它们处理为同一的形式,也就是单词的原型。
相关的算法为PorterStemming[6]算法。
获得单词列表后,就可以构造T-D矩阵了,过程是依次读入每个文档,遇到单词列表中存在的词,相应的矩阵单元加1。
这里用到了GSL的几个函数,用法可参考GSL手册[5]。
FunctionCreateMatrix()
gsl_matrix*CreateMatrix()
//分配T-D矩阵空间
gsl_matrix*mtx=gsl_matrix_alloc(wordList.size(),docList.size());
map<
string,int>
:
const_iteratormap_it=docList.begin();
//foreachdocument
while(map_it!
=docList.end())
…..
//如果当前单词在单词列表中存在
if(wordList.find(pendingWord)!
=wordList.end())
//矩阵相应的单元值加1
gsl_matrix_set(mtx,wordList[pendingWord],map_it->
second,
gsl_matrix_get(mtx,wordList[pendingWord],map_it->
second)+1);
wordCount[map_it->
second]+=1;
现在已经创建了T-D矩阵,但是矩阵单元值为单词在文档中出现的频率,因此下一步是求每个单词的TF*IDF值[7]。
TF代表单词在某一文档中出现的频率,IDF为inversedocumentfrequency,代表的含义是如果一个单词在很多文档中都出现了,那么用它来区分文档的价值就降低。
具体公式:
SVD.CC
FunctionCreateTfIdfMatrix()
gsl_matrix*CreateTfIdfMatrix()
doubletermfrequence=gsl_matrix_get(mtx,i,j)/wordCount[j];
doubleidf=log((double)docList.size()/(double)getDocumentFrequence(mtx,i));
gsl_matrix_set(mtx,i,j,termfrequence*idf);
至此T-D矩阵创建完成。
2.SVD分解
SVD分解使用GSL库中的gsl_linalg_SV_decomp函数
SVD.cc
FunctionCountSVD(gsl_matrix*)
voidCountSVD(gsl_matrix*mtx)
//S=USV^Tsofirstlet'
sallocateU,S,Vthesethreematrix
v_mtx=gsl_matrix_alloc(docList.size(),docList.size());
/*VisaNbyNmatrix*/
s_vct=gsl_vector_alloc(docList.size());
/*Sisstoredinan-dvector*/
gsl_vector*workspace=gsl_vector_alloc(docList.size());
/*workspaceforgslfunction*/
gsl_linalg_SV_decomp(mtx,v_mtx,s_vct,workspace);
3.降维
降维在程序你实现十分简单,也就是给矩阵(由于是对角矩阵,因此程序里表示为向量)赋值零。
FunctionReduceDim(int)
voidReduceDim(intkeep)
for(inti=keep;
i<
docList.size();
i++)
gsl_vector_set(s_vct,i,0);
4.查询
SVD分解完成后,我们就已经获得了潜在语义空间,接下来就可以接受用户的输入,将伪文本转换到文档坐标,然后通过比较向量的夹角,找出相关文档。
voidQuery(stringquery)
//transformqueryintoLSAspace
istringstreamstream(query);
stringword;
//为Xq创建gsl向量,Xq表示伪文本的列向量
gsl_vector*q_vct=gsl_vector_alloc(wordList.size());
//为Dq创建gsl向量,Dq表示伪文本的文档向量
gsl_vector*d_vct=gsl_vector_alloc(LSD);
//首先计算Xq
while(stream>
>
word)
if(wordList.count(word)!
=0)/*wordisinthelist*/
gsl_vector_set(q_vct,wordList[word],
gsl_vector_get(q_vct,wordList[word])+1);
//Dq=Xq'
TS^-1
//再求Xq'
乘T
for(inti=0;
i<
LSD;
i++)
doublesum=0;
for(intj=0;
j<
wordList.size();
j++)
sum+=gsl_vector_get(q_vct,j)*gsl_matrix_get(mtx,j,i);
gsl_vector_set(d_vct,i,sum);
//最后求(Xq'
T)S^-1
for(intk=0;
k<
k++)
gsl_vector_set(d_vct,k,
gsl_vector_get(d_vct,k)*(1/gsl_vector_get(s_vct,k)));
//用文档集合中每个文档和Dq比较
for(intl=0;
l<
l++)
//求两向量夹角,返回cosine值
relation=CompareVector(d_vct,temp_d_vct,LSD);
5.测试
我们先用以前讨论过的文档集
将C1~M4分别保存到9个文件里,放到corpus文件夹
运行程序,输入格式为lsa.out[query]
./lsa.outhumancomputerinteraction
可以看出与主题最相关的文档是C3,其次是C1。
C1~C5文件是同主题文档,主题是人机互交,而M1~M4的共同主题是计算机图形。
而查询”humancomputerinteraction”显然描述的是人机互交。
因此也可以从结果看到C1~C5的相关度全部都高于M1~M4文档。
最后,观察C3,C5文档,它们并不包含任何查询中的词,而计算出的相似度却不为0,并且C3的相似度达0.999658,这也正是LSA潜在语义的效果。
下面是文档两两比较后的结果表格(已导入到Excel)
上图1~9和A~B都分别代表文档{C1,C2,C3,C4,C5,M1,M2,M3,M4}
上图非常清晰的显示出了文档的关系:
先来看[1~5][A~E]也就是第1~5行,
A~E列,由于文档C1~C5是一个主题的文档,所以可以看出[1~5][A~E]都大于0.9,而[1~5][F~I]都不超过0.5,也表明C1~C5文档与M1~M4文档主题是不相干的。
同理可以分析[6~9][F~I]。
上面的讨论表明,潜在语义分析在主题分类上效果明显。
如果设定一个分类的阈值,比如0.8,那么上面9个文档就被自动分为了{C1,C2,C3,C4,C5}和{M1,M2,M3,M4}
在另一个测试中,我从NewYorkTimes网站收集的6个主题,每个主题5篇文章
搜索”whatagreatday”结果如下:
伪文本坐标(0.00402821,-0.0183549,0.00361756),每个文档的相关度如果设定检索阈值为0.9,那么文档movie2,sport4,art2被返回。
7总结
LSA通过对潜在语义空间的建模,提高的信息检索的精确度。
而后又有人提出了PLSA(Probabilisticlatentsemanticanalysis)和LDA(LatentDirichletallocation),将LSA的思想带入到概率统计模型中。
LSA对一词多义问题依然没有解决,仅仅解决了一义多词。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- LSI 潜在 语义 空间 基本原理 代码 实现