Часто задаваемые вопросы#

Здесь мы пытаемся дать ответы на вопросы, которые регулярно возникают в списке рассылки.

О проекте#

Какое название проекта (многие ошибаются)?#

scikit-learn, но не scikit или SciKit, ни sci-kit learn. Также не scikits.learn или scikits-learn, которые использовались ранее.

Как произносится название проекта?#

sy-kit learn. sci означает science!

Почему scikit?#

Существует несколько scikits, которые являются научными инструментальными наборами, построенными вокруг SciPy. Помимо scikit-learn, другой популярный - это scikit-image.

Поддерживаете ли вы PyPy?#

Из-за ограниченных ресурсов сопровождающих и небольшого числа пользователей, использование scikit-learn с PyPy (альтернативная реализация на Python со встроенным компилятором just-in-time) официально не поддерживается.

Как я могу получить разрешение на использование изображений из scikit-learn для своей работы?#

Изображения, содержащиеся в репозиторий scikit-learn и изображения, сгенерированные в документация scikit-learn может использоваться через Лицензия BSD 3-Clause для вашей работы. Цитирование scikit-learn настоятельно рекомендуется и ценится. См. цитирование scikit-learn.

Решения по реализации#

Почему нет поддержки глубокого или обучения с подкреплением? Будет ли такая поддержка в будущем?#

Глубокое обучение и обучение с подкреплением требуют богатого словаря для определения архитектуры, причем глубокое обучение дополнительно требует GPU для эффективных вычислений. Однако ни то, ни другое не вписывается в ограничения дизайна scikit-learn. В результате глубокое обучение и обучение с подкреплением в настоящее время выходят за рамки того, чего стремится достичь scikit-learn.

Вы можете найти больше информации о добавлении поддержки GPU на Будет ли добавлена поддержка GPU?.

Обратите внимание, что scikit-learn в настоящее время реализует простой многослойный перцептрон в sklearn.neural_network. Мы будем принимать только исправления ошибок для этого модуля. Если вы хотите реализовать более сложные модели глубокого обучения, обратитесь к популярным фреймворкам глубокого обучения, таким как tensorflow, keras, и pytorch.

Будут ли добавлены графические модели или прогнозирование последовательностей в scikit-learn?#

Не в обозримом будущем. scikit-learn стремится предоставить унифицированный API для базовых задач машинного обучения, с конвейерами и метаалгоритмами, такими как поиск по сетке, чтобы связать всё вместе. Необходимые концепции, API, алгоритмы и экспертиза, требуемые для структурированного обучения, отличаются от того, что может предложить scikit-learn. Если бы мы начали заниматься произвольным структурированным обучением, нам пришлось бы перепроектировать весь пакет, и проект, вероятно, рухнул бы под собственным весом.

Существует два проекта с API, похожим на scikit-learn, которые выполняют структурированное предсказание:

  • pystruct обрабатывает общее структурированное обучение (фокусируется на SSVM на произвольных графовых структурах с приближенным выводом; определяет понятие выборки как экземпляр графовой структуры).

  • выборка из списков возможных значений вместо scipy.stats обрабатывает только последовательности (фокусируется на точном выводе; содержит HMM, но в основном для полноты; рассматривает вектор признаков как образец и использует смещенное кодирование для зависимостей между векторами признаков).

Почему вы удалили HMM из scikit-learn?#

См. Будут ли добавлены графические модели или прогнозирование последовательностей в scikit-learn?.

Будет ли добавлена поддержка GPU?#

Добавление поддержки GPU по умолчанию ввело бы тяжелые аппаратно-зависимые зависимости, и существующие алгоритмы пришлось бы перереализовывать. Это усложнило бы установку scikit-learn для обычного пользователя и поддержку кода для разработчиков.

Однако, начиная с 2023 года, ограниченное, но растущее список оценщиков scikit-learn уже может работать на GPU, если входные данные предоставлены как массив PyTorch или CuPy и если scikit-learn был настроен на приём таких входных данных, как объяснено в Поддержка Array API (экспериментальная). Эта поддержка Array API позволяет scikit-learn работать на GPU без внесения тяжелых и аппаратно-зависимых зависимостей программного обеспечения в основной пакет.

Большинство оценщиков, которые полагаются на NumPy для своих вычислительно интенсивных операций, могут рассматриваться для поддержки Array API и, следовательно, поддержки GPU.

Однако не все оценщики scikit-learn подходят для эффективной работы на GPU через Array API по фундаментальным алгоритмическим причинам. Например, модели на основе деревьев, в настоящее время реализованные на Cython в scikit-learn, являются фундаментально не основанными на массивах алгоритмами. Другие алгоритмы, такие как k-средних или k-ближайших соседей, полагаются на алгоритмы на основе массивов, но также реализованы на Cython. Cython используется для ручного чередования последовательных операций с массивами, чтобы избежать введения убивающих производительность обращений к памяти для больших промежуточных массивов: эта низкоуровневая алгоритмическая перезапись называется "слиянием ядер" и не может быть выражена через Array API в обозримом будущем.

Добавление эффективной поддержки GPU для оценщиков, которые не могут быть эффективно реализованы с помощью Array API, потребует разработки и принятия более гибкой системы расширений для scikit-learn. Эта возможность рассматривается в следующем issue на GitHub (в обсуждении):

Почему категориальные переменные нуждаются в предобработке в scikit-learn по сравнению с другими инструментами?#

Большинство scikit-learn предполагает, что данные находятся в массивах NumPy или разреженных матрицах SciPy с одним числовым типом данных. В настоящее время они не представляют категориальные переменные явно. Таким образом, в отличие от R data.frames или pandas.DataFrameтребуется явное преобразование категориальных признаков в числовые значения, как обсуждается в Кодирование категориальных признаков. См. также Трансформер столбцов со смешанными типами для примера работы с разнородными (например, категориальными и числовыми) данными.

Обратите внимание, что недавно HistGradientBoostingClassifier и HistGradientBoostingRegressor получил нативную поддержку категориальных признаков через опцию categorical_features="from_dtype". Этот вариант основан на определении того, какие столбцы данных являются категориальными, на основе pandas.CategoricalDtype и polars.datatypes.Categorical dtypes.

Работает ли scikit-learn нативно с различными типами датафреймов?#

Scikit-learn имеет ограниченную поддержку pandas.DataFrame и polars.DataFrame. Оценки scikit-learn могут принимать оба типа датафреймов в качестве входных данных, а преобразователи scikit-learn могут выводить датафреймы с использованием set_output API. Для получения дополнительной информации обратитесь к Введение API set_output.

Однако внутренние вычисления в оценщиках scikit-learn полагаются на численные операции, которые более эффективно выполняются на однородных структурах данных, таких как массивы NumPy или разреженные матрицы SciPy. В результате большинство оценщиков scikit-learn будут внутренне преобразовывать входные данные dataframe в эти однородные структуры данных. Аналогично, выходные данные dataframe генерируются из этих однородных структур данных.

Также обратите внимание, что ColumnTransformer удобно обрабатывать гетерогенные датафреймы pandas, сопоставляя однородные подмножества столбцов датафрейма, выбранные по имени или типу данных, с выделенными преобразователями scikit-learn. Поэтому ColumnTransformer часто используются на первом шаге конвейеров scikit-learn при работе с гетерогенными датафреймами (см. Конвейер: объединение оценщиков для получения дополнительных деталей).

Смотрите также Трансформер столбцов со смешанными типами для примера работы с гетерогенными (например, категориальными и числовыми) данными.

Планируете ли вы реализовать transform для целевой переменной y в конвейере?#

В настоящее время transform работает только для признаков X в конвейере. Существует давнее обсуждение о невозможности преобразования y в конвейере. Следите за issue на GitHub #4143. Тем временем, вы можете посмотреть TransformedTargetRegressor, pipegraph, и imbalanced-learn. Обратите внимание, что scikit-learn решает случай, когда y имеет обратимую трансформацию, примененную перед обучением и инвертированную после предсказания. scikit-learn предназначен для решения случаев использования, где y должны преобразовываться во время обучения, а не во время тестирования, для повторной выборки и аналогичных целей, как в imbalanced-learn. В целом, эти случаи использования могут быть решены с помощью пользовательского мета-оценщика, а не Pipeline.

Почему существует так много различных оценщиков для линейных моделей?#

Обычно существует один классификатор и один регрессор на каждый тип модели, например, GradientBoostingClassifier и GradientBoostingRegressor. Оба имеют схожие опции и оба имеют параметр loss, что особенно полезно в случае регрессии, так как позволяет оценивать условное среднее, а также условные квантили.

Для линейных моделей существует множество классов оценщиков, которые очень близки друг к другу. Давайте рассмотрим

Перспектива сопровождающего: Все они в принципе делают одно и то же и различаются только налагаемым штрафом. Однако это сильно влияет на способ решения базовой оптимизационной задачи. В конечном счете, это сводится к использованию различных методов и приемов из линейной алгебры. Особый случай — SGDRegressor который включает все 4 предыдущие модели и отличается процедурой оптимизации. Дополнительный побочный эффект заключается в том, что разные оценщики предпочитают разные расположения данных (X C-непрерывный или F-непрерывный, разреженный csr или csc). Эта сложность казалось бы простых линейных моделей является причиной наличия разных классов оценщиков для разных штрафов.

С точки зрения пользователя: Во-первых, текущий дизайн вдохновлен научной литературой, где линейные регрессионные модели с различной регуляризацией/штрафами получали разные названия, например. ридж-регрессиякак принадлежащие положительному классу, даже если выход solver параметр. Кроме того, было бы много исключительных взаимодействий между различными параметрами. Например, возможные варианты параметров solver, precompute и selection будет зависеть от выбранных значений параметров штрафа alpha и l1_ratio.

Внесение вклада#

How can I contribute to scikit-learn?#

См. Вклад в pandas. Прежде чем добавлять новый алгоритм, что обычно является крупной и длительной задачей, рекомендуется начать с известные проблемы. Пожалуйста, не связывайтесь напрямую с участниками scikit-learn по поводу вклада в scikit-learn.

Почему мой pull request не получает внимания?#

Процесс ревью scikit-learn занимает значительное время, и контрибьюторы не должны расстраиваться из-за отсутствия активности или ревью их pull request. Мы очень заботимся о том, чтобы сделать все правильно с первого раза, так как поддержка и последующие изменения требуют больших затрат. Мы редко выпускаем «экспериментальный» код, поэтому все наши вклады будут сразу интенсивно использоваться и должны изначально быть максимально высокого качества.

Кроме того, scikit-learn ограничен в ресурсах для рецензирования; многие рецензенты и основные разработчики работают над scikit-learn в свое свободное время. Если рецензия на ваш pull request задерживается, вероятно, рецензенты заняты. Мы просим вашего понимания и просим не закрывать pull request и не прекращать работу только по этой причине.

Советы о том, как сделать ваш pull request более простым для проверки и более вероятным для быстрой проверки, см. Как улучшить мой issue или pull request?.

Как улучшить мой issue или pull request?#

Чтобы ваша проблема получила внимание или повысилась вероятность того, что ваш запрос на слияние будет рассмотрен, вы можете попробовать:

Для ваших pull requests в частности, следующее облегчит проверку:

  • убедитесь, что ваш PR удовлетворяет всем пунктам в Контрольный список pull request.

  • убедитесь, что ваш PR решает проблему, для которой есть четкий консенсус по решению.

  • убедитесь, что изменения минимальны и непосредственно относятся к описанной проблеме.

Что означает метка «спам» для issues или pull requests?#

Метка "спам" является указанием для рецензентов, что проблема или запрос на включение изменений, возможно, не получил достаточных усилий или подготовки от автора для продуктивного рецензирования. Сопровождающие используют эту метку как способ справиться с увеличением количества запросов на включение изменений и проблем низкой ценности.

Если проблема или PR были помечены как спам и одновременно закрыты, решение является окончательным. Частая причина этого — когда люди открывают PR для проблемы, которая всё ещё обсуждается. Пожалуйста, дождитесь завершения обсуждения, прежде чем открывать PR.

Если ваша проблема или PR были помечены как спам и не закрыты, см. Как улучшить мой issue или pull request? для советов по улучшению вашего issue или pull request и увеличению вероятности снятия метки.

Каковы критерии включения новых алгоритмов?#

Мы рассматриваем только хорошо зарекомендовавшие себя алгоритмы для включения. Эмпирическое правило: не менее 3 лет с момента публикации, 200+ цитирований, широкое использование и полезность. Метод, обеспечивающий явное улучшение (например, усовершенствованная структура данных или более эффективная техника аппроксимации) широко используемого метода, также будет рассмотрен для включения.

Из алгоритмов или методов, соответствующих указанным критериям, только те, которые хорошо вписываются в текущий API scikit-learn, то есть fit, predict/transform интерфейс и обычно имеющий входные/выходные данные в виде массива numpy или разреженной матрицы, принимаются.

Автор предложения должен обосновать важность предлагаемого дополнения с помощью научных статей и/или реализаций в других аналогичных пакетах, продемонстрировать его полезность на типичных примерах использования/приложениях и подтвердить улучшение производительности, если таковое имеется, с помощью бенчмарков и/или графиков. Ожидается, что предлагаемый алгоритм должен превосходить уже реализованные в scikit-learn методы хотя бы в некоторых областях.

Пожалуйста, не предлагайте алгоритмы, которые вы (ваш лучший друг, коллега или начальник) создали. scikit-learn — не подходящая площадка для рекламы вашей собственной работы.

Включение нового алгоритма, ускоряющего существующую модель, проще, если:

  • он не вводит новых гиперпараметров (что делает библиотеку более устойчивой к будущим изменениям),

  • легко четко документировать, когда вклад улучшает скорость, а когда нет, например, "когда n_features >> n_samples”,

  • тесты производительности явно показывают ускорение.

Также обратите внимание, что ваша реализация не обязательно должна быть в scikit-learn, чтобы использоваться вместе с инструментами scikit-learn. Вы можете реализовать ваш любимый алгоритм совместимым с scikit-learn способом, загрузить его на GitHub и сообщить нам. Мы будем рады добавить его в список под Связанные проекты. Если у вас уже есть пакет на GitHub, следующий API scikit-learn, вы также можете быть заинтересованы в просмотре scikit-learn-contrib.

Почему вы так избирательны в том, какие алгоритмы включаете в scikit-learn?#

Код требует затрат на поддержку, и нам необходимо сбалансировать объем кода с размером команды (и добавить к этому тот факт, что сложность масштабируется нелинейно с увеличением количества функций). Пакет зависит от основных разработчиков, использующих свое свободное время для исправления ошибок, поддержки кода и проверки вкладов. Любой добавленный алгоритм требует дальнейшего внимания со стороны разработчиков, когда оригинальный автор, возможно, уже давно потерял интерес. См. также Каковы критерии включения новых алгоритмов?Для отличного чтения о проблемах долгосрочного сопровождения в открытом программном обеспечении посмотрите исполнительное резюме по дорогам и мостам.

Использование scikit-learn#

Как начать работу с scikit-learn?#

Если вы новичок в scikit-learn или хотите углубить понимание, мы настоятельно рекомендуем scikit-learn MOOC (массовый открытый онлайн-курс).

Смотрите наш Страница внешних ресурсов, видео и выступлений для получения дополнительной информации.

Какой лучший способ получить помощь по использованию scikit-learn?#

  • Общие вопросы по машинному обучению: используйте Cross Validated с [machine-learning] тег.

  • вопросы по использованию scikit-learn: используйте Stack Overflow с [scikit-learn] и [python] теги. Вы также можете использовать список рассылки.

Пожалуйста, убедитесь, что включили минимальный воспроизводимый фрагмент кода (желательно короче 10 строк), который демонстрирует вашу проблему на игрушечном наборе данных (например, из sklearn.datasets или случайно сгенерированы с помощью функций numpy.random с фиксированным случайным начальным значением). Пожалуйста, удалите любую строку кода, которая не нужна для воспроизведения вашей проблемы.

Проблема должна быть воспроизводима простым копированием вашего фрагмента кода в оболочку Python с установленным scikit-learn. Не забудьте включить операторы импорта. Дополнительные рекомендации по написанию хороших воспроизводимых фрагментов кода можно найти по адресу: https://stackoverflow.com/help/mcve.

Если ваша проблема вызывает исключение, которое вы не понимаете (даже после поиска в Google), пожалуйста, убедитесь, что включили полную трассировку, которую вы получаете при запуске скрипта воспроизведения.

Для сообщений об ошибках или запросов функций, пожалуйста, используйте трекер проблем на GitHub.

Предупреждение

Пожалуйста, не отправляйте электронные письма напрямую авторам с просьбой о помощи, сообщением об ошибках или по любым другим вопросам, связанным с scikit-learn.

Как мне сохранить, экспортировать или развернуть оценщики для продакшена?#

См. Сохранение модели.

Как создать объект bunch?#

Объекты Bunch иногда используются как выходные данные для функций и методов. Они расширяют словари, позволяя получать значения по ключу, bunch["value_key"], или по атрибуту, bunch.value_key.

Их не следует использовать в качестве входных данных. Поэтому вам почти никогда не нужно создавать Bunch объектом, если только вы не расширяете API scikit-learn.

Как я могу загрузить свои собственные наборы данных в формат, пригодный для использования в scikit-learn?#

В целом, scikit-learn работает с любыми числовыми данными, хранящимися в виде массивов NumPy или разреженных матриц SciPy. Другие типы, которые можно преобразовать в числовые массивы, такие как pandas.DataFrame также допустимы.

Для получения дополнительной информации о загрузке ваших файлов данных в эти пригодные для использования структуры данных, пожалуйста, обратитесь к загрузка внешних наборов данных.

Как работать со строковыми данными (или деревьями, графами…)?#

Оценщики scikit-learn предполагают, что вы будете подавать им векторы признаков с вещественными значениями. Это предположение жестко закодировано практически во всей библиотеке. Однако вы можете подавать нечисловые входные данные оценщикам несколькими способами.

Если у вас есть текстовые документы, вы можете использовать признаки частоты терминов; см. Извлечение текстовых признаков для встроенного векторизаторы текста. Для более общей извлечения признаков из данных любого типа см. Загрузка признаков из словарей и Хеширование признаков.

Другой распространённый случай — когда у вас есть нечисловые данные и пользовательская метрика расстояния (или сходства) для этих данных. Примеры включают строки с расстоянием редактирования (также известным как расстояние Левенштейна), например, последовательности ДНК или РНК. Их можно закодировать как числа, но это трудоёмко и подвержено ошибкам. Работа с метриками расстояния для произвольных данных может быть выполнена двумя способами.

Во-первых, многие модели принимают предварительно вычисленные матрицы расстояний/сходства, поэтому если набор данных не слишком велик, можно вычислить расстояния для всех пар входных данных. Если набор данных большой, можно использовать векторы признаков только с одним "признаком", который является индексом в отдельной структуре данных, и предоставить пользовательскую метрическую функцию, которая ищет фактические данные в этой структуре данных. Например, для использования dbscan с расстояниями Левенштейна:

>>> 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]))

Обратите внимание, что приведенный выше пример использует сторонний пакет расстояния редактирования левен. Аналогичные трюки могут быть использованы, с некоторой осторожностью, для ядер деревьев, графовых ядер и т.д.

Почему иногда возникает сбой/зависание с n_jobs > 1 под OSX или Linux?#

Некоторые инструменты scikit-learn, такие как GridSearchCV и cross_val_score внутренне полагаются на Python multiprocessing модуль для распараллеливания выполнения на несколько процессов Python путём передачи n_jobs > 1 в качестве аргумента.

Проблема в том, что Python multiprocessing выполняет fork системный вызов без последующего exec системный вызов по соображениям производительности. Многие библиотеки, такие как (некоторые версии) Accelerate или vecLib под OSX, (некоторые версии) MKL, среда выполнения OpenMP от GCC, Cuda от nvidia (и, вероятно, многие другие), управляют собственными внутренними пулами потоков. При вызове fork, состояние пула потоков в дочернем процессе повреждено: пул потоков считает, что у него много потоков, в то время как было форкнуто только состояние основного потока. Можно изменить библиотеки, чтобы они обнаруживали форк и переинициализировали пул потоков в этом случае: мы сделали это для OpenBLAS (включено в основную ветку с версии 0.2.10) и мы внесли вклад в патч в среду выполнения OpenMP GCC (ещё не проверено).

Но в конечном счете настоящий виновник — это multiprocessing который делает fork без exec для снижения накладных расходов на запуск и использование новых процессов Python для параллельных вычислений. К сожалению, это нарушение стандарта POSIX, поэтому некоторые разработчики программного обеспечения, такие как Apple, отказываются считать отсутствие безопасности при fork в Accelerate и vecLib ошибкой.

В Python 3.4+ теперь можно настроить multiprocessing для использования "forkserver" или "spawn" методы запуска (вместо стандартного "fork") для управления пулами процессов. Чтобы обойти эту проблему при использовании scikit-learn, вы можете установить JOBLIB_START_METHOD переменная окружения для "forkserver". Однако пользователь должен знать, что использование "forkserver" метод предотвращает joblib.Parallel для вызова функции, интерактивно определенной в сеансе оболочки.

Если у вас есть пользовательский код, который использует multiprocessing напрямую вместо использования через joblib вы можете включить "forkserver" режим глобально для вашей программы. Вставьте следующие инструкции в ваш основной скрипт:

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

Более подробную информацию о новых методах запуска можно найти в документация по multiprocessing.

Почему моя задача использует больше ядер, чем указано с n_jobs?#

Это связано с тем, что n_jobs контролирует только количество заданий для процедур, распараллеленных с помощью joblib, но параллельный код может поступать из других источников:

  • некоторые процедуры могут быть распараллелены с помощью OpenMP (для кода, написанного на C или Cython),

  • scikit-learn сильно зависит от numpy, который, в свою очередь, может зависеть от числовых библиотек, таких как MKL, OpenBLAS или BLIS, которые могут предоставлять параллельные реализации.

Для получения более подробной информации, пожалуйста, обратитесь к нашему заметки о параллелизме.

Как установить random_state для всего выполнения?#

Пожалуйста, обратитесь к Управление случайностью.