常見問題?

在這里,我們將對郵件列表中經常出現的問題給出一些答案。

項目名稱是什么(很多人都弄錯了)?

scikit-learn ,不是scikit或SciKit也不是sci-kit learn。同樣不是以前使用的scikits.learn或scikits-learn。

您如何發音項目的名稱?

sy-kit learn。sci代表科學!

為什么選擇scikit?

這里有多個scikits,它們是圍繞SciPy構建的科學工具箱。您可以在https://scikits.appspot.com/scikits上找到該列表。除了scikit-learn,另一個流行的是scikit-image

我如何為scikit-learn做出貢獻?

請參閱貢獻。建議在添加新算法(通常是一項艱巨而漫長的工作)之前,先從已知問題開始 。關于為scikit-learn做貢獻,請不要直接與scikit-learn的貢獻者聯系。

獲取scikit-learn說明幫助的最佳方法是什么?

對于一般的機器學習問題,請使用帶有[machine-learning]標簽的 交叉驗證

對于scikit-learn使用問題,請使用帶有[scikit-learn][python]標簽的Stack Overflow。您也可以使用郵件列表

請確保您提供的代碼塊盡量簡短(最好短于10行),以突出您在虛擬數據集上的問題(例如可以通過sklearn.datasets函數或者通過可設置固定隨機種子的numpy.random來生成數據集)。呈現您的問題時請刪除不必要的代碼行。

只需將代碼塊復制粘貼到安裝了scikit-learn的Python shell中,就可以顯示出該問題。不要忘記帶上導入語句。

有關編寫良好的再現代碼段的更多指南,請參見:

https://stackoverflow.com/help/mcve

如果您的問題引發了一個您不理解的異常(即使在對其進行了搜索之后),也請務必要提供完整的運行代碼塊時得到的提示信息。

如果是錯誤的報告或功能的請求,請使用GitHub上問題跟蹤器

另外還提供了一個scikit-learn的Gitter頻道,這里可以聯系某些用戶及開發人員。

請不要直接給任何作者發送電子郵件,以尋求如報告錯誤,或與scikit-learn相關的任何其他問題的幫助。

我在工作時應該如何保存,導出或部署估算器?

請參閱模型持久性

如何創建bunch對象?

Bunch對象有時會用作函數和方法的輸出。它們可以通過字典的鍵訪問值

bunch["value_key"]或屬性訪問值bunch.value_key來擴展字典 。

它們不僅僅是作為輸出。因此,除非你擴展了scikit-learn的API,否則幾乎不需要創建Bunch對象。

如何將自己的數據集加載為scikit-learn可用的格式?

通常,scikit-learn可處理以numpy數組或scipy稀疏矩陣存儲的任何數字數據。也可以接受其他可轉換為數字數組的類型,例如pandas DataFrame。

有關將數據文件加載到這些可用數據結構中的更多信息,請參考加載外部數據集

新算法的納入標準是什么?

我們只考慮完善的包含算法。經驗法則是自發布以來至少已有3年,被引用200多次,并且被廣泛使用。還將考慮在廣泛使用的方法上提供明顯改進的技術(例如,增強的數據結構或更有效的近似技術)。

從滿足上述標準的算法或技術,只有那些的當前API內合身scikit學習,這是一個fitpredict/transform接口和通常具有輸入/輸出,一個numpy的陣列或稀疏矩陣,被接受。

貢獻者應通過研究論文和/或其他類似軟件包中的實現來支持所提議的添加的重要性,并通過常見的用例/應用程序來證明其有用性,并通過基準和/或圖表來證實性能的改進(如果有)。預期所提出的算法至少應在某些方面優于scikit-learn中已經實現的方法。

在以下情況下,采用新算法加速現有模型更為容易:

  • 它沒有引入新的超參數(因為它使庫更具前瞻性),
  • 可以很容易地清楚地記錄出貢獻何時可以提高速度,何時不可以,例如“當n_features >> n_samples”時,
  • 基準顯然表明速度有所提高。

另外,請注意,您的實現不必與scikit-learn工具一起使用在scikit-learn中。您可以以scikit-learn兼容的方式實現自己喜歡的算法,然后將其上傳到GitHub并告知我們。我們很高興將其列在“ 相關項目”下。如果您已經在scikit-learn API上的GitHub上有了一個軟件包,那么您可能也有興趣查看scikit-learn-contrib

您為什么如此選擇scikit-learn中包含的算法?

代碼帶來了維護成本,我們需要在擁有的代碼量與團隊規模之間取得平衡(并在此基礎上,復雜度與功能數量成非線性比例關系)。該軟件包依靠核心開發人員利用他們的空閑時間來修復錯誤,維護代碼和檢查貢獻。添加的任何算法都需要開發人員將來注意,這時原始作者可能早就失去了興趣。另請參閱新算法的包含標準是什么?。有關開放源代碼軟件中長期維護問題的詳細信息,請 參閱《道路和橋梁執行摘要》。

為什么要從scikit-learn中刪除HMM?

請參閱是否將圖形模型或序列預測添加到scikit-learn?

您是否將圖形模型或序列預測添加到scikit-learn?

在不可預見的將來。scikit-learn嘗試為機器學習中的基本任務提供統一的API,并使用管道和元算法(例如網格搜索)將所有內容結合在一起。結構化學習所需的概念,API,算法和專業知識與scikit-learn提供的內容不同。如果我們開始進行任意的結構化學習,則需要重新設計整個程序包,并且該項目可能會在其自身的負擔下崩潰。

有兩個API與scikit-learn類似的項目,可以進行結構化預測:

  • pystruct處理一般的結構化學習(專注于具有近似推理的任意圖結構上的SSVM;將樣本的概念定義為圖結構的實例)
  • seqlearn僅處理序列(專注于精確推斷;具有HMM,但主要是出于完整性的考慮;將特征向量視為樣本,并對特征向量之間的依賴性使用偏移編碼)

您會添加GPU支持嗎?

不,或者至少在不久的將來不會。主要原因是GPU支持會引入許多軟件依賴關系,并會引入特定于平臺的問題。scikit-learn旨在易于安裝在各種平臺上。在神經網絡之外,GPU在當今的機器學習中并未發揮重要作用,并且通過謹慎選擇算法通常可以實現更大的速度提升。

你支持PyPy嗎?

如果您不知道,PyPy是帶有內置即時編譯器的可替代Python實現。添加了對PyPy3-v5.10 +的實驗支持,需要Numpy 1.14.0+和scipy 1.1.0+。

我該如何處理字符串數據(或樹,圖形等)?

scikit-learn估計器假定您將向他們提供實值特征向量。這個假設在幾乎所有庫中都是硬編碼的。但是,您可以通過幾種方式將非數字輸入提供給估計量。

如果您有文本文檔,則可以使用術語頻率功能;請參閱 內置文本矢量化程序的文本特征提取。有關從任何類型的數據中提取更一般的特征的信息,請參閱 從字典加載特征特征散列

另一個常見的情況是您有非數字數據和這些數據上的自定義距離(或相似性)度量。示例包括具有編輯距離(也稱為Levenshtein距離;例如DNA或RNA序列)的字符串。這些可以被編碼為數字,但是這樣做很麻煩且容易出錯。對任意數據使用距離度量可以通過兩種方式完成。

首先,許多估算器采用預先計算的距離/相似度矩陣,因此,如果數據集不太大,則可以計算所有輸入對的距離。如果數據集很大,則可以僅使用帶有一個“特征”的特征向量,這是一個單獨數據結構的索引,并提供一個自定義指標函數來查找此數據結構中的實際數據。例如,要使用具有Levenshtein距離的DBSCAN:

>>> from leven import levenshtein       
>>> import numpy as np
>>> 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(-11)
>>> X
array([[0],
       [1],
       [2]])
>>> # We need to specify algoritum='brute' as the default assumes
>>> # a continuous feature space.
>>> dbscan(X, metric=lev_metric, eps=5, min_samples=2, algorithm='brute')
... 
([01], array([ 0,  0-1]))

(這使用第三方編輯距離包leven。)

可以小心地將類似的技巧用于樹內核,圖形內核等。

為什么有時在OSX或Linux下,n_jobs> 1會導致崩潰/凍結?

一些scikit-learn工具,例如GridSearchCVcross_val_score 內部依賴于Python的multiprocessing模塊,通過將n_jobs> 1作為參數,將執行并行化到多個Python進程上。

問題在于,由于性能原因,Python multiprocessing會執行fork系統調用,而不會在其后執行exec系統調用。許多庫例如在OSX下運行的Accelerate / vecLib(某些版本),(某些版本的)MKL,GCC的OpenMP運行版,nvidia的Cuda(可能還有許多其他版本)都管理著自己的內部線程池。在調用fork時,子進程中的線程池狀態被破壞:線程池認為它有許多線程,而只有主線程狀態已經分叉。在這種情況下,可以更改庫以使它們檢測到何時發生分支并重新初始化線程池:我們對OpenBLAS進行了此操作(自0.2.10開始并入master),并為GCC的OpenMP運行版提供了補丁(尚未審查)。

但最終,真正的罪魁禍首是Python multiprocessing,在沒有exec的情況下進行fork,以減少啟動和使用新的Python進程進行并行計算的開銷。不幸的是,這違反了POSIX標準,因此某些軟件編輯器(例如Apple)拒絕將缺少fork安全性的Accelerate / vecLib視為一個bug。

在Python 3.4+中,現在可以配置multiprocessing使用'forkserver'或'spawn'啟動方法(而不是默認的'fork')來管理進程池。要在使用scikit-learn時解決此問題,可以將JOBLIB_START_METHOD環境變量設置為“ forkserver”。但是,用戶需要注意,使用“ forkserver”方法會阻止joblib.與在Shell會話中交互式定義的函數并行。

如果您直接使用multiprocessing而不是通過joblib自定義代碼,則可以為程序全局用'forkserver'模式:在主腳本中插入以下說明:

import multiprocessing

# 其他導入,自定義代碼,加載數據,定義模型...

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

    # 這里scikit-learn調用 n_jobs > 1

您可以在多進程處理文檔中找到有關新啟動方法的更多默認設置。

為什么我的任務使用的內核比n_jobs指定的更多?

這是因為n_jobs僅控制與joblib并行化的常規任務的數量,而并行代碼可能來自其他來源:

  • 某些常規的可以與OpenMP并行化(適用于C或Cython編寫的代碼)。
  • scikit-learn非常依賴numpy,而numpy可能依賴于可以提供并行實現的數值庫,例如MKL,OpenBLAS或BLIS。

有關更多詳細信息,請參閱我們的Parallelism注釋

為什么在scikit-learn中不支持深度學習或強化學習?

深度學習和強化學習都需要豐富的詞匯來定義架構,同時深度學習還需要GPU才能進行有效的計算。但是,這些都不符合scikit-learn的設計約束。因此,深度學習和強化學習目前超出了scikit-learn力求實現的范圍。

您可以在“你會添加GPU支持嗎?”中找到有關添加gpu支持的更多信息 。

請注意,scikit-learn當前實現了一個簡單的多層感知器sklearn.neural_network。我們僅接受此模塊的錯誤修復。如果要實現更復雜的深度學習模型,請使用流行的深度學習框架,例如 tensorflowkeraspytorch

為什么我的發起請求沒有引起注意?

scikit-learn審查過程會花費大量時間,投稿者不應該因為沒有在線或未對發起的請求進行審查而灰心。我們非常注重在第一時間把事情做好,因為維護和后期更改的成本很高。我們很少發布任何“實驗”代碼,因此我們的所有貢獻都將立即受到高度使用,并且最初應具有最高的質量。

除此之外,scikit-learn的審查深度是有限的。許多審稿人和核心開發人員正在用自己的時間來研發scikit-learn。如果對您的發起請求審核緩慢,則可能是因為審核者很忙。我們希望得到您的理解,并請求您不要僅由于這個原因就關閉請求或停止工作。

如何為整個執行設置 random_state

考慮到測試性和可復制性,整個執行由單個種子控制,用于具有隨機成分的算法中的偽隨機數生成器是非常重要的。Scikit-learn沒有使用它的全局隨機狀態;當沒有提供RandomState實例或整數隨機種子作為參數時,它就依賴于numpy全局隨機狀態,可以通過numpy.random.seed來設置該狀態。例如,要將執行的numpy全局隨機狀態設置為42,可以在其腳本中執行以下操作:

import numpy as np
np.random.seed(42)

但是,全局隨機狀態在執行期間容易被其他代碼修改。因此,確保可復制性的唯一方法是將RandomState 實例傳遞到任何地方,并確保估計器和交叉驗證拆分器都具有其random_state參數集。

與其他工具相比,為什么分類變量需要在scikit-learn中進行預處理?

大多數scikit-learn都假設數據位于單個數字類型的NumPy數組或SciPy稀疏矩陣中。這些目前還沒有明確表示分類變量。因此,與R的data.frames或pandas.DataFrame不同,我們需要將分類特征顯式轉換為數值,如編碼分類特征中所述。有關使用異構(例如分類和數字)數據的示例,另請參見具有混合類型的列轉換器

為什么Scikit-learn無法直接與pandas.DataFrame等一起使用?

當前NumPy和SciPy同質的數據對象在大多數操作過程中處理效率是最高。另外還需要大量工作來支持Pandas 的分類類型。因此,將輸入限制為同質類型可以減少維護成本,并鼓勵使用有效的數據結構。

您是否打算在pipeline中實現目標y的轉換?

當前,變換僅適用于pipeline中的特征X。關于無法在pipeline中轉換y的問題由來已久。遵循github問題 #4143。同時查閱 sklearn.compose.TransformedTargetRegressor, [pipegraph](https://github.com/mcasl/PipeGraph), imbalanced-learn。請注意,Scikit-learn解決了以下情況:y在訓練之前進行了可逆變換,而在預測之后也可以進行可逆變換。Scikit-learn打算解決一些用例,其中y應該在訓練時而不是在測試時進行轉換,以進行重采樣和類似用途,例如在不平衡學習中。通常,可以使用自定義元估算器而不是pipeline來解決這些用例。