信息检索作业
来源:互联网 发布:c语言初始化程序 编辑:程序博客网 时间:2024/05/22 06:11
# -*- coding:utf-8 -*- require './stemmable.rb' #词干还原代码require './correct2.rb' #peter novig拼写检查代码class Stringinclude Stemmable #字符串类包含进 词干还原模块, 字符串可以使用stem函数进行词干还原endwordCountHash=Hash.new #记录每个单词出现的频率fileListArray=Array.new #检索对象文档集合reverseIndexArray=Array.new #倒排记录表wordDfLocHash=Hash.new #字典,用ruby的hash类实现docLenArray=Array.new #记录文件距离 即每个文档的每个单词的权值平方和的二次根docNum=0 #检索对象文档树木def fileList(docPath, fileListArray) #获取指定路径下的所有文件名 并将文件名保存到数组 fileListArray 中nowPwd=Dir.pwd #获取当前路径Dir.chdir(docPath) #将当前工作目录改为 检索对象集合 所在路径Dir.foreach("./"){|fileName| fileListArray.push(fileName) if(fileName!="." && fileName!="..")}#将路径下所有文件名 存入 数组 fileList中。 会包含. ..目录,需要剔除掉 只支持一层目录#fileList=%x(ls)#fileList.scan(/[a-zA-Z0-9_\.]+/){|fileName| fileListArray.push(fileName)}Dir.chdir(nowPwd) #将当前工作目录 改为 最初的目录enddef file2word(docPath, fileName, fileID) #将文件fileName文件 中的单词 放入wcHash中并返回wcHash=Hash.new #单词计数 的 hash结构nowPwd=Dir.pwd #保存当前工作目录Dir.chdir(docPath) #改变工作目录到 检索对象集合 所在目录docfh=File.open(fileName, 'r') #打开文件fileNamewordArray=Array.new #保存文件中 词干还原处理过后 的单词docfh.readline.downcase.scan(/[a-z]+/){|word| wordArray.push(word.stem)} until docfh.eof wordArray.sort! #对单词数组进行排序wordArray.each do |word| if(word=="is" or word=="who" or word=="a" or word=="to") #去除停用词 next endif(wcHash[word]) #如果hash结构中存在该单词, 该单词计数+1wcHash[word][1]=wcHash[word][1]+1elsewcHash[word]=[fileID, 1] #如果hash结构中不存在该单词, 将该单词加入hash结构中,并加入当前文档ID, 单词计数为1endend # p "xxxxxxxxxxxxxxxxxxxx\n" #p wcHashDir.chdir(nowPwd) #将当前工作目录进行恢复return wcHash #返回hash结构 enddef makeReverseIndex(wordCountHash, reverseIndexArray, wordDfLocHash) #创建 词典 与 倒排记录表count=0wordCountHash.each do |key, value|#p wordCountHash[key]#p "========================="reverseIndexArray.push(value) #将 [ [文档ID,单词计数], ... ]信息存入倒排记录表wordDfLocHash[key]=[wordCountHash[key].length, count] #将对应的单词的 [出现该单词的文档数, 该单词所在倒排记录表的位置] 存入词典count+=1 #位置信息+1endenddef df2idf(wordDfLocHash, docNum) #计算idf值 # p wordDfLocHash # p docNumwordDfLocHash.each do |key, value|value[0]=Math.log(docNum.to_f/value[0], 10) #计算log(N/df)end #p "iiiiiiiiiiiiiiiiiiiiiii\n" #p wordDfLocHashenddef tf2tftd(reverseIndexArray) #计算tftd值reverseIndexArray.each do |valueArray| #对倒排记录表中每一个文档记录的单词频率进行处理 1+log(tf)valueArray.each do |value|value[1]=1+Math.log(value[1], 10)endendenddef tfdf2w(wordDfLocHash, reverseIndexArray) #计算(1+log(tf))*log(N/df)wordDfLocHash.each do |key, value|idf=value[0]loc=value[1]reverseIndexArray[loc].each do |value|value[1]=value[1]*idfendendenddef makeDocLen(docLenArray, reverseIndexArray) #计算每个文件的 距离#p docLenArrayreverseIndexArray.each do |valueArray|valueArray.each do |value|docLenArray[value[0]]=docLenArray[value[0]]+value[1]*value[1]endend#p docLenArraydocLenArray.each_index do |index|docLenArray[index]=Math.sqrt(docLenArray[index])end#p docLenArrayendfileList(ARGV[0], fileListArray) #返回指定 检索集合目录 下的所有文件名数组p fileListArrayfileListArray.sort! #对文件名数组进行排序#puts fileListArraydocNum=fileListArray.length #得到检索对象集合 的文档 总数#fileListArray.each_index{|index| p "#{index}: #{fileListArray[index]}"}fileListArray.each_index do |fileID| #对每一个属于检索对象集合的文件进行处理wcHash=file2word(ARGV[0], fileListArray[fileID], fileID) #返回当前文件的单词hash结构 “word” => [文档ID, 文档ID中"word"的个数]#p wcHashwcHash.each do |key, value|if(wordCountHash[key]) #如果所有文档单词hash中存在当前单词,则把当前文档的该单词信息存入所有文档单词hash中wordCountHash[key].push(value)elsewordCountHash[key]=Array.new.push(value) #如果不存在,则对该单词(作为key)创建新的valueendend#wordCountHash.merge!(wcHash) do |key, oldval, newval|#oldval.push(newval)#p wordCountHashend # wordCountHash: {"word" => [ [文档ID, 该单词计数], [文档ID, 该单词计数] ]}#p wordCountHashmakeReverseIndex(wordCountHash, reverseIndexArray, wordDfLocHash) #生成倒排记录表#p "============================================\n"#p reverseIndexArray#p "============================================\n"#p wordDfLocHash#p wordDfLocHashdf2idf(wordDfLocHash, docNum) #计算log(N/df)#p wordDfLocHash#p docNumdocLenArray=Array.new(docNum, 0) #docLenArray数组保存的 文档距离#p reverseIndexArraytf2tftd(reverseIndexArray) #计算1+log(tf)#p "aaaaaaaaaaaaaaaaaaaaaaaaa\n"#p reverseIndexArray#p "cccccccccccccccccccccc\n"#p wordDfLocHashtfdf2w(wordDfLocHash, reverseIndexArray) #计算(1+log(tf))*log(N/df)#p "=================================================="#p reverseIndexArraymakeDocLen(docLenArray, reverseIndexArray) #计算每个文档 距离#p docLenArrayprint "===========OK============\n" #索引建立完成def queryFunc(queryArray, wordDfLocHash, reverseIndexArray, fileListArray, docLenArray) #实现查询函数positionArray=Array.new qPositionArray=Array.newqReverseIndexArray=Array.newresultArray=Array.new tmpResultArray=Array.newqueryArray.each_index do |index| #对 查询数组 中的每个单词进行 词干还原queryArray[index]=queryArray[index].stem end queryArray.each do |value| #如果 查询数组 中的单词在 词典 中,输出"We find word" if(wordDfLocHash.has_key?(value)) puts "We find #{value}" end end#p queryArrayqueryArray.each do |word| #根据 词典 中查询数组中每个单词 所在 倒排记录表 的位置存入数组positionArrayif(wordDfLocHash.has_key?(word)) positionArray.push(wordDfLocHash[word][1])#positionArray.sort!{|x, y| reverseIndexArray[x].length <=> reverseIndexArray[y].length}endendpositionArray.sort!{|x, y| reverseIndexArray[x].length <=> reverseIndexArray[y].length} #将 位置信息 按照该位置元素所对应的倒排记录表记录项的长度进行排序(从小到大,从而最大限度减小 求交集的时间)if(positionArray.empty?) #如果位置信息数组为空,说明查询中的单词没有一个在字典中,输出"No doc matched"并退出print "No doc matched\n"returnend#p positionArray reverseIndexArray[positionArray[0]].each do |value| #将位置信息中第一个 单词 的 倒排记录表内容存入结果数组中,然后与剩余其他的所有数组进行求交集操作 resultArray.push(value) end # p "cccccccccccccccccccc\n" # p resultArray # p "dddddddddddddddddddd\n" # p reverseIndexArraypositionArray.each_index do |index| #求交集并将文档中所有单词的权重相加 # p "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy\n" position1=0 position2=0 # p "resultArray: #{resultArray}" if(index!=0) #因为第一个数组信息已经存入结果中,所以从第2个开始求交 tmpResultArray=[] # p "timsssssssssssssssss\n" # p "position1=#{position1}" # p "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh\n" # p resultArray # p reverseIndexArray[positionArray[index]] while(resultArray[position1]!=nil and reverseIndexArray[positionArray[index]][position2]!=nil) if(resultArray[position1][0]==reverseIndexArray[positionArray[index]][position2][0]) tmpResultArray.push([reverseIndexArray[positionArray[index]][position2][0], resultArray[position1][1]+reverseIndexArray[positionArray[index]][position2][1]]) position1+=1 position2+=1 elsif(resultArray[position1][0]<reverseIndexArray[positionArray[index]][position2][0]) position1+=1 else position2+=1 end end # p "index :#{index}" # p "tmpResultArray:#{tmpResultArray}" # p "resultArray :#{resultArray}" resultArray=[] tmpResultArray.each do |value| resultArray.push(value) end end #resultArray, tmpResultArray=tmpResultArray, resultArray #tmpResultArray.each do |value| # resultArray.push(value) #endend # p "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\n" # p resultArray # p tmpResultArray resultArray.each_index do |index| #查询结果文档的单词权重之和除以该文档距离 resultArray[index][1]=resultArray[index][1]/docLenArray[resultArray[index][0]] end resultArray.sort!{|x, y| x[1] <=> y[1]} #对查询结果按照权值大小进行排序(从小到大) resultArray.reverse! #求逆序 (从大到小) resultArray.each_index do |index| #输出排序结果 if(index<10) print "rank: #{index+1} \tfileName: ", fileListArray[resultArray[index][0]].ljust(30, ' '),"value:#{resultArray[index][1]}\n" end end # p "docLenArray: #{docLenArray}" # p "reverseIndexArray: #{reverseIndexArray}" # p "wordDfLocHash: #{wordDfLocHash}"#p wordDfLocHash#p reverseIndexArray#p fileListArray# reverseIndexArray.each do |value|# p value# endendqueryArray=Array.newif $0==__FILE__ then# p $stdin$stdin.each do |query|if(query=~/!!/)exit(0)endqueryArray=[]query.scan(/[a-zA-Z]+/){|word| queryArray.push(word) }#puts queryArray cQueryArray=Array.new allCorrect=1 queryArray.each do |word| cWord=correct(word) cQueryArray.push(cWord) if(cWord!=word) allCorrect=0 end end print "The query you input: #{queryArray}\n"queryFunc(queryArray, wordDfLocHash, reverseIndexArray, fileListArray, docLenArray) print "==========================================\n" if(allCorrect==0) print "The query we correct: #{cQueryArray}\n" queryFunc(cQueryArray, wordDfLocHash, reverseIndexArray, fileListArray, docLenArray) print "==========================================\n" endendend
ruby read5.rb setPath
0 0
- 信息检索作业
- 现代信息检索作业5
- 王斌 信息检索导论 现代信息检索 课程建议 大作业
- 《信息检索》第二周作业及第三周内容
- 《信息检索》第三周课件、推荐书籍 及 作业
- 现代信息检索作业5——2
- scrapy+Lucene搭建小型搜索引擎(现代信息检索大作业)
- 信息检索-布尔检索
- 信息检索
- 信息检索
- 信息检索
- 信息检索
- 信息检索
- 信息检索大作业:在Windows XP上搭建 nutch-0.9 搜索引擎环境
- 《信息检索》第二周作业——搜索、整理及相片上传
- 《离散数学》与《信息检索》第二周作业发布推迟到本周六,Sorry
- 信息检索笔记-布尔检索
- 信息检索之布尔检索
- 如何记录acrobat reader上次观看的位置
- Windows核心编程(九)同步设备I/O
- 用通俗易懂的大白话讲解Map/Reduce原理
- 我的第一篇blog
- licencefilepath =E:/tomcat7/wtpwebapps/cms3/data/fsmlicence/
- 信息检索作业
- 每天一个小程序(15)——交换排序之快速排序
- SSIS Package Development - Issues and Solutions
- Ubuntu12.10下安装lighttpd1.4.32详细步骤
- Ipad air里面的照片能恢复吗
- [递归]UVA11129 An antiarithmetic permutation
- java中内存泄露
- JS调用后台函数
- 使用AGSJSONRequestOperation完成webservice资源的请求