1、项向量是一组由项-频率对组成的集合。
1)设一个文档只包括cat和dog两个项,一共有2个文档,向量可表示为图形上的有方向的直线,一个向量就是一个文档。2个项因为是一个二维空间,cat为y轴,dog为x轴。向量为从(0,0)出发到(x,y)截止。x表示dog在该向量表示的文档中出现的频率,y表示cat在该向量表示的文档中出现的频率。
如果是3个文档,则有三个向量,这三个向量表示为3条从原点出发的直线,在第一象限。如果有3个项,5个文档,则表示为一个三维空间,空间内有5条向量,分别表示5个文档。
2)向量之间的夹角越接近,这2个向量的特征就越相似,这2个文档就越相似.
2、查找相似书
1)
public class BooksLikeThis{
public static void main()throws IOException{
String indexDir=System.getProperty("index.dir");
FSDirectory directory=FSDirectory.getDirectory(indexDir,false);
IndexReader reader=IndexReader.open(directory);
int numDocs=reader.maxDoc();
BooksLikeThis blt=new BooksLinkThis(reader);
for(int i=0;i<numDocs;i++){
System.out.println();
Document doc=reader.document(i);
System.out.println(doc.get("title"));
//查找与这本书类似的书,遍历每一本书
Document[] docs=blt.docsLike(i,10);
if (docs.length==0){
System.out.println(" None likethis");
}
for(int j=0;j<docs.length;j++){
Document likeThisDoc=docs[j];
System.out.println("->"+likeThisDoc.get("title"));
}
}
}
private IndexReaderreader;
private IndexSearchersearcher;
publicBooksLinkeThis(IndexReader reader){
this.reader=reader;
searcher=newIndexSearcher(reader);
}
public Document[]docsLike() throws IOException{
Document doc=reader.document(id);
//对作者相同的书进行因子增强,一本书可以有多个作者
String[] authors=doc.getValues("author");
BooleanQuery authorquery=new BooleanQuery();
for (int i=0;i<authors.length;i++){
String author=authors[i];
authorQuery.add(newTermQuery(new Term("author",author)),false,false);
}
authorQuery.setBoost(2.0f);
//使用项向量,项为subject,getTermFreqVector得到项的频率
TermFreqVector vector=reader.getTermFreqVector(id,"subject");
BooleanQuerysubjectQuery=new BooleanQuery();
for (int j=0;j<vector.size();j++){
TermQuerytq=new TermQuery(new Term("subject",vector.getTerms()[j]));
subjectQuery.add(tq,false,false);
}
//创造最终查询对象
BooleanQuery likeThisQuery=new BooleanQuery();
likeThisQuery.add(authorQuery,false,false);
likeThisQuery.add(subjectQuery,false,false);
likeThisQuery.add(newTermQuery(newTerm("isbn",dco.get("isbn"))),false,true);
Hitshits=searcher.search(likeThisQuery);
int size=max;
if (max>hits.length()) size=hits.length();
Document[]docs=new Document(size);
for(int i=0;i<size;i++){
docs[i]=hits.doc[i];
}
return docs;
}
}
2)按向量角计主题中包括extreme、agile、methodology,则这本书属于/technology/computers/programming/methodology分类。
public void testCategorization() throws Exception{
assertEquals("/technology/computers/programming/methodology",getCategory("extremeagilemethodology"));
}
为每个类别建立向量
public class CategorizerTest extends testcase{
Map categoryMap;
protected void setUp()throws Exception{
super.setUp();
categoryMap=new TreeMap();
buildCategoryVectors();
}
}
private void buildCategoryVectors() throws IOException{
IndexReader reader=IndexReader.open(directory);
intmaxDoc=reader.maxDoc();
for (inti=0;i<macDoc;i++){
if (!reader.isDeleted(i)){
Document doc=reader.document(i);
String category=doc.get("category");
Map vectorMap=(Map) categoryMap.get(category);
if (vectorMap==null){
vectorMap=new TreeMap();
categoryMap.put(category,vectorMap);
}
TermFreqVectortermFreqVector=reader.getTermFreqVector(i,"subject");
addTermFreqToMap(vectorMap,termFreqVector);//将文档各个项的频率加入
//到分类中。
}
}
}
private void addTermFreqToMap(Map vectorMap,TermFreqVectortermFreq){
String[] terms=termFreqVector.getTerms();
int[] freqs=termFreqVector.getTermFrequencies();
for (int i=0;i<term.length;i++){
Stringterm=terms[i];
if (vectorMap.contiansKey(term)){
Integer value=(Integer) vectorMap.get(term);
vectorMap.put(term,newInteger(value.intValue()+freqs[i]));
}
else {
vectorMap.put(term,new Integer(freq[i]));
}
}
}
得到新书与每个类别向量之间的夹角,找到最匹配的类别
private String getCategory(String subject){
String[]words=subject.split(" ");
IteratorcategoryIterator=categoryMap.keySet().iterator();
doublebestAngle=Double.MAX_VALUE;
StringbestCategory=null;
while(categoryIterator.hasNext()){
Stringcategory=(String) categoryIterator.next();
double angle=computeAngle(words,category);
if (angle<bestAngle){
bestAngle=angle;
bestCategory=category;
}
}
return bestCategory;
}
计算向量夹角
private double computAngle(String[] words,String category){
MapvectorMap=(Map) categoryMap.get(category);
intdtProduct=0;
intsumOfSquares=0;
for (inti=0;i<words.length;i++){
String word=words[i];
int categoryWrodFreq=0;
if (vectorMap.containsKey(word)){
categoryWordFreq=((Integer)vectorMap.get(word)).intValue();
}
doProduct+=categoryWordFreq;
sumOfSquares+=categoryWrodFreq*categoryWordFreq;
}
doubledenominator;
if(sumOfSquares==words.length){
denominator=sumOfSquares;
}else{
denominator=Math.sqrt(sumOfSquares)+Math.sqrt(words.length);
}
doubleratio=dotProduct/denomiator;
returnMath.acos(ratio);
}
分享到:
相关推荐
1. **分词与索引**:Lucene使用高效的分词器将文档内容分解成独立的词汇项(tokens),然后建立倒排索引。倒排索引是一种数据结构,它将每个词汇项映射到包含该词汇项的文档列表,极大地加速了搜索过程。 2. **搜索...
《Lucene5学习之TermVector项向量》 在深入理解Lucene5的搜索引擎功能时,TermVector(项向量)是一个关键的概念,它对于文本分析、信息检索和相关性计算等方面起着至关重要的作用。TermVector是Lucene提供的一种...
4.9 版本是 Lucene 的一个重要里程碑,引入了多项改进和新特性,以优化搜索性能和用户体验。在本文中,我们将深入探讨 Lucene 4.9 的核心组件和关键功能。 1. **Lucene Core 模块**: Lucene 的核心模块包括索引和...
向量空间模型算法(VSM)**:通过计算查询向量与文档向量之间的相似度来确定相关性。 #### 二、Lucene的总体架构 Lucene的设计遵循模块化原则,其架构可以分为几个关键部分: - **存储层**:负责管理和维护索引...
- **位向量(Bit Vectors)**:用于布尔查询和删除标记,标记哪些文档包含特定项。 - **分块存储(Block Storage)**:如DocValues和Stored Fields,用于存储非文本数据。 以上各部分通过紧凑的数据结构和高效的...
- **文档向量(Document Vector)**:将每个文档表示为词项的集合,每个词项对应一个权重,权重通常由词频(Term Frequency, TF)和逆文档频率(Inverted Document Frequency, IDF)计算得出。 2. **倒排索引...
为了提高性能,Lucene提供了缓存机制、位向量(BitSet)以及分块索引等技术。此外,合理的硬件配置和索引策略也能显著提升搜索速度。 总的来说,《Lucene实战》第二版将带领读者深入了解Lucene的工作原理,通过...
在Lucene 3.0版本中,它引入了多项优化和改进,进一步提升了检索效率和用户体验。 **一、Lucene 3.0 的核心概念** 1. **索引**:Lucene首先将文档内容转换成倒排索引(Inverted Index),这是一个数据结构,用于...
索引的创建和维护由`src/core/org/apache/lucene/index`下的类完成,如IndexWriter负责写入索引,TermVectorsWriter处理词项向量,SegmentMerger合并段以优化索引。 3. 索引结构 倒排索引是Lucene的核心数据结构,...
- **片断(segments)**:Lucene使用多个独立的段来组织索引数据,这有助于提高性能并简化维护工作。 - **文档编号**:为了高效地管理文档,Lucene为每篇文档分配了一个唯一的数字ID。 - **索引结构概述**: - ...
Lucene使用的索引文件格式是其高效检索能力的关键所在。这些文件包括但不限于: - **SegmentInfo**:记录了每个段的元数据信息。 - **Fields**:存储了文档字段的信息。 - **Terms**:保存了索引中所有词汇及其统计...
4. **相关性评分**:Lucene使用向量空间模型(VSM)来评估文档与查询的相关性。这涉及到计算文档和查询向量之间的余弦相似度,其中向量的维度对应于词典中的词项,权重反映了词的重要性。 ### Lucene的总体架构 ...
5. **Term Vector查看**:Luke可以显示文档的词项向量(Term Vectors),这在进行相关性分析和查询优化时很有帮助。 6. **多语言支持**:随着Lucene对多种语言的支持,Luke也能够处理不同语言的索引,提供相应的...
全文检索技术是一项用于在大量非结构化文档中快速定位信息的技术,而Apache Lucene是一个高性能的全文检索引擎工具包,其提供了完整的搜索引擎实现,包括索引创建、搜索管理等功能。本文将对Lucene的基本原理及其...
此外,书中还探讨了Lucene的Perl、Python、C#、.Net和C++的移植版本,并介绍了排序、过滤、项向量特性以及对多索引和远程索引的搜索操作。针对新引入的SpanQuery特性、扩展的查询解析器以及命中结果集等功能也进行了...
Lucene为每个字段提供了不同的索引方式,例如词项向量、存储、索引和文档频率等。 ### Paoding中文分词 Paoding 是一个面向中文的分词器,它支持中文分词、自动识别词性、支持多种自定义词典和扩展字典等特性。在 ...
在VSM中,每个文档或查询被视为一个由词项构成的向量,每个词项是向量的一个维度,而词项的频率决定了对应维度的权重。通过计算两个向量之间的余弦相似度,可以评估文档与查询的相关性。 **Java实现VSM** Java作为...
例如,Lucene 1.4引入了排序、跨度查询和词项向量等新特性,而后续的版本则修复了一些性能问题并进行了优化。 Lucene的特点和优势显著,首先,它的索引文件格式是跨平台的,这意味着不同操作系统或应用可以共享同一...