เครื่องมือค้นหาที่ไร้เดียงสามากใช้งานโดยใช้ Django-2.1.3, python3.6
ฉันยังใหม่กับ Django และไม่ค่อยเชี่ยวชาญด้านการเขียน ดังนั้นโค้ดนี้จึงมีไว้สำหรับอ้างอิงเท่านั้น
หน้าแรก
การแบ่งหน้า
เราจำเป็นต้องบันทึกดัชนีแบบกลับด้าน เช่นเดียวกับเวลาที่ส่ง ผู้ส่ง หัวเรื่อง ลิงก์หัวข้อ ฯลฯ ที่สอดคล้องกับหัวข้อ ดังนั้นฉันจึงออกแบบโครงสร้างฐานข้อมูลต่อไปนี้
isIndexed
)ควรสังเกตว่าการเพิ่มคู่คีย์-ค่า ไม่สามารถ ใช้โค้ดต่อไปนี้ได้
word . index [ doc . id ] = num
word . save ()
ควร
dic = word . index
dic [ doc . id ] = num
word . index = dic
word . save ()
รับด้านล่างเป็นรหัสสำหรับรุ่นใน django
from django . db import models
class Doc ( models . Model ):
sendTime = models . DateField () # 2018-12-12 , differ from DateTimeField which can be datetime or date
sender = models . CharField ( max_length = 20 )
messageType = models . CharField ( max_length = 20 ) # Journal, conf, et al
subject = models . CharField ( max_length = 100 )
begin = models . DateField ()
deadline = models . DateField ()
subjectUrl = models . CharField ( max_length = 100 )
webpageUrl = models . CharField ( max_length = 100 )
desc = models . CharField ( max_length = 250 , default = '' )
loc = models . CharField ( max_length = 40 , default = '' )
keywords = models . CharField ( max_length = 200 , default = '' )
def __str__ ( self ):
return self . subjectUrl
import json
class Wordindex ( models . Model ):
word = models . CharField ( max_length = 45 )
# model to store a list, another way is to create a custom field
_index = models . TextField ( null = True )
@ property
def index ( self ):
return json . loads ( self . _index )
@ index . setter
def index ( self , li ):
self . _index = json . dumps ( li )
def __str__ ( self ):
return self . word
class File ( models . Model ):
doc = models . OneToOneField ( Doc , on_delete = models . CASCADE )
content = models . TextField ( null = True )
isIndexed = models . BooleanField ( default = False )
def __str__ ( self ):
return 'file: {} -> doc: {}' . format ( self . id , self . doc . id )
ที่แรกก็คือหน้าแรกมีโครงสร้างดังนี้:
< TBODY >
< TR VALIGN = TOP >
< TD > 03-Jan-2019 </ TD >
< TD > conf. ann. </ TD >
< TD > marta cimitile </ TD >
< TD > < A HREF =" http://www.cs.wisc.edu/dbworld/messages/2019-01/1546520301.html " rel =" nofollow " > Call forFUZZ IEEE Special Session </ A > </ TD >
< TD > 13-Jan-2019 </ TD >
< TD > < A rel =" nofollow " HREF =" http://sites.ieee.org/fuzzieee-2019/special-sessions/ " > web page </ A > </ TD >
</ TR > </ TBODY >
มีความสม่ำเสมอและสามารถแตกไฟล์ได้โดยตรง ในระหว่างการใช้งาน ฉันใช้แพ็คเกจ BeautifulSoup ของ python เพื่อแตกไฟล์
ระหว่างการใช้งาน สิ่งสำคัญคือการส่ง parser ฉันลองใช้ html แล้ว แต่มีปัญหากับ lxml ในที่สุดฉันก็ใช้ html5lib
จากนั้นจะมีคอลัมน์ที่สี่ (นั่นคือแท็ก td ที่สี่) ในตารางด้านบน โดยที่แท็ก <a>
คือลิงก์ไปยังหน้าเว็บที่มีหัวข้อนั้นอยู่ จะต้องแยกออกด้วย
เนื่องจากเวลาและสถานที่มีรูปแบบทั่วไป จึงสามารถแสดงรายการและจับคู่รูปแบบทั่วไปได้โดยใช้นิพจน์ทั่วไป
เมื่อใช้อัลกอริธึม textrank ฉันใช้อัลกอริธึม textrank ขั้นพื้นฐานด้วยตัวเอง แต่ผลที่ได้แย่มาก ต่อมาฉันใช้ text-rank เวอร์ชันอย่างเป็นทางการ
ส่วนนี้ยึดตามหลักการของดัชนีแบบกลับด้าน การแบ่งส่วนข้อความหน้าเว็บเป็นคำ ลบเครื่องหมายวรรคตอนออก ฯลฯ จากนั้นใช้โมเดลฐานข้อมูลที่แนะนำข้างต้นเพื่อจัดเก็บดัชนีแบบกลับด้าน
ขั้นแรก ด้านล่างชื่อคือแถวของตัวเลือก ซึ่งสามารถจัดเรียงตามฟิลด์เหล่านี้ได้ จากนั้นจะมีปุ่มอัปเดตในแถวถัดไป และแบบฟอร์มการส่งการค้นหา
เนื้อหาต่อไปนี้คือผลการค้นหาที่จัดเรียงโดยใช้ div
ผลลัพธ์แต่ละรายการประกอบด้วยชื่อเรื่อง คำสำคัญ เวลา สถานที่ และสรุป
ที่นี่ฉันใช้อัลกอริธึม tf-idf
ด้วยตัวเองเพื่อเรียงลำดับผลลัพธ์ รหัสมีดังนี้
def tfidf ( words ):
if not words : return docs
ct = process ( words )
weight = {}
tf = {}
for term in ct :
try :
tf [ term ] = Wordindex . objects . get ( word = term ). index
except Exception as e :
print ( e )
tf [ term ] = {}
continue
for docid in tf [ term ]:
if docid not in weight :
weight [ docid ] = 0
N = len ( weight )
for term in ct :
dic = tf [ term ]
for docid , freq in dic . items ():
w = ( 1 + log10 ( freq )) * ( log10 ( N / len ( dic ))) * ct [ term ]
if term in stopWords :
w *= 0.3
weight [ docid ] += w
ids = sorted ( weight , key = lambda k : weight [ k ], reverse = True )
if len ( ids ) < 8 : pass #???
return [ Doc . objects . get ( id = int ( i )). __dict__ for i in ids ]