⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 irmodel.cpp

📁 一个信息检索模型
💻 CPP
字号:
#include "stdafx.h"
#include <iostream>
#include <tchar.h>
#include <string>
#include <time.h>
#include <fstream>

#include <vector>
#include <map>
#include <set>

using namespace std;

#include "IRModel.h"
// Using DLL
#include "ELUS_Use.h" // Dynamic Link Lib: ELUSCORE.dll Import Lib: ELUSCORE.lib
// Training Dll
#include "JELUSStatInterface.h" //Dynamic Link Lib: ELUSTRAIN.dll  Import Lib :ELUSTRAIN.lib
// Dict Manager Dll
#include "JELUSDictInterface.h" // Dynamic Link Lib: ELUSDICT.dll  Import Lib :ELUSDICT.lib
// Encode Convert Dll
#include "InsunEncodeToolkit.h" // Dynamic Lib: InsunEncode.dll  Import Lib: InsunEncode.lib

int IRModel::docSequence = 0;

/*
	函数功能:自动下载网页
	返回值	:
	参数	:
	作者	:岳
	日期	:2007-10-26	
	描述    :用到图论中的遍历(Traverse) 算法
*/


/*
	函数功能:分词
	返回值	:保存分词结果文件列表的文件名
	参数	:未处理的文件列表的文件名
	作者	:岳
	日期	:2007-10-26
	描述    :建立索引的过程:识别文档中的词;删除停用词;提取词干;从某一个文件列表中读取文档集合,作为网络爬虫的替代形式。即目前不做WEB搜索暂时。
  
*/

string  IRModel::WordSegment(string FileList)
{
	
	fstream fFileList(FileList.c_str(),ios_base::in);
	string::size_type indexOfDoc = FileList.find_last_of(".");
	string WSFileList = FileList.substr(0,indexOfDoc) + "_ws" + "." + FileList.substr(indexOfDoc + 1);
	fstream fWSFileList(WSFileList.c_str(), ios_base::out);
	if(!fFileList.good())
	{
		cout << "File List file can not open, please check" << endl;
	}
	if(!fWSFileList.good())
	{
		cout << "File List file can not open, please check" << endl;
	}

	string LibPath = ".\\ELUS.ini";//ConfigFile Path
	HObject m_Obj = NewELUSObject( LibPath.c_str() );//申请ELUS对象,所有资源挂载于此对象	

	string AFileName;
	while(getline(fFileList,AFileName))
	{
		wstring SegRlt;
		string tmp="";
		int count=0;
		int totleByte = 0;
		ifstream inFile(AFileName.c_str());
		indexOfDoc = AFileName.find_last_of(".");
	    string WSFileName = AFileName.substr(0,indexOfDoc) + "_ws" + "." + AFileName.substr(indexOfDoc + 1);
		ofstream outFile(WSFileName.c_str());
		if(!inFile.good())
		{
			cout << "file waiting to WS process can not open ,please check" << endl;		
		}

		while( getline(inFile,tmp ) )
		{
			totleByte += tmp.length();
			//Performs Seg & Pos to every line in the file
			SegRlt = ViterbiSeg( GbToUni( tmp.c_str() ) , m_Obj );
			outFile << UniToGb( SegRlt.c_str() ) << endl;
			if(++count%10000==0)
				cout<<count/10000<<"lines Already Done!\r";
		}
		fWSFileList << WSFileName << endl;
		inFile.close();
		outFile.close();
	}
	FreeAllELUSObject();
	return WSFileList;
}

/*
	函数功能:初步建立索引
	返回值	:
	参数	:经过分词处理的文件列表的文件名
	作者	:岳
	日期	:
	修订	:
	日期	:2007-10-26
	描述    :建立索引的过程:识别文档中的词;删除停用词;提取词干时。建立的是索引的TF-DF,即暂时不是IDF。
  
*/

void IRModel::EstablishIndex(string WSFileList)
{
	fstream infileList(WSFileList.c_str(), ios_base::in);
	if(!infileList.good())
		cout << "file list: "<< WSFileList << "can not open ,please check" << endl;
	
	string AFileName;
	int wordSequence;
	string line; //存放从文件中读入的一行文件

	while(getline(infileList, AFileName))
	{
		fstream infile(AFileName.c_str(), ios_base::in);
		if(!infile.good())
			cout << AFileName << "can not open, please check" << endl;
		sequence_doc.insert(valT_Seq_Doc(++docSequence, string(AFileName)));
		wordSequence = 0;
	 
		//读入分词后的文件,建立文件的 TF 项和索引项在此文件中的位置容器,并改变索引项的IDF
		while(getline(infile, line))
		{
			/*以行为单位建立索引*/
			index_line(line, wordSequence); 
		}
	}
}

/*
	函数功能:以行为单位建立索引
	返回值	:
	参数	:读入的分词后文件的某行
	作者	:岳
	日期	:
	修订	:
	日期	:2007-11-6
	描述    :
*/

void IRModel::index_line(string line, int wordSequence)
{
	int TF = 0;
	int DF = 0;
	string word;
	string::size_type pos = 0, prev_pos = 0;

	Locs * pLocs;	
	TF_Locs * pTF_Locs;  
	Doc_locs * pDoc_locs;
	IndexTermLocs * pIndexTermLocs;
	IDF_IndexTerm * pIDF_IndexTerm;   //<IDF, indexTerm>
	Index * pIndex = &invertedIndex;

	while((pos = line.find("  ",prev_pos))!= string::npos)
	{
		word = line.substr(prev_pos, pos - prev_pos);
        prev_pos = pos + 2;
		wordSequence++;

		if( stopWord_set.count(word) )
			continue;

		//如果此单词在索引项中不存在
		if(! invertedIndex.count(word))
		{
		
            pLocs = new Locs;	
			pTF_Locs = new TF_Locs;  
			pDoc_locs = new Doc_locs;
			pIndexTermLocs = new IndexTermLocs;
			pIDF_IndexTerm = new IDF_IndexTerm;
		

			pLocs->push_back(wordSequence);
            TF = 1;
			pTF_Locs -> first = TF;
			pTF_Locs -> second = *pLocs;
			pDoc_locs ->insert(ValT_Doc_locs(docSequence, *pTF_Locs));
			pIndexTermLocs ->push_back(*pDoc_locs);
            DF = 1;
          	pIDF_IndexTerm ->first = DF;
			pIDF_IndexTerm ->second = *pIndexTermLocs;
			pIndex ->insert(ValT_Word_IndexTerm(word, *pIDF_IndexTerm));

			delete pLocs;
			delete pTF_Locs;  
			delete pDoc_locs;
			delete pIndexTermLocs;
			delete pIDF_IndexTerm;					
		}	
		//如果此单词在索引项中存在
		else
		{
			pIDF_IndexTerm = &(invertedIndex[word]);
			pIndexTermLocs  = &(pIDF_IndexTerm->second);
		
			IndexTermLocs::iterator iter_indexTermLocs = pIndexTermLocs ->begin();
			int count = 0; 

			Doc_locs doc_locs;	

			for(; iter_indexTermLocs != pIndexTermLocs ->end(); iter_indexTermLocs++)
			{
				if((*iter_indexTermLocs).count(docSequence))
				{
					count = (*iter_indexTermLocs).count(docSequence);
					doc_locs = (*iter_indexTermLocs);
					break;
				}
			}
			//如果此单词未在此文档中出现
			if(count == 0)
			{   
				pLocs = new Locs;	
				pTF_Locs = new TF_Locs;  
				pDoc_locs = new Doc_locs;
				
				pLocs->push_back(wordSequence);
				TF = 1;
				pTF_Locs -> first = TF;
				pTF_Locs -> second = *pLocs;
				pDoc_locs ->insert(ValT_Doc_locs(docSequence, *pTF_Locs));
				pIndexTermLocs->push_back(*pDoc_locs);
                DF = (pIDF_IndexTerm ->first);
				pIDF_IndexTerm ->first = ++DF;	

				pIDF_IndexTerm ->second = *pIndexTermLocs;
                (*pIndex)[word] = *pIDF_IndexTerm;
				
				delete pLocs;
				delete pTF_Locs;  
				delete pDoc_locs;
			}
			//此单词在此文档中出现过
			else
			{	
				pIndexTermLocs->erase(iter_indexTermLocs);
            
				pDoc_locs = &doc_locs;
				pTF_Locs = &((*pDoc_locs)[docSequence]);  
				pLocs = &(pTF_Locs->second);
				pLocs ->push_back(wordSequence);
				TF = (pTF_Locs ->first);
				pTF_Locs ->first = ++TF;

				pTF_Locs -> second = *pLocs;
		    	(*pDoc_locs)[docSequence] = *pTF_Locs;
				pIndexTermLocs->push_back(*pDoc_locs);
				pIDF_IndexTerm ->second = *pIndexTermLocs;
				(*pIndex)[word] = *pIDF_IndexTerm;

			}
		}			
	}
}

/*
	函数功能:初始化停用词表
	返回值	:
	参数	:无
	作者	:岳
	日期	:
	修订	:
	日期	:2007-11-6
	描述    :
*/

void IRModel::initStopWordSet()
{
	/*english stop word*/
    stopWord_set.insert("(");
	stopWord_set.insert(")");
	stopWord_set.insert(",");
	stopWord_set.insert(".");
	stopWord_set.insert(";");
	stopWord_set.insert("?");
	stopWord_set.insert("i");
	stopWord_set.insert("me");
	stopWord_set.insert("we");
	stopWord_set.insert("our");
	stopWord_set.insert("ours");
	stopWord_set.insert("you");
	stopWord_set.insert("they");
	stopWord_set.insert("them");
	stopWord_set.insert("their");
	stopWord_set.insert("theirs");
	stopWord_set.insert("of");
	stopWord_set.insert("the");
	stopWord_set.insert("and");
	stopWord_set.insert("or");
	stopWord_set.insert("not");

	/*中文标点符号词*/
	stopWord_set.insert("(");
	stopWord_set.insert(")");
    stopWord_set.insert(",");
	stopWord_set.insert("。");
	stopWord_set.insert(";");
	stopWord_set.insert("?");

	stopWord_set.insert("我");
	stopWord_set.insert("我们");
	stopWord_set.insert("你");
	stopWord_set.insert("你们");
	stopWord_set.insert("他");
	stopWord_set.insert("他们");
	stopWord_set.insert("的");
	stopWord_set.insert("了");
	stopWord_set.insert("过");
	stopWord_set.insert("向");
    stopWord_set.insert("要");
	stopWord_set.insert("也");
	stopWord_set.insert("是");
	stopWord_set.insert("有");
	stopWord_set.insert("一");
	stopWord_set.insert("一个");
	stopWord_set.insert("又");
	stopWord_set.insert("于");
	stopWord_set.insert("在");
	stopWord_set.insert("再次");
	stopWord_set.insert("做");
	stopWord_set.insert("指出");
	//stopWord_set.insert("");
	//stopWord_set.insert("");
	//stopWord_set.insert("");
	//stopWord_set.insert("");
	//stopWord_set.insert("");
	//stopWord_set.insert("");
	//stopWord_set.insert("");
	//stopWord_set.insert("");
	//stopWord_set.insert("");


}

/*
	函数功能:删除索引中的停用词,更新停用词表
	返回值	:
	参数	:无
	作者	:岳
	日期	:
	修订	:
	日期	:2007-10-26
	描述    :如果某个词的
*/

void  IRModel::deleteStopWords()
{
	Index::iterator iter = invertedIndex.begin(), iter_end = invertedIndex.end(), iter_deleted;
	short DF;
	string word;

	while(iter != iter_end)
	{
		DF = (((*iter).second).first);
		word = (*iter).first;
				
		if(DF == docSequence)
		{
			cout << "删除的单词为:" << word << endl;	
			stopWord_set.insert(word);
			iter_deleted = iter;
			iter++;
			invertedIndex.erase(iter_deleted);		
		}
		else
            iter++;
	}
}

/*
	函数功能:遍历索引
	返回值	:
	参数	:无
	作者	:岳
	日期	:
	修订	:
	日期	:2007-10-26
	描述    :
  
*/
void  IRModel::displayIndex()
{
	Index::iterator iter_index = invertedIndex.begin(), iter_end_index = invertedIndex.end();
	int indexSequence = 0;

	for(; iter_index != iter_end_index; iter_index++)
	{
		cout<< "第" << ++indexSequence<<"个索引项:\"" << ((*iter_index).first) << "\",出现在" <<(*iter_index).second.first << "篇文章中" <<endl;
		IndexTermLocs::iterator iter_indexTermLocs = (*iter_index).second.second.begin(),
			iter_end_indexTermLocs = (*iter_index).second.second.end();
		for(; iter_indexTermLocs != iter_end_indexTermLocs; iter_indexTermLocs++)
		{
			Doc_locs::iterator iter_Doc_locs = (*iter_indexTermLocs).begin(),
				iter_end_Doc_locs = (*iter_indexTermLocs).end();
			/*以在其中出现过的文章为单位处理*/
			for(; iter_Doc_locs != iter_end_Doc_locs; iter_Doc_locs++)
			{
				Sequence_Doc::iterator iter_Sequence_Doc;
				iter_Sequence_Doc = sequence_doc.find((*iter_Doc_locs).first);
				if(iter_Sequence_Doc != sequence_doc.end())
				{
					string path = (*iter_Sequence_Doc).second; 
					cout << "    出现在第" << (*iter_Doc_locs).first << "篇文章中,路径为:" << path << endl;
				}
				else 
					cout << "    文件路径错误" << endl;

				Locs::iterator iter_Locs = (*iter_Doc_locs).second.second.begin(),
					iter_end_Locs = (*iter_Doc_locs).second.second.end();

				cout << "        共出现了" << (*iter_Doc_locs).second.first << "次" << endl;
				for(; iter_Locs != iter_end_Locs; iter_Locs++)
				{
					cout << "        出现位置为:第"<<(*iter_Locs) << "个单词" << endl;
				}			 
			}		
		}
	}

	cout << endl << "索引显示完毕" << endl;
}
/*
	函数功能:文档集合处理
	返回值	:
	参数	:
	作者	:岳
	日期	:
	修订	:
	日期	:2007-10-26
	描述    :建立索引的过程:识别文档中的词;删除停用词;提取词干;从某一个文件列表中读取文档集合,作为网络爬虫的替代形式。即目前不做WEB搜索暂时。
  
*/

//void IRModel::DocumentsProcess(string fileList)
//{
//	fstream fFileList(fileList,ios_base::in);
//	string AFileName;
//	WordSegment(fFileList);
//	EstablishIndex(fFileList);		
//	}
//
//
//}



/*
	函数功能:衡量网页的质量
	返回值	:
	参数	:
	作者	:岳
	日期	:
	修订	:
	日期	:2007-10-26
*/



/*
	函数功能:确定一个文档和某个查询的相关性
	返回值	:查询和某篇文档的相似度
	参数	:query -- 查询
	          documentSequence -- 文档序号
	作者	:岳
	日期	:2007-11-6
	描述    :向量空间模型。TF-IDF
*/
//int IRModel::query_document_similarity(string query, short documentSequence)
//{
//	//对查询句子分词
//	string LibPath = ".\\ELUS.ini";//ConfigFile Path
//	HObject m_Obj = NewELUSObject( LibPath.c_str() );//申请ELUS对象,所有资源挂载于此对象	
//	wstring SegRlt = ViterbiSeg( GbToUni( query.c_str() ) , m_Obj );
//	query = UniToGb( SegRlt.c_str() ) ;
//	FreeAllELUSObject();
//
//   
//	return 0;
//}



/*
	函数功能:网页排名
	返回值	:
	参数	:
	作者	:岳
	日期	:
	修订	:
	日期	:2007-10-26

*/

/*
	函数功能:
	返回值	:
	参数	:
	作者	:岳
	日期	:
	修订	:
	日期	:2007-10-26
*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -