所謂索引建立,就是對一堆文檔的內容建立一個索引表,當然是傳說中的倒排索引。
倒排索引:
倒排索引源於實際應用中需要根據屬性的值來尋找記錄。這種索引表中的每一項都包括一個屬性值和具有該屬性值的各記錄的地址。由於不是由記錄來確定屬性值,而是由屬性值來確定記錄的位置,因而稱為倒排索引(inverted index)。帶有倒排索引的檔案我們稱為倒排索引檔案,簡稱倒排檔案(inverted file)。
為了繼續說明倒排檔案,看看一下兩個概念點:
(1)順排檔案
假設有網頁P1,P2,……,Pn,給每個網頁檔案賦予一個編號Pid,給每個關鍵字賦予一個編號keyi,假設key是網頁檔案中的一個關鍵字,ni表示該關鍵字在網頁檔案中出現的次數,<hit1,hit2,…,hitn>表示該關鍵字在網頁檔案中的位置資訊。首先將網頁內容切分成一系列關鍵字:Pi={Key1,key2,…,keyn}。建立以下順排檔案:
P1={[n1,Key1(hit1,hit2,…,hitn)],…,[nx,keyi(hit1,hit2,…,hitx)] }
P2={[n1,Key1(hit1,hit2,…,hitn)],…,[nn,keyk(hit1,hit2,…,hitn)] }
…………
Pn={[n1,Key1(hit1,hit2,…,hitn)],…,[ny,keyj(hit1,hit2,…,hity)] }
例如,對以下兩段文字進行順排檔案操作。
“隨著經濟的發展,人們對生活的品質要求越來越高。特別是在視覺欣賞方面,更是追求精益求精。如何把模糊的映像變得清晰,把暗淡的色彩變得色彩鮮豔是一個非常值得研究的課題。並且在數字電視、掃描器、醫學映像、電腦視覺、衛星監測、航空攝像等方面對映像的清晰度有著廣泛的需求。目前基於網格和密度的聚類方法已經滲透到各個領域,且得到了令人意想不到的效果。本文是將基於網格和密度的聚類方法運用到模糊映像中,從而對映像進行增色處理。”
“數位影像處理又稱為電腦影像處理,它是指將映像訊號轉換成數字訊號並利用電腦對其進行處理的過程。數位影像處理最早出現於20世紀50年代,當時的電子電腦已經發展到一定水平,人們開始利用電腦來處理圖形和映像資訊。數位影像處理作為一門學科大約形成於20世紀60年代初期。早期的影像處理的目的是改善映像的品質,它以人為對象,以改善人的視覺效果為目的。”
假設第一段文字是一個網頁P1的全部內容,段首的起始位置為1。第二段文字是第二個網頁P2的全部內容,段首的起始位置為1。
對網頁進行自動分詞,得到關鍵字以及關鍵字在網頁檔案中出現的位置資訊。順排檔案的結果為:
P1={[1,經濟(3)],[1,發展(6)],……,[2,視覺(26,93)],……,[5,映像(46,88,107,177,182)],……,[1,處理(189)]}
P2={[4,數字(1,29,48,101)],[8,映像(3,13,21,49,96,103,130,140)],……,[1,視覺(156)],……,[2,目的(135,161)]}
(2)倒排檔案
順排檔案是以網頁來索引關鍵字的,即形式為(網頁→關鍵字),不符合搜尋引擎的需要。因此,需進行倒排處理,以關鍵字來索引網頁,即形式為(關鍵字→網頁):
Keyi→{[Pid1,ni1(hit1,hit2,…,hitni1)],…,[Pidn,nin(hit1,hit2,…,hitnin)]}
對以上順排檔案中建立的兩個執行個體網頁P1和P2的順排檔案進行倒排,倒排檔案的結果為:
經濟→{[P1,1(3)]}
發展→{[P1,1(6)],[P2,1(74)]}
……
視覺→{[P1,2(26,93)],[P2,1(156)]}
……
映像→{[P1,5(46,88,107,177,182)],[P2,8(3,13,21,49,96,103,130,140)]}
……
綜上所述,倒排檔案的實現過程是:先得到順排檔案,然後根據順排檔案得到倒排檔案,從而實現由關鍵字來索引網頁。
再如,簡單建立以下兩個檔案的倒排索引。
1.txt——我愛我的祖國,我愛五星紅旗。
2.txt——我愛北京天安門。
則倒排檔案的內容結構為:
假設格式為:keyword——DocumentName1(frequency1),DocumentName2(frequency2),……,DocumentName_n(frequency_n)
我——1.txt(3),2.txt(1) 愛——1.txt(2),2.txt(1) …… 五——1.txt(1) 北——2.txt(1) |
Lucene是一款開源的索引/搜尋開源架構,通過基於Lucene可以構建索引引擎,以下給出個對Html等網頁檔案進行索引的執行個體代碼。
Index.java:
import java.io.File;import java.io.IOException;import java.util.List;import jeasy.analysis.MMAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.index.IndexWriter;import GEsearcher.index.html.HtmlParser;public class Index { //定義索引路徑和資料路勁 private String indexpath; private String datapath; /* * 設定和擷取函數 */ public String getDatapath() { return datapath; } public void setDatapath(String datapath) { this.datapath = datapath; } public String getIndexpath() { return indexpath; } public void setIndexpath(String indexpath) { this.indexpath = indexpath; } /* * 建立索引函數 */ public void DoIndex(boolean createnew) { FileManager filemanager=new FileManager(datapath);//擷取索引材料庫路徑 List<File> filelist=filemanager.getFileList(); //todo //開始建立索引 Object[] files= filelist.toArray(); int i=0;//testing for(Object o:files) { File f=(File) o; String extname=getFileExtendsName(f); if(extname.equals("html") || extname.equals("htm") || extname.equals("asp")) { HtmlParser hp=new HtmlParser(f.getPath());//解析html檔案 String title=hp.getTitle(); String url=hp.getUrl().replace("\\", "/"); String content=hp.getContent(); try { if(i==0 && createnew) { writeIndex(url, title, content, true); } else { writeIndex(url, title, content, false); } i++;//testing } catch (IOException e) { System.err.println("建立索引出錯!"); e.printStackTrace(); } } else{ //其他檔案格式的處理 } } System.out.println("建立html檔案數為:"+i);//testing } /* * 判斷副檔名 */ public String getFileExtendsName(File f) { String name=f.getName().toLowerCase(); int beginIndex=name.indexOf(".")+1; String res=name.substring(beginIndex); return res; } /* * 寫索引 */ public void writeIndex(String url,String title,String content,boolean createnew) throws IOException { IndexWriter writer=new IndexWriter(indexpath, new MMAnalyzer(), createnew); writer.setUseCompoundFile(true); Document doc=new Document(); Field url_f=new Field("url", url, Field.Store.YES, Field.Index.NO); Field title_f=new Field("title", title, Field.Store.YES, Field.Index.TOKENIZED); Field content_f=new Field("content",content,Field.Store.YES,Field.Index.TOKENIZED); doc.add(url_f); title_f.setBoost(2f); //加大標題命中得分率 doc.add(title_f); doc.add(content_f); writer.setMaxFieldLength(1000); writer.addDocument(doc);//把檔案寫入索引 writer.close(); }}
其中, setDatapath(String datapath)是設定待建立索引的材料檔案路徑(檔案夾),setIndexpath(String indexpath)是設定存放索引檔案的的目錄。writeIndex(String url,String title,String content,boolean createnew)方法是建立索引的核心程式單元,在建立索引過程中需要進行切詞,這裡使用jeasy.analysis.MMAnalyzer來實現。索引程式執行後,大致在存放索引的目錄上產生如所示的檔案。
至此,索引建立完畢!