Cómo construir un motor de búsqueda con Python y Laravel

Indexando un estructura de datos una técnica que le permite recuperar rápidamente registros de un archivo de base de datos. Se basa en los mismos atributos de los que están hechos los índices.

¿Qué es un motor de búsqueda basado en índices?

Un motor de búsqueda basado en índices en Python es un sistema que se basa en datos almacenados en un índice invertido para encontrar respuestas. Cuando un usuario ingresa una consulta de búsqueda, en lugar de buscar en todo el conjunto de listados de documentos uno por uno, escaneará el índice relevante para mostrar el resultado más cercano.

Momento índice es una pequeña mesa con sólo dos columnas. La primera columna contiene una copia de la clave primaria o candidata de la tabla. Su segunda columna contiene una matriz de punteros para almacenar la dirección del bloque de disco donde se almacena el valor de clave particular.

En programas de motores de búsquedaesto se llama un índice invertido.

¿Qué es un índice invertido?

Un índice invertido es una estructura de datos de índice o índice de base de datos creado para facilitar las consultas de búsqueda. Funciona asignando datos del contenido de la lista de documentos, como palabras o números, a ubicaciones en la lista de documentos. La búsqueda con palabras o números asignados será más rápida y eficiente que buscar en todo el documento uno por uno. liza.

¿Qué es una encuesta?

Una consulta, o una consulta de búsqueda, como se denomina en un motor de búsqueda, es una consulta basada en un término de búsqueda específico que un usuario ingresa en un motor de búsqueda para satisfacer sus necesidades de información.

Esta es una solicitud de información utilizando un motor de búsqueda. Cada vez que un usuario ingresa una cadena de caracteres en un motor de búsqueda y presiona la tecla “Enter”, se realiza una consulta del motor de búsqueda. Y la aplicación web mostrará los resultados de la consulta de búsqueda.

Requisitos para construir un motor de búsqueda basado en índices en Python

Debes tener:

  • pitón 3.xx
  • Administrador de paquetes PIP
  • Editor de código (en este tutorial usaré Visual Studio Code, opcional)

Paquete de requisitos

  • Biblioteca de pepinillos: Agrio es el módulo predeterminado instalado en Python 2 y Python 3. Si no se encuentra su módulo pickle, ejecute este comando en su terminal para instalar esta biblioteca:
pip install pickle-mixin

Usaremos el módulo acid para almacenar nuestro archivo de índice y cargar el archivo de índice cuando se llame a la consulta. El ácido es útil para mantener el módulo Pitón convertir objetos a archivo. Con esta función, usaremos acid para guardar nuestro diccionario de Python en un archivo, lo que nos permitirá leer los archivos más rápido.

Más sobre Python: PCA usando Python: un tutorial

Cómo crear un índice invertido en Python

Usaremos un diccionario de Python para crear un índice invertido. El diccionario almacenará el término como clave y la puntuación del documento como valor. De esta manera podemos almacenar un archivo de datos y un archivo de puntuación para cada palabra

Para ello, utilizaremos el término de frecuencia: técnica de frecuencia densa inversa (TF-IDF) para puntuar un documento.

TF-FDI es una técnica utilizada para encontrar el significado de oraciones y supera las deficiencias de la técnica de la bolsa de palabras. La técnica de la bolsa de palabras es buena para la clasificación de textos o para ayudar a una máquina a leer palabras en números.

Indexación de guiones con TF-IDF

import re
import sys
import json
import pickle
import math

#Argumen check
if len(sys.argv) !=3 :
	print ("\n\\Use python \n\t tf-idf.py [data.json] [output]\n")
	sys.exit(1)


#data argumen
input_data = sys.argv[1]
output_data = sys.argv[2]


data = open(input_data).read()
list_data = data.split("\n")

sw = open("stopword.txt").read().split("\n")

content=[]
for x in list_data :
	try:
		content.append(json.loads(x))
	except:
		continue


# Clean string function
def clean_str(text) :
	text = (text.encode('ascii', 'ignore')).decode("utf-8")
	text = re.sub("&.*?;", "", text)
	text = re.sub(">", "", text)    
	text = re.sub("[\]\|\[\@\,\$\%\*\&\\\(\)\":]", "", text)
	text = re.sub("-", " ", text)
	text = re.sub("\.+", "", text)
	text = re.sub("^\s+","" ,text)
	text = text.lower()
	return text



df_data={}
tf_data={}
idf_data={}

i=0;
for data in content :
	tf={} 
	#clean and list word
	clean_title = clean_str(data['book_title'])
	list_word = clean_title.split(" ")
	
	for word in list_word :
		if word in sw:
			continue
		
		#tf term frequency
		if word in tf :
			tf[word] += 1
		else :
			tf[word] = 1

		#df document frequency
		if word in df_data :
			df_data[word] += 1
		else :
			df_data[word] = 1

	tf_data[data['url']] = tf


# Calculate Idf
for x in df_data :
   idf_data[x] = 1 + math.log10(len(tf_data)/df_data[x])

tf_idf = {}

for word in df_data:
	list_doc = []
	for data in content:
		tf_value = 0

		if word in tf_data[data['url']] :
			tf_value = tf_data[data['url']][word]

		weight = tf_value * idf_data[word]

		doc = {
			'url' : data['url'],
			'title' : data['book_title'],
			'image' : data['image-url'],
			'price' : data['price'],
			'score' : weight
		}

		if doc['score'] != 0 :
			if doc not in list_doc:
				list_doc.append(doc)
		
		
	tf_idf[word] = list_doc

# Write dictionary to file
with open(output_data, 'wb') as file:
     pickle.dump(tf_idf, file)

Guión de línea de argumento

if len(sys.argv) !=3 :
   print ("\n\nPenggunaan\n\ttf-idf.py [data.json] [output]\n")
   sys.exit(1)
input_data = sys.argv[1]
output_data = sys.argv[2]
data = open(input_data).read()
list_data = data.split("\n")
#load Stopword
sw = open("stopword.txt").read().split("\n")
content=[]
for x in list_data :
    try:
        content.append(json.loads(x))
    except: continue

En el código anterior, cargué los datos que devolvimos del proceso de raspado e incluí un término de “palabra vacía” que no usamos para indexar. Escriba el siguiente comando para ejecutar el script:

python3 tf-idf.py  

es, es, es, es conjunto de datos es el resultado de este script que obtenemos cuando hacemos el proceso de raspado y lo convertimos en un archivo de índice.

Borrado de conjuntos de datos de cadena

# Clean string function                       
def clean_str(text) :                        
    text = (text.encode('ascii', 'ignore')).decode("utf-8")
    text = text.lower()                   
    text = re.sub("&.*?;", "", text)                        
    text = re.sub(">", "", text)                            
    text = re.sub("[\]\|\[\@\,\$\%\*\&\\\(\)\":]", "", text)               
    text = re.sub("-", " ", text)                        
    text = re.sub("\.+", "", text)                        
    text = re.sub("^\s+","" ,text)                        
                          
    return text

Como sugiere el nombre, esta función funciona para limpiar book_title de conjuntos de datos que contienen puntuación no válida.

Cómo calcular TF-IDF

Hay tres términos que debes saber:

  • Duración Frecuencia (TF): Este es el término frecuencia para todo el documento.
  • Frecuencia del documento (DF): Esta es la frecuencia del término de un documento en particular.
  • Frecuencia de documento inversa (IDF): Este es el valor que obtienes al calcular DF ​​con la fórmula: IDF =Log[(# Number of documents) / (Number of documents containing the word (DF))]

Con esta técnica TF-IDF podemos obtener el peso de cada palabra contra el documento. El peso de cada palabra es lo que usaremos como nuestro valor de puntuación. La fórmula para obtener este peso es: WEIGHT = TF * IDF

Guardar el índice en Archivo

with open(output_data, 'wb') as file:
   pickle.dump(tf_idf, file)

Este código guarda el diccionario en un archivo usando el módulo acid.

Creación de un script de consulta

El script de consulta que se generará debe poder leer el diccionario almacenado en el archivo anterior. Por supuesto, si lo guardó usando el módulo pickle, usaremos el módulo pickle para leerlo.

import re
import sys
import json
import pickle

#Argumen check
if len(sys.argv) != 4 :
	print ("\n\nPenggunaan\n\tquery.py [index] [n] [query]..\n")
	sys.exit(1)

query = sys.argv[3].split(" ")
n = int(sys.argv[2])

with open(sys.argv[1], 'rb') as indexdb:
	indexFile = pickle.load(indexdb)

#query
list_doc = {}
for q in query:
	try :
		for doc in indexFile[q]:
			if doc['url'] in list_doc :
				list_doc[doc['url']]['score'] += doc['score']
			else :
				list_doc[doc['url']] = doc
	except :
		continue


#convert to list
list_data=[]
for data in list_doc :
	list_data.append(list_doc[data])


#sorting list descending
count=1;
for data in sorted(list_data, key=lambda k: k['score'], reverse=True):
	y = json.dumps(data)
	print(y)
	if (count == n) :
		break
	count+=1

Cómo ejecutar un script de consulta

Para ejecutar este script, debe escribir este comando en la terminal:

python3 query.py   

es el index_file que creamos anteriormente en el módulo acid.

es el número de resultados que queremos mostrar.

es la palabra clave para la información que el usuario desea.

Cómo descargar un archivo de índice

with open(sys.argv[1], 'rb') as indexdb:
   indexFile = pickle.load(indexdb)

Leer un diccionario de archivos con el módulo Acid no toma mucho tiempo. Incluso podemos escribir índice con módulo ácido.

Cómo puntuar un artículo para la indagación

El puntaje que obtenemos en el índice no puede ser una referencia de clasificación, porque el índice que preparamos consta de solo un gramo de palabras. Como resultado, las frases que constan de más de una palabra no pueden fijarse en la puntuación del índice.

Para resolver este problema, debe dividir las palabras de la consulta y calcular la puntuación de cada palabra consultada.

for q in query:
   try :
      for doc in indexFile[q]:
          if doc['url'] in list_doc :
              list_doc[doc['url']]['score'] += doc['score']
          else :
              list_doc[doc['url']] = doc
    except :
          continue

Cómo ordenar el resultado de la consulta

Para crear una clasificación, solo necesitamos ordenar los resultados de búsqueda según el resultado más alto.

count=1;
for data in sorted(list_data, key=lambda k: k['score'], reverse=True):
   y = json.dumps(data)
   print(y)
   if (count == n) :
      break
   count+=1

Tutorial sobre cómo construir un motor de búsqueda en Python. | Vídeo: PyGotham 2017

Más sobre Python: Python Databases 101: Cómo elegir una biblioteca de base de datos

Ejemplo de secuencia de comandos de consulta

Usando un script de consulta. | Foto: Andika Pratama

puedes ver en producción de un script de consulta donde el conjunto de datos está asociado con una consulta de palabra clave en formato JSON. El formato JSON facilitará la lectura de los resultados en la interfaz del motor de búsqueda que creamos.

Leave a Reply

Your email address will not be published. Required fields are marked *