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.
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
Ejemplo de secuencia de comandos de consulta
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.