Два часа по-късно и все още работи? Как да държите sklearn.fit под контрол.

Написано от Габриел Лернър и Нейтън Тубиана

Всичко, което искахте да направите, беше да тествате кода си, но два часа по-късно вашият Scikit-learn fit не показва никакви признаци за завършване. Scitime е пакет, който предсказва времето на работа на алгоритмите за машинно обучение, така че да не бъдете изненадани от безкрайно нападение.

Независимо дали сте в процес на изграждане на модел за машинно обучение или внедрявате кода си в производството, знанието за това колко време ще отнеме алгоритъмът Ви е от ключово значение за рационализирането на работния Ви процес. С Scitime ще можете за няколко секунди да прецените колко време трябва да отнеме напасването на най-често използваните Scikit Learn алгоритми.

По тази тема са публикувани няколко изследователски статии (като тази). Доколкото знаем обаче, няма практическо изпълнение от него. Целта тук не е да се предскаже точното време на изпълнение на алгоритъма, а повече да се даде грубо приближение.

Какво е Scitime?

Scitime е пакет на python, който изисква поне python 3.6 с зависимости от pandas, scikit-learn, psutil и joblib. Ще намерите репозитория на Scitime тук.

Основната функция в този пакет се нарича „ време “. Като се има предвид матричен вектор X, прогнозният вектор Y заедно с избрания от вас модел Scikit Learn, времето ще изведе както очакваното време, така и неговия доверителен интервал. Понастоящем пакетът поддържа следните алгоритми Scikit Learn с планове за добавяне на повече в близко бъдеще:

  • KMeans
  • RandomForestRegressor
  • SVC
  • RandomForestClassifier

Бърз старт

Нека инсталираме пакета и стартираме основите.

Първо създайте нов virtualenv (това е по избор, за да се избегнат конфликти на версии!)

❱ virtualenv env❱ source env/bin/activate

и след това изпълнете:

❱ (env) pip install scitime

или с конда:

❱ (env) conda install -c conda-forge scitime

След като инсталацията е успешна, вие сте готови да изчислите времето на първия си алгоритъм.

Да приемем, че сте искали да обучите kmeans клъстериране например. Първо ще трябва да импортирате пакета scikit-learn, да зададете параметрите kmeans и също така да изберете входовете (известни още като X) , генерирани тук на случаен принцип за простота.

Изпълнението на това, преди да се извърши действителното прилягане, ще даде приблизително време на изпълнение:

Както можете да видите, можете да получите тази информация само в един допълнителен ред код! Входовете на функцията за време са точно това, което е необходимо за стартиране на пригодността (това е самият алго и X), което го прави още по-лесен за използване.

Разглеждайки по-отблизо последния ред на горния код, първият изход ( оценка: 15 секунди в този случай) е прогнозираното време на изпълнение, което търсите. Scitime също ще го изведе с доверителен интервал (по- нисък и горен: 10 и 30 секунди в този случай). Винаги можете да го сравните с действителното време за тренировка, като изпълните:

В този случай на нашата локална машина оценката е 15 секунди, докато действителното време за обучение е 20 секунди (но може да не получите същите резултати, както ще обясним по-късно).

Като ръководство за бързо използване:

Клас на оценител (meta_algo, многословен, уверен):

  • meta_algo : Изчислителят, използван за прогнозиране на времето, или „RF“, или „NN“ (вижте подробности в следващия параграф) - по подразбиране е „RF“
  • подробен : Контрол на сумата на изхода на регистрационния файл (или 0, 1, 2 или 3) - по подразбиране е 0
  • увереност : Доверие за интервали - по подразбиране 95%

функция estimator.time (algo, X, y):

  • algo : алго, чието изпълнение потребителят иска да предвиди
  • X : numpy масив от входни данни за обучение
  • y : numpy масив от изходи, които трябва да бъдат обучени (задайте на None, ако алго е без надзор)

Бърза бележка: за да се избегне объркване, струва си да подчертаем, че algo и meta_algo са две различни неща тук: algo е алгоритъмът, чието време на изпълнение искаме да изчислим, meta_algo е алгоритъмът, използван от Scitime за предсказване на времето на изпълнение.

Как работи Scitime

Ние сме в състояние да предвидим времето на изпълнение да се побере, като използваме собствения си оценител, ние го наричаме мета алгоритъм ( meta_algo ), чиито тегла се съхраняват в специален файл за туршия в метаданните на пакета. За всеки модел Scikit Learn ще намерите съответстващ файл с мета алго киселина в кодовата база на Scitime.

Може би си мислите:

Защо не се изчисли ръчно сложността на времето с големи O нотации?

Това е справедлива точка. Това е валиден начин за подход към проблема и нещо, за което сме мислили в началото на проекта. Едно обаче е, че ще трябва да формулираме сложността изрично за всеки алго и набор от параметри, което е доста предизвикателно в някои случаи, като се има предвид броят на факторите, играещи роля по време на изпълнение. Meta_algo по принцип върши цялата работа вместо вас и ние ще обясним как.

Два вида мета алго са обучени да изчисляват времето за напасване (и двете от Scikit Learn):

  • В RF мета алго, оценител на RandomForestRegressor.
  • В NN мета алго, основен MLPRegressor оценител.

Тези мета алгоритми изчисляват времето, за да се поберат, използвайки набор от „мета“ функции. Ето обобщение на начина, по който изграждаме тези функции:

Първо, извличаме формата на вашата входна матрица X и изходния вектор y. Второ, параметрите, които подавате към модела Scikit Learn, са взети под внимание, тъй като те ще повлияят и на времето за обучение. И накрая, вашият специфичен хардуер, уникален за вашата машина, като налична памет и брой процесори също се вземат предвид.

Както беше показано по-рано, ние също предоставяме доверителни интервали за прогнозата за времето. Начинът, по който се изчисляват, зависи от избрания мета алго:

  • За RF , тъй като всеки случаен регресор на гора е комбинация от множество дървета (наричани още оценители ), интервалът на доверие ще се основава на разпределението на набора от прогнози, изчислени от всеки оценител.
  • За NN процесът е малко по-недвусмислен: първо изчисляваме набор от MSE, заедно с броя на наблюденията върху тестов набор, групирани по предвидени бинове за продължителност (това е от 0 до 1 секунда, 1 до 5 секунди и т.н. on) и след това изчисляваме t-stat, за да получим долната и горната граница на оценката. Тъй като нямаме много данни за много дълги модели, интервалът на доверие за такива данни може да стане много широк.

Как го изградихме

Може би си мислите:

Как взехте достатъчно данни за времето за обучение на всички тези научни приспособления за различни параметри и хардуерни конфигурации?

(Негламурният) отговор е, че генерирахме данните сами, използвайки комбинация от компютри и хардуер на виртуална машина, за да симулираме какво би било времето за обучение в различните системи. След това монтирахме нашите мета алгоритми върху тези произволно генерирани точки от данни, за да изградим оценител, предназначен да бъде надежден, независимо от вашата система.

Докато файлът identify.py обработва прогнозата за изпълнение, файлът _model.py ни помогна да генерираме данни за обучение на нашите мета алгоритми, използвайки нашия специален клас Model. Ето съответния примерен код за kmeans:

Имайте предвид, че можете също да използвате файла _data.py директно с командния ред, за да генерирате данни или да обучите нов модел. Свързани инструкции могат да бъдат намерени във файла за репо Readme.

Когато генерирате точки от данни, можете да редактирате параметрите на моделите Scikit Learn, по които искате да тренирате. Можете да се насочите към scitime / _config.json и да редактирате параметрите на моделите, както и броя на редовете и колоните, с които искате да тренирате.

Използваме функция itertool, за да преминем през всяка възможна комбинация, заедно със скорост на падане, зададена между 0 и 1, за да контролираме колко бързо цикълът ще премине през различните възможни повторения.

Колко точно е Scitime?

По-долу подчертаваме как се представят нашите прогнози за конкретния случай на kmeans. Нашият генериран набор от данни съдържа ~ 100 000 точки от данни, които разделяме на влак и тестови комплекти (75% - 25%).

Групирахме прогнозираните часове на обучение по различни времеви групи и изчислихме MAPE и RMSE за всяка от тези групи за всички наши оценители, използвайки RF мета-алго и NN мета-алго.

Моля, обърнете внимание, че тези резултати са извършени върху ограничен набор от данни, така че те могат да бъдат различни при неизследвани точки от данни (като други системи / екстремни стойности на определени параметри на модела). За този специфичен комплект за обучение R-квадратът е около 80% за NN и 90% за RF.

Както можем да видим, не е изненадващо, че точността е постоянно по-висока на влака, отколкото на теста, както за NN, така и за RF. Също така виждаме, че RF изглежда се представя по-добре от NN като цяло. MAPE за RF е около 20% за влаковия комплект и 40% за тестовия комплект. NN MAPE е изненадващо много висок.

Нека разделим MAPE (на тестовия набор) по броя на предвидените секунди:

Едно важно нещо, което трябва да имате предвид, е, че в някои случаи прогнозата за времето е чувствителна към избрания мета алго (RF или NN). Според нашия опит RF се е представил много добре в рамките на входящите диапазони от данни, както е показано по-горе. Въпреки това, за точки извън обхвата, NN може да се представи по-добре, както се предлага от края на горната диаграма. Това би обяснило защо NN MAPE е доста висок, докато RMSE е приличен: той се представя зле при малки стойности.

Като пример, ако се опитате да предскажете времето на изпълнение на kmeans с параметри по подразбиране и с входна матрица от няколко хиляди реда, RF мета алго ще бъде прецизен, защото нашият набор от данни за обучение съдържа подобни точки от данни. Въпреки това, за прогнозиране на много специфични параметри (например много голям брой клъстери), NN може да се представи по-добре, защото екстраполира от набора за обучение, докато RF не. NN се представя по-зле на горните диаграми, тъй като тези графики се основават само на данни, близки до набора от входове на данните за обучение.

Както е показано на тази графика, стойностите извън обхвата (тънки линии) се екстраполират от NN оценителя, докато RF оценяващият прогнозира изхода постепенно.

Сега нека разгледаме най-важните „мета“ функции за примера на kmeans:

Както виждаме, само 6 функции представляват повече от 80% от вариацията на модела. Сред тях най-важен е параметър на самия клас scikit-learn kmeans (брой клъстери), но много външни фактори оказват голямо влияние върху времето на изпълнение, като брой редове / колони и налична памет.

Ограничения

Както споменахме по-рано, първото ограничение е свързано с доверителните интервали: те могат да бъдат много широки, особено за NN, и за тежки модели (това би отнело поне час).

Освен това NN може да се представи слабо при малки до средни прогнози. Понякога за малка продължителност NN може дори да предскаже отрицателна продължителност, като в този случай автоматично превключваме обратно към RF.

Друго ограничение на оценката възниква, когато се използват "специални" стойности на алго параметър. Например в сценарий RandomForest, когато max_depth е зададен на None , дълбочината може да приеме всякаква стойност. Това може да доведе до много по-дълго време за побиране, което е по-трудно за мета алго да вземе, въпреки че се постарахме да ги отчетем.

Когато изпълняваме estimator.time (algo, X, y), ние изискваме от потребителя да въведе действителния вектор X и y, което изглежда ненужно, тъй като можем просто да поискаме формата на данните, за да изчислим времето за обучение. Причината за това е, че всъщност се опитваме да приспособим модела, преди да прогнозираме времето за изпълнение, за да предизвикаме незабавни грешки. Изпълняваме algo.fit (X, y) в подпроцес за една секунда, за да проверим за грешка при напасване, след което преминаваме към частта за прогнозиране. Има обаче моменти, в които алго (и / или входната матрица) са толкова големи, че стартирането на алго.фит (Х, у) в крайна сметка ще изведе грешка в паметта, която не можем да отчетем.

Бъдещи подобрения

Най-ефективният и очевиден начин за подобряване на ефективността на настоящите ни прогнози би бил генерирането на повече точки от данни в различни системи, за да се поддържа по-добре широк спектър от хардуер / параметри.

В близко бъдеще ще разгледаме добавянето на още поддържани алгоритми Scikit Learn. Можем да внедрим и други алгоритми като lightGBM или xgboost. Чувствайте се свободни да се свържете с нас, ако има алгоритъм, който бихте искали да внедрим в следващите итерации на Scitime!

Други интересни начини за подобряване на ефективността на оценителя биха били включването на по-подробна информация за входната матрица, като дисперсия или корелация с изхода. Понастоящем генерираме данни напълно произволно, за които времето за напасване може да е по-голямо, отколкото за реалните набори от данни. Така че в някои случаи може да надцени времето за обучение.

В допълнение бихме могли да проследяваме по-фина информация за хардуера, като честота на процесора или текуща употреба на процесора.

В идеалния случай, тъй като алгоритъмът може да се промени от версия на scikit-learn към друга и по този начин да окаже въздействие върху времето на изпълнение, ние също бихме го взели предвид, например като използваме версията като „мета“ функция.

Тъй като придобиваме повече данни, за да отговарят на нашите мета алго, можем да помислим да използваме по-сложни мета алго, като сложни невронни мрежи (използвайки техники на регуларизация като отпадане или нормализиране на партида). Можем дори да обмислим използването на tensorflow, за да се побере мета алго (и да го добавим като незадължителен): това не само ще ни помогне да получим по-добра точност, но и ще изградим по-стабилни интервали на доверие, използвайки отпадане.

Допринасяте за Scitime и ни изпращате вашите отзиви

Първо, всякакъв вид обратна връзка, особено относно изпълнението на прогнозите и идеите за подобряване на този процес на генериране на данни, е много ценен!

Както беше обсъдено по-горе, можете да използвате нашето репо, за да генерирате свои собствени точки от данни, за да обучите вашия собствен мета алгоритъм. Когато правите това, можете да помогнете за подобряване на Scitime, като споделите вашите точки от данни, намерени в резултата csv ( ~ / scitime / scitime / [algo] _results.csv ), за да можем да го интегрираме в нашия модел.

За да генерирате свои собствени данни, можете да изпълните команда, подобна на тази (от пакета repo source):

❱ python _data.py --verbose 3 --algo KMeans --drop_rate 0.99

Забележка: ако се изпълнява директно с помощта на кодовия източник (с класа Model ), не забравяйте да зададете write_csv на true, в противен случай генерираните точки от данни няма да бъдат запазени.

Използваме проблеми с GitHub, за да проследяваме всички грешки и заявки за функции. Чувствайте се свободни да отворите проблем, ако сте открили грешка или искате да видите внедрена нова функция. Повече информация може да бъде намерена за това как да допринесете в репозитория на Scitime.

За проблеми с прогнозите за време на обучение, когато изпращате обратна връзка, включително пълния речник на параметрите, които вписвате във вашия модел, може да ви помогне, за да можем да диагностицираме защо производителността е подчинена за конкретния ви случай на употреба. За да направите това, просто задайте подробния параметър на 3 и копирайте, поставете регистрационния файл на параметъра dic в описанието на проблема.

Намерете източника на кода

Намерете документацията

Кредити

  • Gabriel Lerner & Nathan Toubiana са основните сътрудници на този пакет и съавтори на тази статия
  • Специални благодарности на Philippe Mizrahi за помощта по пътя
  • Благодарим за цялата помощ, която получихме от ранните рецензии / бета тестване