Häufig gestellte Fragen#

Hier versuchen wir, einige Fragen zu beantworten, die regelmäßig in der Mailingliste auftauchen.

Über das Projekt#

Wie lautet der Projektname (viele Leute machen ihn falsch)?#

scikit-learn, aber nicht scikit oder SciKit oder sci-kit learn. Auch nicht scikits.learn oder scikits-learn, die früher verwendet wurden.

Wie spricht man den Projektnamen aus?#

sy-kit learn. sci steht für Science!

Warum scikit?#

Es gibt mehrere scikits, die wissenschaftliche Toolboxes sind, die auf SciPy aufbauen. Abgesehen von scikit-learn ist scikit-image ein weiteres beliebtes.

Unterstützen Sie PyPy?#

Aufgrund begrenzter Betreuerressourcen und einer geringen Nutzerzahl wird die Verwendung von scikit-learn mit PyPy (einer alternativen Python-Implementierung mit einem integrierten Just-in-Time-Compiler) nicht offiziell unterstützt.

Wie kann ich die Erlaubnis erhalten, die Bilder in scikit-learn für meine Arbeit zu verwenden?#

Die im scikit-learn Repository enthaltenen Bilder und die im scikit-learn Dokumentation generierten Bilder können über die BSD 3-Clause Lizenz für Ihre Arbeit verwendet werden. Zitate von scikit-learn sind sehr erwünscht und werden geschätzt. Siehe scikit-learn zitieren.

Implementierungsentscheidungen#

Warum gibt es keine Unterstützung für Deep Learning oder Reinforcement Learning? Wird es in Zukunft eine solche Unterstützung geben?#

Deep Learning und Reinforcement Learning erfordern beide ein reichhaltiges Vokabular zur Definition einer Architektur, wobei Deep Learning zusätzlich GPUs für effizientes Rechnen benötigt. Keines davon passt jedoch zu den Designbeschränkungen von scikit-learn. Daher fallen Deep Learning und Reinforcement Learning derzeit außerhalb des Umfangs dessen, was scikit-learn erreichen möchte.

Weitere Informationen zur Hinzufügung von GPU-Unterstützung finden Sie unter Werden Sie GPU-Unterstützung hinzufügen?.

Beachten Sie, dass scikit-learn derzeit ein einfaches Mehrschichten-Perzeptron in sklearn.neural_network implementiert. Wir werden nur Fehlerkorrekturen für dieses Modul akzeptieren. Wenn Sie komplexere Deep-Learning-Modelle implementieren möchten, wenden Sie sich bitte an beliebte Deep-Learning-Frameworks wie tensorflow, keras und pytorch.

Werden Sie grafische Modelle oder Sequenzvorhersagen zu scikit-learn hinzufügen?#

Nicht in absehbarer Zeit. scikit-learn versucht, eine einheitliche API für die grundlegenden Aufgaben des maschinellen Lernens bereitzustellen, mit Pipelines und Meta-Algorithmen wie Grid Search, um alles zusammenzubinden. Die erforderlichen Konzepte, APIs, Algorithmen und das Fachwissen für strukturiertes Lernen unterscheiden sich von dem, was scikit-learn zu bieten hat. Wenn wir mit beliebigem strukturiertem Lernen beginnen würden, müssten wir das gesamte Paket neu gestalten und das Projekt würde wahrscheinlich unter seinem eigenen Gewicht zusammenbrechen.

Es gibt zwei Projekte mit einer ähnlichen API wie scikit-learn, die strukturiertes Vorhersagen durchführen.

  • pystruct behandelt allgemeines strukturiertes Lernen (konzentriert sich auf SSVMs auf beliebigen Graphenstrukturen mit approximativer Inferenz; definiert die Vorstellung von Stichproben als Instanz der Graphenstruktur).

  • seqlearn behandelt nur Sequenzen (konzentriert sich auf exakte Inferenz; hat HMMs, aber hauptsächlich der Vollständigkeit halber; behandelt einen Merkmalsvektor als Stichprobe und verwendet eine Offset-Kodierung für die Abhängigkeiten zwischen Merkmalsvektoren).

Warum haben Sie HMMs aus scikit-learn entfernt?#

Siehe Werden Sie grafische Modelle oder Sequenzvorhersagen zu scikit-learn hinzufügen?.

Werden Sie GPU-Unterstützung hinzufügen?#

Die standardmäßige Hinzufügung von GPU-Unterstützung würde schwere hardwareabhängige Softwareabhängigkeiten einführen und bestehende Algorithmen müssten neu implementiert werden. Dies würde es sowohl für den durchschnittlichen Benutzer schwieriger machen, scikit-learn zu installieren, als auch für die Entwickler schwieriger, den Code zu warten.

Seit 2023 kann eine begrenzte, aber wachsende Liste von scikit-learn-Schätzern bereits auf GPUs ausgeführt werden, wenn die Eingabedaten als PyTorch- oder CuPy-Array bereitgestellt werden und scikit-learn so konfiguriert wurde, dass solche Eingaben akzeptiert werden, wie in Array API-Unterstützung (experimentell) erläutert. Diese Array API-Unterstützung ermöglicht es scikit-learn, auf GPUs ausgeführt zu werden, ohne schwere und hardwareabhängige Softwareabhängigkeiten in das Hauptpaket einzuführen.

Die meisten Schätzer, die für ihre rechenintensiven Operationen auf NumPy angewiesen sind, können für die Array API-Unterstützung und damit für die GPU-Unterstützung in Betracht gezogen werden.

Allerdings sind nicht alle scikit-learn-Schätzer aus grundlegenden algorithmischen Gründen für die effiziente Ausführung auf GPUs über die Array API geeignet. Baum-basierte Modelle, die derzeit mit Cython in scikit-learn implementiert sind, sind beispielsweise grundsätzlich keine Array-basierten Algorithmen. Andere Algorithmen wie k-means oder k-nearest neighbors basieren auf Array-basierten Algorithmen, sind aber ebenfalls in Cython implementiert. Cython wird verwendet, um aufeinanderfolgende Array-Operationen manuell zu verketten, um leistungsschwächende Speicherzugriffe auf große Zwischenarrays zu vermeiden: diese Low-Level-algorithmische Neufassung wird als „Kernel Fusion“ bezeichnet und kann auf absehbare Zeit nicht über die Array API ausgedrückt werden.

Die Hinzufügung einer effizienten GPU-Unterstützung für Schätzer, die nicht effizient mit der Array API implementiert werden können, würde die Entwicklung und Einführung eines flexibleren Erweiterungssystems für scikit-learn erfordern. Diese Möglichkeit wird in der folgenden GitHub-Ausgabe (in Diskussion) erwogen.

Warum benötigen kategoriale Variablen in scikit-learn eine Vorverarbeitung im Vergleich zu anderen Tools?#

Die meisten scikit-learn-Funktionen gehen davon aus, dass die Daten in NumPy-Arrays oder SciPy-Sparse-Matrizen mit einem einzigen numerischen Datentyp vorliegen. Diese repräsentieren derzeit keine kategorialen Variablen explizit. Daher benötigen wir, im Gegensatz zu R's `data.frames` oder pandas.DataFrame, eine explizite Umwandlung kategorialer Merkmale in numerische Werte, wie in Kategoriale Merkmale kodieren erläutert. Siehe auch Column Transformer mit gemischten Typen für ein Beispiel zur Arbeit mit heterogenen (z. B. kategorialen und numerischen) Daten.

Beachten Sie, dass HistGradientBoostingClassifier und HistGradientBoostingRegressor seit kurzem native Unterstützung für kategoriale Merkmale durch die Option `categorical_features="from_dtype"` erhalten haben. Diese Option beruht auf der Inferenz, welche Spalten der Daten basierend auf den `pandas.CategoricalDtype` und `polars.datatypes.Categorical` Dtypes kategorial sind.

Funktioniert scikit-learn nativ mit verschiedenen Datentypen von DataFrames?#

Scikit-learn hat eine begrenzte Unterstützung für pandas.DataFrame und `polars.DataFrame`. scikit-learn-Schätzer können beide DataFrame-Typen als Eingabe akzeptieren, und scikit-learn-Transformer können DataFrames über die `set_output`-API ausgeben. Weitere Details finden Sie unter Einführung der set_output API.

Die internen Berechnungen in scikit-learn-Schätzern beruhen jedoch auf numerischen Operationen, die auf homogenen Datenstrukturen wie NumPy-Arrays oder SciPy-Sparse-Matrizen effizienter ausgeführt werden. Daher werden die meisten scikit-learn-Schätzer intern DataFrame-Eingaben in diese homogenen Datenstrukturen umwandeln. Ebenso werden DataFrame-Ausgaben aus diesen homogenen Datenstrukturen generiert.

Beachten Sie auch, dass ColumnTransformer die bequeme Handhabung von heterogenen Pandas-DataFrames ermöglicht, indem homogene Teilmengen von DataFrame-Spalten, die nach Name oder Dtype ausgewählt wurden, dedizierten scikit-learn-Transformern zugeordnet werden. Daher werden ColumnTransformer oft im ersten Schritt von scikit-learn-Pipelines verwendet, wenn mit heterogenen DataFrames gearbeitet wird (siehe Pipeline: Schätzer verkettet für weitere Details).

Siehe auch Column Transformer mit gemischten Typen für ein Beispiel zur Arbeit mit heterogenen (z. B. kategorialen und numerischen) Daten.

Planen Sie, `transform` für das Ziel `y` in einer Pipeline zu implementieren?#

Derzeit funktioniert `transform` nur für Merkmale `X` in einer Pipeline. Es gibt eine langjährige Diskussion darüber, dass `y` nicht in einer Pipeline transformiert werden kann. Verfolgen Sie dies auf GitHub Issue #4143. In der Zwischenzeit können Sie TransformedTargetRegressor, pipegraph und imbalanced-learn ansehen. Beachten Sie, dass scikit-learn für den Fall gelöst wurde, dass auf `y` eine invertierbare Transformation angewendet wird, bevor trainiert und nach der Vorhersage invertiert wird. scikit-learn beabsichtigt, Anwendungsfälle zu lösen, bei denen `y` zur Trainingszeit transformiert werden soll und nicht zur Testzeit, für Resampling und ähnliche Zwecke, wie z. B. bei imbalanced-learn. Im Allgemeinen können diese Anwendungsfälle mit einem benutzerdefinierten Meta-Schätzer und nicht mit einer Pipeline gelöst werden.

Warum gibt es so viele verschiedene Schätzer für lineare Modelle?#

Normalerweise gibt es einen Klassifikator und einen Regressor pro Modelltyp, z. B. GradientBoostingClassifier und GradientBoostingRegressor. Beide haben ähnliche Optionen und beide haben den Parameter `loss`, der besonders im Regressionsfall nützlich ist, da er die Schätzung des bedingten Mittelwerts sowie der bedingten Quantile ermöglicht.

Für lineare Modelle gibt es viele Schätzerklassen, die sich sehr nahe sind. Betrachten wir einmal

Perspektive des Maintainers: Sie alle tun im Prinzip dasselbe und unterscheiden sich nur durch die Strafe, die sie auferlegen. Dies hat jedoch großen Einfluss auf die Art und Weise, wie das zugrunde liegende Optimierungsproblem gelöst wird. Letztendlich beläuft es sich auf die Verwendung unterschiedlicher Methoden und Tricks aus der linearen Algebra. Ein Sonderfall ist SGDRegressor, der alle 4 vorherigen Modelle umfasst und sich durch das Optimierungsverfahren unterscheidet. Eine weitere Nebenwirkung ist, dass die verschiedenen Schätzer unterschiedliche Datenlayouts bevorzugen (`X` C-contiguous oder F-contiguous, sparse csr oder csc). Diese Komplexität der scheinbar einfachen linearen Modelle ist der Grund für die unterschiedlichen Schätzerklassen für verschiedene Strafen.

Benutzerperspektive: Erstens ist das aktuelle Design von der wissenschaftlichen Literatur inspiriert, in der lineare Regressionsmodelle mit unterschiedlicher Regularisierung/Strafe unterschiedliche Namen erhielten, z. B. *Ridge-Regression*. Unterschiedliche Modellklassen mit entsprechenden Namen erleichtern es den Benutzern, diese Regressionsmodelle zu finden. Zweitens, wenn alle 5 oben genannten linearen Modelle zu einer einzigen Klasse vereinheitlicht würden, gäbe es Parameter mit vielen Optionen wie dem Parameter `solver`. Darüber hinaus gäbe es viele exklusive Interaktionen zwischen verschiedenen Parametern. Zum Beispiel würden die möglichen Optionen der Parameter `solver`, `precompute` und `selection` von den gewählten Werten der Strafparameter `alpha` und `l1_ratio` abhängen.

Beiträge#

Wie kann ich zu scikit-learn beitragen?#

Siehe Beitrag zu pandas. Bevor Sie einen neuen Algorithmus hinzufügen möchten, was in der Regel ein großes und langwieriges Unterfangen ist, wird empfohlen, mit den bekannten Problemen zu beginnen. Bitte kontaktieren Sie die Mitwirkenden von scikit-learn nicht direkt bezüglich eines Beitrags zu scikit-learn.

Warum erhält meine Pull-Anfrage keine Aufmerksamkeit?#

Der Überprüfungsprozess von scikit-learn nimmt erhebliche Zeit in Anspruch, und Mitwirkende sollten sich nicht von mangelnder Aktivität oder Überprüfung ihrer Pull-Anfrage entmutigen lassen. Wir legen großen Wert darauf, Dinge von Anfang an richtig zu machen, da Wartung und spätere Änderungen mit hohen Kosten verbunden sind. Wir veröffentlichen selten „experimentellen“ Code, daher werden alle unsere Beiträge sofort intensiv genutzt und sollten anfänglich von höchster Qualität sein.

Darüber hinaus ist die Überprüfungskapazität von scikit-learn begrenzt; viele der Gutachter und Kernentwickler arbeiten in ihrer Freizeit an scikit-learn. Wenn die Überprüfung Ihrer Pull-Anfrage langsam erfolgt, liegt es wahrscheinlich daran, dass die Gutachter beschäftigt sind. Wir bitten um Ihr Verständnis und möchten Sie bitten, Ihre Pull-Anfrage nicht allein aus diesem Grund zu schließen oder Ihre Arbeit einzustellen.

Tipps, wie Sie Ihre Pull-Anfrage leichter überprüfbar und mit höherer Wahrscheinlichkeit schnell überprüft machen können, finden Sie unter Wie kann ich meine Issue oder Pull-Anfrage verbessern?.

Wie kann ich meine Issue oder Pull-Anfrage verbessern?#

Um Ihrer Issue Aufmerksamkeit zu verschaffen oder die Wahrscheinlichkeit zu erhöhen, dass Ihre Pull-Anfrage überprüft wird, können Sie versuchen:

Für Ihre Pull-Anfragen im Speziellen erleichtert Folgendes die Überprüfung:

  • sicherzustellen, dass Ihre PR alle Punkte in der Checkliste für Pull-Anfragen erfüllt.

  • sicherzustellen, dass Ihre PR ein Problem betrifft, für das ein klarer Konsens über die Lösung besteht.

  • sicherzustellen, dass die Änderungen minimal und direkt auf das beschriebene Problem bezogen sind.

Was bedeutet das „Spam“-Label für Issues oder Pull-Anfragen?#

Das Label „Spam“ ist ein Hinweis für Gutachter, dass die Issue oder Pull-Anfrage möglicherweise nicht ausreichend Aufwand oder Vorbereitung vom Autor für eine produktive Überprüfung erhalten hat. Die Maintainer verwenden dieses Label, um mit der Zunahme von PRs und Issues geringen Wert umzugehen.

Wenn eine Issue oder PR als Spam gekennzeichnet und gleichzeitig geschlossen wurde, ist die Entscheidung endgültig. Ein häufiger Grund dafür ist, wenn Leute eine PR für eine noch diskutierte Issue eröffnen. Bitte warten Sie, bis die Diskussion abgeschlossen ist, bevor Sie eine PR eröffnen.

Wenn Ihre Issue oder PR als Spam gekennzeichnet und nicht geschlossen wurde, siehe Wie kann ich meine Issue oder Pull-Anfrage verbessern? für Tipps zur Verbesserung Ihrer Issue oder Pull-Anfrage und zur Erhöhung der Wahrscheinlichkeit, dass das Label entfernt wird.

Was sind die Aufnahmekriterien für neue Algorithmen?#

Wir berücksichtigen nur gut etablierte Algorithmen für die Aufnahme. Eine Faustregel ist mindestens 3 Jahre seit der Veröffentlichung, 200+ Zitationen und breite Nutzung und Nützlichkeit. Eine Technik, die eine klare Verbesserung (z. B. eine verbesserte Datenstruktur oder eine effizientere Approximationstechnik) gegenüber einer weit verbreiteten Methode bietet, wird ebenfalls zur Aufnahme in Betracht gezogen.

Von den Algorithmen oder Techniken, die die oben genannten Kriterien erfüllen, werden nur diejenigen akzeptiert, die gut in die aktuelle API von scikit-learn passen, d. h. eine `fit`, `predict/transform`-Schnittstelle und normalerweise eine Ein- und Ausgabe, die ein NumPy-Array oder eine Sparse-Matrix ist.

Der Mitwirkende sollte die Bedeutung des vorgeschlagenen Zusatzes mit Forschungsarbeiten und/oder Implementierungen in anderen ähnlichen Paketen untermauern, seine Nützlichkeit durch gängige Anwendungsfälle/Anwendungen demonstrieren und Leistungsverbesserungen, falls vorhanden, durch Benchmarks und/oder Diagramme belegen. Es wird erwartet, dass der vorgeschlagene Algorithmus die bereits in scikit-learn implementierten Methoden zumindest in einigen Bereichen übertrifft.

Bitte schlagen Sie keine Algorithmen vor, die Sie (Ihr bester Freund, Kollege oder Chef) erstellt haben. scikit-learn ist kein guter Ort, um Ihre eigene Arbeit zu bewerben.

Die Aufnahme eines neuen Algorithmus, der ein bestehendes Modell beschleunigt, ist einfacher, wenn

  • er keine neuen Hyperparameter einführt (da dies die Bibliothek zukunftssicherer macht),

  • es leicht ist, klar zu dokumentieren, wann der Beitrag die Geschwindigkeit verbessert und wann nicht, z. B. „wenn `n_features >> n_samples`“,

  • Benchmarks eine deutliche Beschleunigung zeigen.

Beachten Sie auch, dass Ihre Implementierung nicht unbedingt in scikit-learn sein muss, um zusammen mit scikit-learn-Tools verwendet zu werden. Sie können Ihren Lieblingsalgorithmus auf eine scikit-learn-kompatible Weise implementieren, ihn auf GitHub hochladen und uns Bescheid geben. Wir werden ihn gerne unter Verwandte Projekte auflisten. Wenn Sie bereits ein Paket auf GitHub haben, das die scikit-learn API befolgt, sind Sie vielleicht auch an scikit-learn-contrib interessiert.

Warum sind Sie so wählerisch bei der Aufnahme von Algorithmen in scikit-learn?#

Code verursacht Wartungskosten, und wir müssen die Menge des Codes, den wir haben, mit der Größe des Teams abgleichen (und dazu die Tatsache hinzufügen, dass die Komplexität nichtlinear mit der Anzahl der Merkmale skaliert). Das Paket ist darauf angewiesen, dass Kernentwickler ihre Freizeit nutzen, um Fehler zu beheben, Code zu warten und Beiträge zu überprüfen. Jeder hinzugefügte Algorithmus benötigt zukünftige Aufmerksamkeit von den Entwicklern, zu einem Zeitpunkt, zu dem das Interesse des ursprünglichen Autors möglicherweise längst erloschen ist. Siehe auch Was sind die Aufnahmekriterien für neue Algorithmen?. Für eine großartige Lektüre über langfristige Wartungsprobleme in Open-Source-Software siehe die Executive Summary von Roads and Bridges.

scikit-learn verwenden#

Wie beginne ich mit scikit-learn?#

Wenn Sie neu bei scikit-learn sind oder Ihr Verständnis vertiefen möchten, empfehlen wir dringend den scikit-learn MOOC (Massive Open Online Course).

Siehe unsere Seite Externe Ressourcen, Videos und Vorträge für weitere Details.

Was ist der beste Weg, um Hilfe bei der Verwendung von scikit-learn zu erhalten?#

  • Allgemeine Fragen zum maschinellen Lernen: Nutzen Sie Cross Validated mit dem Tag `[machine-learning]`.

  • Fragen zur Verwendung von scikit-learn: Nutzen Sie Stack Overflow mit den Tags `[scikit-learn]` und `[python]`. Alternativ können Sie die Mailingliste nutzen.

Bitte stellen Sie sicher, dass Sie einen minimalen Reproduktionscode-Schnipsel (idealweise kürzer als 10 Zeilen) einfügen, der Ihr Problem mit einem Spiel-Datensatz hervorhebt (z. B. aus sklearn.datasets oder zufällig mit Funktionen von `numpy.random` mit einem festen Zufallsseed generiert). Entfernen Sie jede Zeile Code, die nicht zur Reproduktion Ihres Problems notwendig ist.

Das Problem sollte durch einfaches Kopieren und Einfügen Ihres Code-Schnipsels in eine Python-Shell mit installiertem scikit-learn reproduzierbar sein. Vergessen Sie nicht, die Importanweisungen einzufügen. Weitere Anleitungen zum Schreiben guter Reproduktions-Code-Schnipsel finden Sie unter: https://stackoverflow.com/help/mcve.

Wenn Ihr Problem eine Ausnahme auslöst, die Sie nicht verstehen (auch nach Googeln), stellen Sie bitte sicher, dass Sie den vollständigen Traceback angeben, den Sie beim Ausführen des Reproduktionsskripts erhalten.

Für Fehlerberichte oder Feature-Anfragen nutzen Sie bitte den Issue Tracker auf GitHub.

Warnung

Bitte senden Sie keine E-Mails direkt an die Autoren, um Hilfe zu erbitten, Fehler zu melden oder für andere Probleme im Zusammenhang mit scikit-learn.

Wie sollte ich Schätzer für die Produktion speichern, exportieren oder bereitstellen?#

Siehe Modellpersistenz.

Wie kann ich ein „bunch“-Objekt erstellen?#

Bunch-Objekte werden manchmal als Ausgabe für Funktionen und Methoden verwendet. Sie erweitern Dictionaries, indem sie es ermöglichen, auf Werte über einen Schlüssel zuzugreifen (`bunch["value_key"]`) oder über ein Attribut (`bunch.value_key`).

Sie sollten nicht als Eingabe verwendet werden. Daher müssen Sie fast nie ein Bunch-Objekt erstellen, es sei denn, Sie erweitern die API von scikit-learn.

Wie kann ich eigene Datensätze in ein von scikit-learn nutzbares Format laden?#

Generell arbeitet scikit-learn mit numerischen Daten, die als numpy-Arrays oder scipy-Sparse-Matrizen gespeichert sind. Andere Datentypen, die in numerische Arrays konvertierbar sind, wie z.B. pandas.DataFrame, sind ebenfalls akzeptabel.

Weitere Informationen zum Laden Ihrer Datendateien in diese nutzbaren Datenstrukturen finden Sie unter Laden externer Datensätze.

Wie gehe ich mit Zeichenketten-Daten (oder Bäumen, Graphen…)?#

scikit-learn-Schätzer gehen davon aus, dass Sie ihnen reellwertige Merkmalsvektoren zuführen. Diese Annahme ist praktisch in der gesamten Bibliothek fest einprogrammiert. Sie können jedoch nicht-numerische Eingaben auf verschiedene Weise an Schätzer übergeben.

Wenn Sie Textdokumente haben, können Sie Termfrequenz-Merkmale verwenden; siehe Textmerkmalextraktion für die integrierten Text-Vektorisierer. Für eine allgemeinere Merkmalsabstraktion aus jeder Art von Daten siehe Laden von Merkmalen aus Dictionaries und Feature Hashing.

Ein weiterer häufiger Fall ist, wenn Sie nicht-numerische Daten und eine benutzerdefinierte Distanz- (oder Ähnlichkeits-)Metrik für diese Daten haben. Beispiele hierfür sind Zeichenketten mit Editierdistanz (auch Levenshtein-Distanz genannt), z.B. DNA- oder RNA-Sequenzen. Diese können als Zahlen kodiert werden, aber das ist mühsam und fehleranfällig. Die Arbeit mit Distanzmetriken auf beliebigen Daten kann auf zwei Arten erfolgen.

Erstens akzeptieren viele Schätzer vorab berechnete Distanz-/Ähnlichkeitsmatrizen. Wenn der Datensatz also nicht zu groß ist, können Sie Distanzen für alle Paare von Eingaben berechnen. Wenn der Datensatz groß ist, können Sie Merkmalsvektoren mit nur einem "Merkmal" verwenden, das ein Index in einer separaten Datenstruktur ist, und eine benutzerdefinierte Metrikfunktion bereitstellen, die die tatsächlichen Daten aus dieser Datenstruktur abruft. Zum Beispiel, um dbscan mit Levenshtein-Distanzen zu verwenden

>>> import numpy as np
>>> from leven import levenshtein
>>> from sklearn.cluster import dbscan
>>> data = ["ACCTCCTAGAAG", "ACCTACTAGAAGTT", "GAATATTAGGCCGA"]
>>> def lev_metric(x, y):
...     i, j = int(x[0]), int(y[0])  # extract indices
...     return levenshtein(data[i], data[j])
...
>>> X = np.arange(len(data)).reshape(-1, 1)
>>> X
array([[0],
       [1],
       [2]])
>>> # We need to specify algorithm='brute' as the default assumes
>>> # a continuous feature space.
>>> dbscan(X, metric=lev_metric, eps=5, min_samples=2, algorithm='brute')
(array([0, 1]), array([ 0,  0, -1]))

Beachten Sie, dass das obige Beispiel das Drittanbieter-Paket für Editierdistanz leven verwendet. Ähnliche Tricks können mit einiger Vorsicht für Baumkerne, Graphenkerne usw. verwendet werden.

Warum stürzt/friert mein System manchmal mit n_jobs > 1 unter OSX oder Linux ein?#

Mehrere scikit-learn-Werkzeuge wie GridSearchCV und cross_val_score nutzen intern Pythons multiprocessing-Modul, um die Ausführung auf mehrere Python-Prozesse zu parallelisieren, indem n_jobs > 1 als Argument übergeben wird.

Das Problem ist, dass Pythons multiprocessing einen fork-Systemaufruf durchführt, ohne diesem aus Leistungsgründen einen exec-Systemaufruf folgen zu lassen. Viele Bibliotheken wie (einige Versionen von) Accelerate oder vecLib unter OSX, (einige Versionen von) MKL, die OpenMP-Laufzeitumgebung von GCC, Nvidias Cuda (und wahrscheinlich viele andere) verwalten ihre eigenen internen Thread-Pools. Bei einem Aufruf von fork ist der Zustand des Thread-Pools im Kindprozess korrumpiert: Der Thread-Pool glaubt, viele Threads zu haben, obwohl nur der Zustand des Hauptthreads "geforkt" wurde. Es ist möglich, die Bibliotheken so zu ändern, dass sie erkennen, wenn ein Fork stattfindet, und den Thread-Pool in diesem Fall neu initialisieren: Wir haben dies für OpenBLAS getan (seit 0.2.10 im Hauptzweig zusammengeführt) und einen Patch zur OpenMP-Laufzeitumgebung von GCC beigesteuert (noch nicht überprüft).

Aber letztendlich ist der eigentliche Schuldige Pythons multiprocessing, das fork ohne exec durchführt, um den Overhead beim Starten und Verwenden neuer Python-Prozesse für paralleles Rechnen zu reduzieren. Leider ist dies eine Verletzung des POSIX-Standards, und daher weigern sich einige Softwarehersteller wie Apple, die mangelnde Fork-Sicherheit in Accelerate und vecLib als Fehler anzuerkennen.

In Python 3.4+ ist es nun möglich, multiprocessing so zu konfigurieren, dass die Startmethoden "forkserver" oder "spawn" (anstelle des Standardwerts "fork") verwendet werden, um die Prozess-Pools zu verwalten. Um dieses Problem bei der Verwendung von scikit-learn zu umgehen, können Sie die Umgebungsvariable JOBLIB_START_METHOD auf "forkserver" setzen. Der Benutzer sollte sich jedoch bewusst sein, dass die Verwendung der "forkserver"-Methode joblib.Parallel daran hindert, interaktiv in einer Shell-Sitzung definierte Funktionen aufzurufen.

Wenn Sie benutzerdefinierten Code haben, der multiprocessing direkt verwendet und nicht über joblib, können Sie den "forkserver"-Modus global für Ihr Programm aktivieren. Fügen Sie die folgenden Anweisungen in Ihr Hauptskript ein

import multiprocessing

# other imports, custom code, load data, define model...

if __name__ == "__main__":
    multiprocessing.set_start_method("forkserver")

    # call scikit-learn utils with n_jobs > 1 here

Weitere Details zu den neuen Startmethoden finden Sie in der Dokumentation zu Multiprocessing.

Warum verwendet mein Job mehr Kerne als mit n_jobs angegeben?#

Das liegt daran, dass n_jobs nur die Anzahl der Jobs für Routinen steuert, die mit joblib parallelisiert werden, aber paralleler Code kann aus anderen Quellen stammen.

  • einige Routinen können mit OpenMP parallelisiert werden (für in C oder Cython geschriebenen Code).

  • scikit-learn stützt sich stark auf numpy, das wiederum auf numerischen Bibliotheken wie MKL, OpenBLAS oder BLIS basieren kann, die parallele Implementierungen bereitstellen können.

Weitere Details finden Sie in unseren Hinweisen zur Parallelität.

Wie setze ich einen random_state für eine gesamte Ausführung?#

Siehe Kontrolle der Zufälligkeit.