| Diskutieren Sie bei Relevanz Slack
SearchArray verwandelt Pandas -Stringspalten in einen Termindex. Es weist eine effiziente BM25 / TFIDF -Bewertung von Phrasen und einzelnen Token mit.
Denken Sie an Lucene, aber als Pandas -Kolumne.
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 ist in diesen Notizbüchern dokumentiert:
SearchArray Guide | SearchArray -Offline -Experiment | Über Interna
pip install searcharray
def tokenize(value: str) -> List[str] ) beim Indexieren.data_dir an den Index für den Speicher zugeordneten IndexSo vereinfachen Sie die lexikalische Suche im Python -Datenstapel.
Viele ML / KI -Praktiker greifen nach einer Vektor -Suchlösung und stellen dann fest, dass sie in einem gewissen Grad an BM25 / Lexikal -Suche streuen müssen. Lassen Sie uns eine traditionelle Volltext-Suche erhalten, um sich wie andere Teile des Datenstapels zu verhalten.
SearchArray erstellt eine pandas-zentrierte Methode zum Erstellen und Verwenden eines Suchindex als Teil eines Pandas-Arrays. In gewissem Sinne erstellt es eine Suchmaschine in Pandas - damit jedem Ideen prototypisieren und eine Wiederholung ohne externe Systeme durchführen kann.
In diesem Colab-Notebook können Sie ein volles Experiment zur Relevanz von End-to-End-Suchern sehen
Dh, lasst uns einen Datenrahmen nehmen, der eine Reihe von Text enthält, wie Filmtitel und Übersichten:
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 ...
Index den Text:
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'})```
(Beachten Sie die dumme Tokenisierung - keine Sorge, Sie können Ihren eigenen Tokenizer übergeben.)
Suchen Sie dann und erhalten Sie Top N mit 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])
Und da es nur Pandas ist, können wir natürlich nur die Top -Matches abrufen
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': [...
Weitere Anwendungsfälle sind im Colab -Notizbuch zu sehen
Ziel ist es, viele der lexikalischen Merkmale (Term / Phrase -Suche) einer Suchmaschine wie Solr oder Elasticsearch, jedoch in einem Pandas -Datenframe, nachzubilden.
Wir möchten, dass der Index so speicher und schnell wie möglich sucht. Wir möchten, dass es einen minimalen Overhead hat.
Wir möchten, dass Sie für die Offline-Bewertung relativ effizient mit einem angemessenen Datensatz (100x-1m DOCs) arbeiten können. Und 1000s für die schnelle Löschung in einem Service.
Anstatt für 'Big Data' zu bauen, ist unser Ziel, für kleine Daten zu bauen. Das heißt, konzentrieren Sie sich auf Fähigkeiten und Ausdruckskraft von Pandas, um die Funktionalität zugunsten der Skalierbarkeit zu begrenzen.
Zu diesem Zweck konzentrieren sich die Anwendungen von SearchArray dazu, sich auf Experimente und Top -N -Kandidaten zu konzentrieren. Für das Experimentieren möchten wir, dass alle in Pandas zum Ausdruck gebrachten Ideen einen etwas klaren Pfad / "Vertrag" in der Implementierung in einer klassischen lexikalischen Suchmaschine haben. Für die Wiederbelebung möchten wir einige Top -N -Ergebnisse aus einem Basissystem laden und diese ändern können.
Wir wissen in der Suche, Lappen und anderen Abrufproblemen Hybrid -Suchtechniken dominieren. Doch oft ist es in Bezug auf eine riesige, seltsame, big data lexikalische Suchmaschine, die den meisten Datenwissenschaftlern seltsam aussieht, der mit einer Vektor -Datenbank verbunden ist. Wir möchten, dass die lexikalische Suche für Datenwissenschaftler und ML -Ingenieure zugänglicher ist, die diese Systeme bauen.
Python -Bibliotheken machen bereits sehr gut Tokenisierung. Selbst wenn Lucene das tun kann ... gibt Ihnen die Fähigkeit, die Fähigkeiten der Tokenisierung von Lucene zu simulieren und/oder zu übertreffen.
In SearchArray ist ein Tokenizer eine Funktion, die eine Zeichenfolge nimmt und eine Reihe von Token ausgibt. Dh dumme, Standard -Whitespace -Tokenisierung:
def ws_tokenizer ( string ):
return string . split ()Und Sie können jeden Tokenizer übergeben, der dieser Signatur an den Index entspricht:
def ws_lowercase_tokenizer ( string ):
return string . lower (). split ()
df [ 'title_indexed' ] = SearchArray . index ( df [ 'title' ], tokenizer = ws_lowercase_tokenizer )Erstellen Sie Ihre eigenen mit Stemming -Bibliotheken oder egal welche Python -Funktionalität Sie möchten.
Solr hat eine eigene eindeutige Funktionsabfrage syntaxhtpps: //solr.apache.org/guide/7_7/function-queries.html. Elasticsearch hat schmerzlos.
Verwenden Sie anstatt diese nachzubilden, einfach Pandas für vorhandene Pandas -Spalten. Wenn Sie dies dann in Solr oder Elasticsearch implementieren müssen, versuchen Sie später, die Funktionalität nachzubilden. Wohl in Solr / ES wäre eine Untergruppe dessen, was Sie in Pandas tun könnten.
# Calculate the number of hours into the past
df['hrs_into_past'] = (now - df['timestamp']).dt.total_seconds() / 3600
Multiplizieren Sie dann mit BM25, wenn Sie möchten:
df['score'] = df['title_indexed'].score('Cat') * df['hrs_into_past']
Wir konzentrieren uns auf die lexikalischen, dh "BM25-ish" und benachbarte Probleme. Es gibt andere großartige Tools für die Vektorsuche.
Besuchen Sie den #searchArray -Kanal zu Relevanz Slack