| Discuter à la pertinence
SearchArray transforme les colonnes de chaîne Pandas en un index de terme. Il éteint une notation efficace BM25 / TFIDF des phrases et des jetons individuels.
Pensez à Lucene, mais en tant que colonne Pandas.
from searcharray import SearchArray
import pandas as pd
df [ 'title_indexed' ] = SearchArray . index ( df [ 'title' ])
np . sort ( df [ 'title_indexed' ]. array . score ([ 'cat' , 'in' , 'the' , 'hat' ])) # Search w/ phrase
> BM25 scores :
> array ([ 0. , 0. , 0. , ..., 15.84568033 , 15.84568033 , 15.84568033 ])SearchArray est documenté dans ces cahiers:
Guide SearchArray | Expérience hors ligne de recherche | À propos des internes
pip install searcharray
def tokenize(value: str) -> List[str] ) lors de l'indexation.data_dir à index pour l'index mappé de mémoirePour simplifier la recherche lexicale dans la pile de données Python.
De nombreux praticiens ML / AI atteignent une solution de recherche de vecteurs, puis se rendent compte qu'ils doivent saupoudrer dans un certain degré de recherche BM25 / lexicale. Faisons une recherche traditionnelle en texte intégral pour se comporter comme d'autres parties de la pile de données.
SearchArray crée une manière centrée sur les pandas de créer et d'utiliser un index de recherche comme faisant partie d'un tableau Pandas. Dans un sens, il construit un moteur de recherche dans Pandas - pour permettre à quiconque de prototyper les idées et d'effectuer des rediffus, sans systèmes externes.
Vous pouvez voir une expérience de pertinence de recherche de bout en bout dans ce cahier Colab
IE, prenons un dataframe qui a un tas de texte, comme le titre de film et les aperçus:
In[1]: df = pd.DataFrame({'title': titles, 'overview': overviews}, index=ids)
Out[1]:
title overview
374430 Black Mirror: White Christmas This feature-length special consists of three ...
19404 The Brave-Hearted Will Take the Bride Raj is a rich, carefree, happy-go-lucky second...
278 The Shawshank Redemption Framed in the 1940s for the double murder of h...
372058 Your Name. High schoolers Mitsuha and Taki are complete s...
238 The Godfather Spanning the years 1945 to 1955, a chronicle o...
... ... ...
65513 They Came Back The lives of the residents of a small French t...
65515 The Eleventh Hour An ex-Navy SEAL, Michael Adams, (Matthew Reese...
65521 Pyaar Ka Punchnama Outspoken and overly critical Nishant Agarwal ...
32767 Romero Romero is a compelling and deeply moving look ...
Indexez le texte:
In[2]: df['title_indexed'] = SearchArray.index(df['title'])
df
Out[2]:
title overview title_indexed
374430 Black Mirror: White Christmas This feature-length special consists of three ... Terms({'Black', 'Mirror:', 'White'...
19404 The Brave-Hearted Will Take the Bride Raj is a rich, carefree, happy-go-lucky second... Terms({'The', 'Brave-Hearted', 'Wi...
278 The Shawshank Redemption Framed in the 1940s for the double murder of h... Terms({'The', 'Shawshank', 'Redemp...
372058 Your Name. High schoolers Mitsuha and Taki are complete s... Terms({'Your', 'Name.'}, {'Your': ...
238 The Godfather Spanning the years 1945 to 1955, a chronicle o... Terms({'The', 'Godfather'}, {'The'...
... ... ... ...
65513 They Came Back The lives of the residents of a small French t... Terms({'Back', 'They', 'Came'},...
65515 The Eleventh Hour An ex-Navy SEAL, Michael Adams, (Matthew Reese... Terms({'The', 'Hour', 'Eleventh': ...
65521 Pyaar Ka Punchnama Outspoken and overly critical Nishant Agarwal ... Terms({'Ka', 'Pyaar', 'Punchnama':...
32767 Romero Romero is a compelling and deeply moving look ... Terms({'Romero'})
65534 Poison Paul Braconnier and his wife Blandine only hav... Terms({'Poison'})```
(Remarquez la tokenisation stupide - pas de soucis, vous pouvez transmettre votre propre tokenizer).
Puis recherchez, obtenant le top n avec Cat
In[3]: np.sort(df['title_indexed'].array.score('Cat'))
Out[3]: array([ 0. , 0. , 0. , ..., 15.84568033,
15.84568033, 15.84568033])
In[4]: df['title_indexed'].score('Cat').argsort()
Out[4]:
array([0, 18561, 18560, ..., 15038, 19012, 4392])
Et comme ses juste pandas, nous pouvons bien sûr récupérer les meilleurs matchs
In[5]: df.iloc[top_n_cat[-10:]]
Out[5]:
title overview title_indexed
24106 The Black Cat American honeymooners in Hungary are trapped i... Terms({'Black': 1, 'The': 1, 'Cat': 1}, ...
12593 Fritz the Cat A hypocritical swinging college student cat ra... Terms({'Cat': 1, 'the': 1, 'Fritz': 1}, ...
39853 The Cat Concerto Tom enters from stage left in white tie and ta... Terms({'The': 1, 'Cat': 1, 'Concerto': 1...
75491 The Rabbi's Cat Based on the best-selling graphic novel by Joa... Terms({'The': 1, 'Cat': 1, "Rabbi's": 1}...
57353 Cat Run When a sexy, high-end escort holds the key evi... Terms({'Cat': 1, 'Run': 1}, {'Cat': [0],...
25508 Cat People Sketch artist Irena Dubrovna (Simon) and Ameri... Terms({'Cat': 1, 'People': 1}, {'Cat': [...
11694 Cat Ballou A woman seeking revenge for her murdered fathe... Terms({'Cat': 1, 'Ballou': 1}, {'Cat': [...
25078 Cat Soup The surreal black comedy follows Nyatta, an an... Terms({'Cat': 1, 'Soup': 1}, {'Cat': [0]...
35888 Cat Chaser A Miami hotel owner finds danger when be becom... Terms({'Cat': 1, 'Chaser': 1}, {'Cat': [...
6217 Cat People After years of separation, Irina (Nastassja Ki... Terms({'Cat': 1, 'People': 1}, {'Cat': [...
Plus de cas d'utilisation peuvent être vus dans le cahier Colab
Les objectifs globaux sont de recréer une grande partie des fonctionnalités lexicales (recherche à terme / phrase) d'un moteur de recherche comme Solr ou Elasticsearch, mais dans un Pandas DataFrame.
Nous voulons que l'index soit aussi efficace de mémoire et rapide pour la recherche possible. Nous voulons l'utiliser pour avoir une surcharge minimale.
Nous voulons que vous puissiez travailler avec un ensemble de données raisonnable (100x-1M DOC) relativement efficacement pour une évaluation hors ligne. Et 1000s pour rediriger rapidement dans un service.
Au lieu de construire pour «Big Data», notre objectif est de construire pour les petites données . Autrement dit, se concentrer sur les capacités et l'expressivité des pandas, sur la limitation des fonctionnalités en faveur de l'évolutivité.
À cette fin, les applications de SearchArray auront tendance à se concentrer sur l'expérimentation et la rediffusion des candidats top n. Pour l'expérimentation, nous voulons que toutes les idées exprimées dans Pandas aient un chemin / "contrat" quelque peu clair dans la façon dont ils seraient mis en œuvre dans un moteur de recherche lexical classique. Pour le rediffusion, nous voulons charger certains résultats supérieurs d'un système de base et pouvoir les modifier.
Nous savons que dans la recherche, le chiffon et d'autres problèmes de récupération, les techniques de recherche hybride dominent. Pourtant, souvent son casting en termes de moteur de recherche lexical géant, étrange et de Big Data qui semble étrange à la plupart des scientifiques des données joints à une base de données vectorielle. Nous voulons que la recherche lexicale soit plus accessible pour les scientifiques des données et les ingénieurs ML qui construisent ces systèmes.
Les bibliothèques Python font déjà très bien la tokenisation. Même dépasser ce que Lucene peut faire ... vous donnant la possibilité de simuler et / ou de dépasser les capacités de la tokenisation de Lucene.
Dans SearchArray, un tokenizer est une fonction prend une chaîne et émet une série de jetons. IE Dumb, Tokenisation des espaces par défaut:
def ws_tokenizer ( string ):
return string . split ()Et vous pouvez passer n'importe quel tokenzer qui correspond à cette signature à l'index:
def ws_lowercase_tokenizer ( string ):
return string . lower (). split ()
df [ 'title_indexed' ] = SearchArray . index ( df [ 'title' ], tokenizer = ws_lowercase_tokenizer )Créez les vôtres en utilisant des bibliothèques en tige ou quelle que soit la fonctionnalité Python que vous souhaitez.
Solr a sa propre fonction de fonction unique syntaxhttps: //solr.apache.org/guide/7_7/function-quèques.html. Elasticsearch a indolore.
Au lieu de les recréer, utilisez simplement des pandas sur les colonnes Pandas existantes. Ensuite, si vous devez implémenter cela dans Solr ou Elasticsearch, essayez de recréer la fonctionnalité. On peut dire ce qui est dans Solr / ES serait un sous-ensemble de ce que vous pourriez faire dans Pandas.
# Calculate the number of hours into the past
df['hrs_into_past'] = (now - df['timestamp']).dt.total_seconds() / 3600
Multipliez ensuite par BM25 si vous voulez:
df['score'] = df['title_indexed'].score('Cat') * df['hrs_into_past']
Nous nous concentrons sur les problèmes lexicaux, c'est-à-dire "BM25-ish" et adjacents. Il existe d'autres excellents outils pour la recherche de vecteur.
Visitez la chaîne #SearchArray sur la pertinence