机器学习与Scikit Learn学习库
摘要:?本文介紹機器學習相關的學習庫Scikit Learn,包含其安裝及具體識別手寫體數字案例,適合機器學習初學者入門Scikit Learn。
在我科研的時候,機器學習(ML)是計算機科學領域中最先吸引我的一門學科。雖然這個概念非常簡單,但是它表現優異。以Google、AirBnb和Uber為代表的高科技公司,已經將機器學習應用于他們的產品中。當我第一次嘗試在工作中應用機器學習時,Scikit Learn庫是一個很好的起點。
針對于Python語言開發的Scikit Learn,允許開發者們輕易地將機器學習集成到自己的項目中。我希望通過一個簡單的Scikit Learn應用來教會大家學習,如果你剛接觸Python,不要感到害怕,本文會有詳細的代碼注釋講解。
安裝
在進行應用展示之前,需要安裝Scikit Learn。首先確保下載并安裝Python(本文使用Python 3)。除此之外,確保通過pip語句安裝NumPy?和 SciPy。
pip install numpy pip install scipy剩下的安裝過程很簡單,一條語句命令即可完成Scikit Learn的安裝。
pip install scikit-learn只需花費一小段時間即可安裝成功,為了讀取所舉案例的CSV?文件,還需要安裝Pandas,同樣只需一條語句即可完成安裝:
pip install pandas此時,我們已經完成全部安裝!
程序
Scikit Learn在其主頁上提供了豐富的使用案例,當我第一次使用該軟件包時,我發現這個主頁是非常有用的。為了在這里展示Scikit Learn,我打算實現一個識別數字手寫體的分類器,數據集來自于UCI數據集(由11000張圖片組成)。這個數據集來自44個參與者,每個參與者需要手寫250個數字,并且數據集中的每張圖片(也被稱作樣本)對應于0-9之間的一個手寫數字。
每個樣本用一個保存0到100之間的特征向量表示,這些值表示樣本中每個像素的強度。鑒于每個樣本大小為500x500,這樣會造成特征向量很長以至于難以處理。為了解決這個問題,圖像被重新采樣以減少像素的數目,采樣后的特征向量長度為16。
數字0到9將是分類器在分類過程中要考慮的類別集合,分類器將從30名參與者(約7500張)抽取樣本,以學習每個數字類別的樣本。剩余的樣本將被保留以測試訓練好后的分類器。每個樣本已經通過人為分類,這也意味著測試集中的每個樣本有著正確的分類(標簽)。這使得能夠通過比較預測值與實際標簽值來確定分類器的性能。
訓練數據集和測試數據集均由UCI的CSV文件提供,通過Pandas將這些文件導入Python中,命令如下:
import pandas as pddef retrieveData():trainingData = pd.read_csv("training-data.csv").as_matrix()testData = pd.read_csv("test-data.csv").as_matrix()return trainingData, testData使用read_csv讀取每個文件,以生成Pandas 數據框架,并使用as_matrix將其轉換為Numpy數組以便后續使用。這些文件的每一行都對應著一個數字樣本——由長度為16的特征向量組成,后面跟著對應的類別標簽。將特征向量與類別標簽分離有利于后續Scikit Learn的使用。
def separateFeaturesAndCategories(trainingData, testData):trainingFeatures = trainingData[:, :-1]trainingCategories = trainingData[:, -1:]testFeatures = testData[:, :-1]testCategories = testData[:, -1:]return trainingFeatures, trainingCategories, testFeatures, testCategories預處理
Scikit Learn提供的絕大多數分類器對特征縮放比較敏感,每個特征向量中的值是0到100之間,沒有一致的均值或方差。將這些特征向量進行縮放以滿足零均值和方差為1的條件,這有助于分類器在訓練和分類過程中能夠識別任何數字類別的樣本。這種預處理操作是機器學習中一個可選步驟,但我強烈推薦使用這種操作,有助于提升分類器的性能。使用Scikit Learn的預處理數據包中的StandardScalar能夠完成預處理操作,這樣證明該操作實現起來非常簡單。首先允許縮放器擬合訓練數據以學習未縮放特征是什么樣,縮放器能夠將訓練和測試數據集中的特征轉換為零均值和方差為1的特征向量。
from sklearn.preprocessing import StandardScalerdef scaleData(trainingFeatures, testFeatures):scaler = StandardScaler()scaler.fit(trainingFeatures)scaledTrainingFeatures = scaler.transform(trainingFeatures)scaledTestFeatures = scaler.transform(testFeatures)return scaledTrainingFeatures, scaledTestFeatures分類
Scikit Learn提供了一系列適合我們需求的分類器,選擇其中的隨機梯度下降分類器(SGD)作為此次舉例的分類器,這是因為我過去經常使用該分類器。首先,我們需要將分類器擬合訓練數據集(即訓練分類器)。然后,我們準備設置分類器以預測未見過的測試樣本的標簽。使用Scikit Learn,所有的這些操作只需要通過幾行代碼即可實現。
from sklearn.linear_model.stochastic_gradient import SGDClassifierdef classifyTestSamples(trainingFeatures, trainingCategories, testFeatures):clf = SGDClassifier()clf.fit(trainingFeatures, trainingCategories)predictedCategories = clf.predict(testFeatures)return predictedCategories結果
有了預測值之后,就可以與文件中提供的類別標簽進行比較。那么這里會有幾個問題,分類器效果怎樣?我們如何衡量分類器的效果?給定一個特定的衡量標準,我們在哪里設置閾值來區分不好的結果?為了回答前兩個問題,可以參考Scikit Learn的分類器度量包。我從中挑選出四個指標,分別是準確率、精度、召回率和F1分數。
Scikit Learn的accuracy_score函數能夠得出分類器的準確率,剩余的三個指標通過classification_report得到,最終打印出每個類別的準確率、精度、召回率和F1分數,并提供平均值。
from sklearn.metrics import accuracy_score, classification_reportdef gatherClassificationMetrics(testCategories, predictedCategories):accuracy = accuracy_score(testCategories, predictedCategories)metrics_report = classification_report(testCategories, predictedCategories)print("Accuracy rate: " + str(round(accuracy, 2)) + "\n")print(metrics_report)分類器運行時其指標總會有小的變化,有些情況下會得到很高的測試準確率。雖然這些預測值與文件提供的標簽值可能相一致,但也會出現分類器對其工作缺乏信心的情況。每次運行時,分類器可能會得出不同的預測結果,這可能歸結為針對特定數字的樣本數量不足或分類器遇到了與訓練集中有顯著區別的字跡。考慮到這些變化,下面是SGD分類器的一組實驗結果。
Accuracy rate: 0.84precision recall f1-score support0 0.98 0.84 0.90 3631 0.58 0.84 0.69 3642 0.97 0.81 0.88 3643 0.98 0.90 0.94 3364 0.95 0.93 0.94 3645 0.62 0.94 0.75 3356 1.00 0.96 0.98 3367 0.88 0.84 0.86 3648 0.85 0.76 0.80 3369 0.93 0.58 0.72 336avg / total 0.87 0.84 0.85 3498對于第一次嘗試而言,84%的準確率已經相當不錯了。這也提醒了我們之前提到的問題中的第三個問題——我們在哪里設置區分好結果和壞結果的閾值?這是一個棘手的問題,因為這完全取決于分類器要實現的目標,每個人考慮的好壞區分標準都不一樣。我們是否可以改進分類器,使其始終能夠比這里觀察到的結果更好嗎?
我們可以做得更好嗎?
答案是肯定的,并有很多選擇需要考慮。首先,本次舉例使用了基本的預處理操作,更復雜的縮放方法可能會進一步降低分類器的敏感度以提升相關指標。其次,本次舉例實現的是一個基本的SGD分類器,而且使用的是Scikit Learn提供的默認參數,沒有進行適當的調整。因此,我們可以改變訓練數據的迭代次數(被稱作epoch),防止分類器在每次迭代時打亂訓練數據,或者是多次運行分類器,啟用它的熱啟動屬性,以便分類器回憶之前做出的預測。
同樣值得考慮的是,我們只實現了Scikit Learn中提供的其中一種分類器。雖然SGD分類器足夠完成文中所舉的例子,但是我們也可以考慮嘗試使用一些其它的分類器,比如LinearSVC或Multinomial Naive Bayes等。機器學習的樂趣在于:有很多參數變量需要考慮,調整這些參數可能會改善或惡化整個模型嗎的性能。為任何機器學習問題尋找最佳解決方案都是一項艱巨的任務,需要通過不斷嘗試。
結論
以上是所舉例子的全部內容,文中只是介紹了一些基本知識,而Scikit Learn提供了更多豐富的內容等待著大家的探索,可以借助于其主頁找到很多有用的文檔。對于希望查看完整代碼或自行嘗試的讀者,可以在本人的Github上找到相應的CSV文件和Python代碼。
作者信息
Ross Rhodes,軟件開發工程師,擅長Java、Python。
文章原標題《Machine Learning with Scikit Learn》,作者:Ross Rhodes,譯者:海棠,審閱:?
原文鏈接
干貨好文,請關注掃描以下二維碼:
總結
以上是生活随笔為你收集整理的机器学习与Scikit Learn学习库的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Quick BI v3.0版本全新起航—
- 下一篇: 【2018新年巨献】像阿里巴巴一样高效工