版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
第9章機器學(xué)習(xí)目錄contents基于數(shù)據(jù)的學(xué)習(xí)實例:手寫數(shù)字識別實例:交通車流量預(yù)測實例:電影推薦系統(tǒng)Scikit-learn近年來,從計算機科學(xué)開始,到物理、生物、能源、醫(yī)療等領(lǐng)域,人工智能都實現(xiàn)了許多優(yōu)秀的實際應(yīng)用。如計算機視覺模型可以協(xié)助醫(yī)生開展日常工作,自然語言模型在對話翻譯中大放異彩,基于大數(shù)據(jù)的推薦系統(tǒng)能夠針對性地為用戶推薦所需信息。在這其中,機器學(xué)習(xí)算法是實現(xiàn)相關(guān)應(yīng)用的核心,是使計算機具有智能的根本途徑。在之前的章節(jié)中已經(jīng)介紹了NumPy對高維數(shù)組數(shù)據(jù)的高效處理,Matplotlib對數(shù)據(jù)的可視化分析,Scipy提供的豐富科學(xué)計算資源,這些以足夠作為開發(fā)基礎(chǔ)機器學(xué)習(xí)應(yīng)用的工具。本章將介紹Python中最普遍與流行的機器學(xué)習(xí)庫Scikit-Learn(簡稱Sklearn),該庫建立在NumPy、SciPy以及Matplotlib的基礎(chǔ)之上,因此也擁有幾乎等效于C語言的運算速度。由于該庫API設(shè)計的易用性,通過修改幾行代碼即可實現(xiàn)各類機器學(xué)習(xí)算法并進行實驗,其在學(xué)術(shù)研究與工業(yè)應(yīng)用領(lǐng)域都很流行。Scikit-learn可以通過conda或者pip安裝,由于該庫內(nèi)容龐大,在進行實驗和開發(fā)時通常只導(dǎo)入項目需要的模塊,而不像NumPy和Matplotlib一樣將整個庫導(dǎo)入?;跀?shù)據(jù)的學(xué)習(xí)01機器學(xué)習(xí)簡述早在1959年,機器學(xué)習(xí)的先驅(qū)ArthurSamuel首次對機器學(xué)習(xí)進行了定義:“機器學(xué)習(xí)是使計算機無需明確編程即可學(xué)習(xí)的研究領(lǐng)域?!背酥猓€開發(fā)了一個機器學(xué)習(xí)的跳棋程序,其通過與用戶進行跳棋游戲,在一段時間后,程序可以學(xué)習(xí)到什么是好的布局,什么是不好的布局,并且學(xué)會跳棋的基本玩法。通過長期的學(xué)習(xí)后,該程序甚至可以打敗ArthurSamuel。在那個沒有高級編程語言甚至也沒有顯示器的年代,該機器學(xué)習(xí)系統(tǒng)的開發(fā)與驗證是具有劃時代的開創(chuàng)意義的。到了1998年,卡內(nèi)基梅隆大學(xué)教授TomM.Mitchell對機器學(xué)習(xí)作出了更嚴謹?shù)亩x“一個計算機程序利用經(jīng)驗E來學(xué)習(xí)任務(wù)T,性能是P,如果針對任務(wù)T的性能P隨著經(jīng)驗E不斷增長,則稱為機器學(xué)習(xí)”。圖9-1展示了該機器學(xué)習(xí)算法的定義。機器學(xué)習(xí)簡述例如,對于一個傳統(tǒng)的垃圾電子郵件過濾系統(tǒng),設(shè)計者首先需要收集垃圾郵件中可能包含的文本信息、發(fā)件人姓名、郵件的格式等,對每種異常的模式編寫檢測算法,對于檢測到異常的郵件標記為垃圾郵件。但這種方法在實施時會極度困難,因為程序中會包含大量復(fù)雜的規(guī)則而變得難以維護。而在基于機器學(xué)習(xí)的垃圾郵件過濾系統(tǒng)中,可以使用垃圾郵件(如通過人工標記)和普通郵件作為訓(xùn)練數(shù)據(jù)(經(jīng)驗E),對垃圾郵件分類任務(wù)自動學(xué)習(xí)(任務(wù)T),分類的正確率(性能P)會隨著訓(xùn)練數(shù)據(jù)的增加不斷地增長。這意味系統(tǒng)會自動學(xué)習(xí)垃圾郵件中的特征,這類方法不僅更易維護,其分類準確率通常也更高。上述的案例使用機器學(xué)習(xí)算法判斷郵件是否為垃圾郵件,是典型的分類任務(wù)。按任務(wù)的不同,機器學(xué)習(xí)大體可分為分類、回歸、聚類、降維四種任務(wù)。分類任務(wù)和回歸任務(wù)都是基于數(shù)據(jù)作出預(yù)測,區(qū)別在于分類任務(wù)是對離散值進行預(yù)測,而回歸任務(wù)是對連續(xù)值進行預(yù)測。如預(yù)測會不會下雨是一個分類任務(wù),預(yù)測氣溫是一個回歸任務(wù)。聚類任務(wù)是按照某種特定的標準把相似的數(shù)據(jù)聚合在一起,與分類任務(wù)不同的是聚類任務(wù)對無標記訓(xùn)練樣本學(xué)習(xí)數(shù)據(jù)的內(nèi)在性質(zhì)。降維任務(wù)是針對高緯度、大規(guī)模、高復(fù)雜數(shù)據(jù),挖掘其中有意義的內(nèi)容,去除特征的冗余,用更加少的維度表示信息,從而更好地認識和理解數(shù)據(jù)。機器學(xué)習(xí)簡述按是否有標簽數(shù)據(jù),機器學(xué)習(xí)又可分為監(jiān)督學(xué)習(xí)、無監(jiān)督學(xué)習(xí)和強化學(xué)習(xí)。監(jiān)督學(xué)習(xí)的每個訓(xùn)練實例都包含輸入和期望輸出的標簽,如分類和回歸任務(wù)都屬于監(jiān)督學(xué)習(xí)。無監(jiān)督學(xué)習(xí)輸入的數(shù)據(jù)并沒有期望輸出的標簽,其利用算法探索數(shù)據(jù)中隱藏的模式,如聚類任務(wù)屬于無監(jiān)督學(xué)習(xí)。與監(jiān)督學(xué)習(xí)和無監(jiān)督學(xué)習(xí)不同,強化學(xué)習(xí)關(guān)注的是如何基于環(huán)境而行動,以取得最大化的預(yù)期利益,其不需要帶標簽的輸入輸出對,同時也無需對非最優(yōu)解的精確地糾正。強化學(xué)習(xí)注重于對未知領(lǐng)域的探索和對已有知識利的利用之間的平衡,如知名的AlphaGo圍棋就是基于強化學(xué)習(xí)算法構(gòu)建的。如圖9-2所示,這三種類型并不是完全孤立的,在實際的設(shè)計與開發(fā)中,通常會對其中的一種或多種算法進行結(jié)合構(gòu)建出適合任務(wù)特點的機器學(xué)習(xí)模型。機器學(xué)習(xí)數(shù)據(jù)準備對于機器學(xué)習(xí)算法來說,數(shù)據(jù)是及其重要的,如果沒有數(shù)據(jù)就無法進行模型的訓(xùn)練,而數(shù)據(jù)質(zhì)量過低也會導(dǎo)致模型性能降低。之前的章節(jié)介紹了基于NumPy進行數(shù)據(jù)的導(dǎo)入與處理工作,在面對復(fù)雜的數(shù)據(jù)集時,由于NumPy矩陣對數(shù)據(jù)格式的要求,會加大數(shù)據(jù)讀取工作的復(fù)雜度。事實上,在大量機器學(xué)習(xí)任務(wù)的數(shù)據(jù)準備環(huán)節(jié)中,開發(fā)者往往會選用Pandas庫對數(shù)據(jù)進行預(yù)處理。Pandas的出現(xiàn)不僅簡化了Python進行數(shù)據(jù)準備和分析的流程,更降低了其上手難度。對于機器學(xué)習(xí)算法來說,數(shù)據(jù)是及其重要的,如果沒有數(shù)據(jù)就無法進行模型的訓(xùn)練,而數(shù)據(jù)質(zhì)量過低也會導(dǎo)致模型性能降低。之前的章節(jié)介紹了基于NumPy進行數(shù)據(jù)的導(dǎo)入與處理工作,在面對復(fù)雜的數(shù)據(jù)集時,由于NumPy矩陣對數(shù)據(jù)格式的要求,會加大數(shù)據(jù)讀取工作的復(fù)雜度。事實上,在大量機器學(xué)習(xí)任務(wù)的數(shù)據(jù)準備環(huán)節(jié)中,開發(fā)者往往會選用Pandas庫對數(shù)據(jù)進行預(yù)處理。Pandas的出現(xiàn)不僅簡化了Python進行數(shù)據(jù)準備和分析的流程,更降低了其上手難度。通常以如下方式進行引用:>>>importpandasaspdPandas常用的數(shù)據(jù)讀取函數(shù)函數(shù)名描述read_csv()讀取CSV文件并轉(zhuǎn)換為DataFrame對象read_excel()讀取Excel文件并轉(zhuǎn)換為DataFrame對象read_json()讀取JSON文件并轉(zhuǎn)換為Pandas對象read_html()讀取HTML表格并轉(zhuǎn)換為DataFrame對象的列表read_pickle()讀取文件中PickledPandas對象DataFrame對象下列代碼使用read_csv()函數(shù)讀取“student.csv”文件,由于該文件中包含中文,需在讀取文件時確定編碼格式為“GB18030”,以避免亂碼現(xiàn)象的出現(xiàn)。隨后,使head(5)函數(shù)觀察數(shù)據(jù)的前五行內(nèi)容。>>>df=pd.read_csv('student.csv',encoding='GB18030')>>>df.head(5)缺失值檢測數(shù)據(jù)為NaN,代表數(shù)據(jù)缺失。在實際中,常常會由于數(shù)據(jù)收集、數(shù)據(jù)整理、數(shù)據(jù)挖掘等過程中的不完善或限制因素,造成數(shù)據(jù)缺失的問題。Pandas提供了isnull()和notnull()兩種方法對缺失值進行檢測,下列代碼對數(shù)據(jù)對象各列的缺失值進行統(tǒng)計并打印。>>>print(df.isnull().sum())學(xué)號0姓名1年齡1性別0評分2dtype:int64缺失值填充不完整的數(shù)據(jù)會給機器學(xué)習(xí)模型帶來極大挑戰(zhàn)。對于缺失數(shù)據(jù),在Pandas中常用的有使用fillna()函數(shù)進行值替換或使用dropna()函數(shù)刪除數(shù)據(jù)段兩種處理方法。下列代碼分辨展示替換缺失值0和刪除含缺失值行的方法。#將缺失值替換為0>>>print(df.fillna(value=0))
學(xué)號姓名年齡性別評分010001小明22.0男75.0110002大飛27.0男86.0210003小王22.0男0.0310004丁丁24.0女95.0410005小張20.0女79.0510006小麗22.0女81.0610007大壯21.0男0.0710008小飛22.0女83.0810009小強20.0男65.0910010021.0女76.01010011小華0.0男83.0#將包含缺失值的行刪除>>>print(df.dropna())
學(xué)號姓名年齡性別評分010001小明22.0男75.0110002大飛27.0男86.0310004丁丁24.0女95.0410005小張20.0女79.0510006小麗22.0女81.0710008小飛22.0女83.0810009小強20.0男65.0Pandas索引方法方法描述[]切片索引.loc()基于標簽的索引.iloc()基于整數(shù)的索引#使用切片索引>>>print(df[['姓名','評分']][:3])
姓名評分0小明75.01大飛86.02小王NaN#基于標簽的索引>>>print(df.loc[:2,['姓名','評分']])
姓名評分0小明75.01大飛86.02小王NaN#基于整數(shù)的索引>>>print(df.iloc[:3,[1,4]])
姓名評分0小明75.01大飛86.02小王NaNDataFrame與ndarray與NumPy相比,Pandas更適合處理包含不同數(shù)據(jù)格式的表格類數(shù)據(jù),并提供了對數(shù)據(jù)進行去重、排序、合并、統(tǒng)計、采樣等便捷的功能函數(shù)。但是,Pandas的DataFrame的內(nèi)存消耗也要高于NumPy的ndarray,在實際進行數(shù)據(jù)準備時,需根據(jù)開發(fā)和效率需求使用正確的工具。對Pandas其他功能感興趣的讀者可以根據(jù)Pandas官方網(wǎng)站提供的用戶手冊進一步學(xué)習(xí)。機器學(xué)習(xí)流程在機器學(xué)習(xí)模型與算法的開發(fā)與實施通常會遵循一套適用的流程和步驟1.獲得數(shù)據(jù)2.數(shù)據(jù)預(yù)處理3.模型建立與訓(xùn)練4.模型預(yù)測和評估獲得數(shù)據(jù)機器學(xué)習(xí)中的經(jīng)驗E本質(zhì)上是數(shù)據(jù),在開發(fā)模型前,首先需要明確需要的訓(xùn)練數(shù)據(jù)類型。數(shù)據(jù)需要對擬問題具有顯著的代表性,如對于“中文—英文”翻譯模型,諸如德語、法語等數(shù)據(jù)在一般情況下是對模型沒有明顯幫助的。隨后需要確定數(shù)據(jù)的數(shù)量,這往往取決于擬解決的問題與模型的復(fù)雜度。通常來說,越復(fù)雜的模型需要越多的數(shù)據(jù)進行訓(xùn)練。這之后最重要的步驟就是對所需的數(shù)據(jù)開展收集工作,如查閱公開的數(shù)據(jù)集、使用爬蟲程序從互聯(lián)網(wǎng)收集數(shù)據(jù)、使用傳感器收集實測數(shù)據(jù)等。如表9-3所示,Scikit-learn在sklearn.datasets中提供了一系列用于機器學(xué)習(xí)的數(shù)據(jù)集。除此之外,sklearn.datasets還提供了從中下載數(shù)據(jù)集的接口。出于時間和成本的考慮,在收集數(shù)據(jù)時應(yīng)首先考慮公開的數(shù)據(jù)集Scikit-learn中常用的內(nèi)置數(shù)據(jù)集方法描述任務(wù)load_iris()鳶尾花數(shù)據(jù)集分類load_digits()數(shù)字數(shù)據(jù)集分類load_wine()葡萄酒數(shù)據(jù)集分類load_breast_cancer()威斯康星乳腺癌數(shù)據(jù)集分類load_diabetes()糖尿病數(shù)據(jù)集回歸load_linnerud()林納魯?shù)麦w能訓(xùn)練數(shù)據(jù)集(多輸出)回歸數(shù)據(jù)預(yù)處理在機器學(xué)習(xí)的訓(xùn)練數(shù)據(jù)中,通常包含著大量的特征,每個特征的性質(zhì)、量綱、數(shù)量級、可用性等都可能存在一定的差異。若特征之間差異較大時,直接使用原始數(shù)據(jù)分析會造成特征的不平衡。如在考慮不同時期的物價指數(shù)時,若將較低價格的食品和較高價格的汽車的價格漲幅一并納入特征,會導(dǎo)致汽車在綜合指數(shù)中的作用被放大。因此,在訓(xùn)練機器學(xué)習(xí)模型前,通常需要對數(shù)據(jù)進行預(yù)處理工作。對于數(shù)字數(shù)據(jù),為了保持其數(shù)量級上的統(tǒng)一,最常用的預(yù)處理方式是數(shù)據(jù)標準化。其做法是對數(shù)據(jù)集中的數(shù)據(jù)首先減去平均值,再除以標準差,將數(shù)據(jù)映射至平均值為0且有相同階數(shù)的方差。數(shù)據(jù)標準化處理>>>importsklearn>>>importnumpyasnp>>>importmatplotlib.pyplotasplt#設(shè)置中文顯示>>>pltrcParams['font.sans-serif']=['SimHei']>>>plt.rcParams['axes.unicode_minus']=False#生成正態(tài)分布的測試數(shù)據(jù)>>>x=np.random.normal(-10,10,1000)>>>y=np.random.normal(-5,2,1000)>>>data=np.stack([x,y],axis=-1)#對數(shù)據(jù)進行標準化處理>>>scaler=sklearn.preprocessing.StandardScaler()>>>scaler.fit(data)>>>trans_data=scaler.transform(data)#可視化對比>>>fig,ax=plt.subplots(1,2,figsize=(9,4),dpi=300)>>>ax[0].scatter(data[:,0],data[:,1])>>>ax[0].grid()>>>ax[0].axis([-40,40,-40,40])>>>ax[0].set(xlabel='x軸',ylabel='y軸',title='原始數(shù)據(jù)')>>>ax[1].scatter(trans_data[:,0],trans_data[:,1],color='red')>>>ax[1].axis([-40,40,-40,40])>>>ax[1].grid()>>>ax[1].set(xlabel='x軸',ylabel='y軸',title='標準化處理后的數(shù)據(jù)')>>>plt.show()數(shù)據(jù)集劃分機器學(xué)習(xí)算法最終的目的是將訓(xùn)練好的模型部署至真實環(huán)境中,并希望模型能夠在未知的數(shù)據(jù)上得到較好的預(yù)測效果。因此,模型在訓(xùn)練數(shù)據(jù)集上的表現(xiàn)并不能完全代表模型的泛化能力。為此,在訓(xùn)練機器學(xué)習(xí)模型時需要將數(shù)據(jù)分割為訓(xùn)練集(Train)和測試集(Test)兩個部分。在模型訓(xùn)練時只使用訓(xùn)練集數(shù)據(jù),然后用測試集數(shù)據(jù)上的誤差作為模型應(yīng)對真實場景中的泛化誤差。劃分數(shù)據(jù)集必須在開始構(gòu)建之前模型完成,防止數(shù)據(jù)窺探偏誤。通常來說,應(yīng)該將數(shù)據(jù)集的大部分(80%以上)劃撥為訓(xùn)練集,以保證模型能夠從足夠的樣本中學(xué)習(xí)到數(shù)據(jù)的模式。當涉及到根據(jù)預(yù)測結(jié)果調(diào)整模型參數(shù)時(通常稱為模型的超參數(shù)),為了保證無偏估計不可以直接在測試集數(shù)據(jù)上進行模型調(diào)整。為此,可以將訓(xùn)練集數(shù)據(jù)進一步劃分為訓(xùn)練集與驗證集(Validation),通過驗證集評估模型,再通過測試集觀察模型的泛化能力。train_test_split()sklearn.model_selection.train_test_split(*arrays,**options)下列代碼使用該函數(shù)將使用NumPy生成模擬數(shù)據(jù)集并劃分為80%的訓(xùn)練集和20%的測試集>>>fromsklearn.model_selectionimporttrain_test_split>>>importnumpyasnp>>>X,y=np.arange(10).reshape((5,2)),range(5)>>>X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.2)模型建立與訓(xùn)練在完成數(shù)據(jù)預(yù)處理后,需要選擇合適的算法開展訓(xùn)練。表9-4列出了Scikit-learn庫針對分類、回歸、聚類、降維等機器學(xué)習(xí)任務(wù)提供的常用算法。在實際應(yīng)用中,需要考慮算法的應(yīng)用場景和可用的數(shù)據(jù)形式。若數(shù)據(jù)帶有標簽,則根據(jù)輸出的數(shù)據(jù)是否連續(xù)選擇回歸或分類算法。若數(shù)據(jù)沒有標簽,如需將數(shù)據(jù)劃分為離散的組,則使用聚類算法;若僅需要對數(shù)據(jù)的維度進行約簡,則使用降維算法。確定好任務(wù)類型后,需對算法進行合適的選擇。當數(shù)據(jù)的特征數(shù)較少時,簡單的模型就可以保證足夠的學(xué)習(xí)和泛化能力。當特征數(shù)較大時,往往應(yīng)選擇諸如集成學(xué)習(xí)的較復(fù)雜的模型。隨著數(shù)據(jù)量的增大,對模型復(fù)雜度要求也會增加,使其能夠充分學(xué)習(xí)大量數(shù)據(jù)提供的信息。Scikit-learn中常用的機器學(xué)習(xí)算法任務(wù)類型算法名稱Scikit-learn中類名稱回歸線性回歸linear_model.LinearRegression()嶺回歸linear_model.Ridge()LASSO回歸linear_model.Lasso()貝葉斯嶺回歸linear_model.BayesianRidge()核函數(shù)嶺回歸kernel_ridge.KernelRidge()線性支持向量回歸svm.LinearSVR()決策樹回歸tree.DecisionTreeRegressor()隨機森林回歸ensemble.RandomForestRegressor()梯度提升回歸ensemble.GradientBoostingRegressor()分類邏輯回歸linear_model.LogisticRegression()嶺回歸分類linear_model.RidgeClassifier()線性感知器分類linear_model.Perceptron()線性支持向量分類svm.LinearSVC()決策樹分類tree.DecisionTreeClassifier(隨機森林分類ensemble.RandomForestClassifier()梯度提升分類ensemble.GradientBoostingClassifier()聚類K-Means聚類cluster.KMeans()DBSCAN聚類cluster.DBSCAN()均值偏移聚類cluster.MeanShift()譜聚類cluster.SpectralClustering()降維主成成分分析降維decomposition.PCA()截斷SVD降維decomposition.TruncatedSVD()非負矩陣分解decomposition.NMF()fit()函數(shù)在確定模型使用的機器學(xué)習(xí)算法后,即可利用訓(xùn)練數(shù)據(jù)對模型進行訓(xùn)練。由于Scikit-learn在設(shè)計時統(tǒng)一了API,因此模型的訓(xùn)練與數(shù)據(jù)預(yù)處理中一樣,只需在選擇的對象上使用fit()方法既可以展開訓(xùn)練。下列代碼首先使用NumPy生成模擬數(shù)據(jù)作為數(shù)據(jù)集,劃分80%為訓(xùn)練集。構(gòu)建線性回歸算法的模型,利用訓(xùn)練數(shù)據(jù)訓(xùn)練該模型,并將訓(xùn)練好的模型賦值給reg。>>>fromsklearn.linear_modelimportLinearRegression>>>X,y=np.arange(10).reshape((5,2)),range(5)>>>X_train,X_test,y_train,y_test=train_test_split(X,y,train_size=0.8)>>>reg=LinearRegression().fit(X_train,y_train)模型預(yù)測和評估獲得訓(xùn)練好的模型后,即可調(diào)用predict()方法對數(shù)據(jù)進行輸出預(yù)測。然而僅僅觀察預(yù)測輸出并不能直觀地反映模型的性能。sklearn.metrics針對不同機器學(xué)習(xí)任務(wù)的實現(xiàn)了各類指標函數(shù),以科學(xué)地評估模型性能。任務(wù)類型指標名稱方法名稱描述分類準確率accuracy_score()正確分類樣本的比例召回率recall_score()正樣本中預(yù)測正確的百分比F1分數(shù)f1_score()準確率和召回率的調(diào)和平均值A(chǔ)UCroc_auc_score()ROC曲線下方的面積回歸平均絕對誤差mean_absolute_error()絕對誤差均方誤差mean_squared_error()二次誤差R2分數(shù)r2_score()決定系數(shù)最大誤差max_error()誤差的最大值聚類蘭德指數(shù)rand_score()聚類的相似性度量調(diào)整蘭德指數(shù)adjusted_rand_score()改進的蘭德系數(shù)完整性completeness_score()類的所有成員都在同個集群同質(zhì)性homogeneity_score()每個集群只包含單個類的成員模型預(yù)測和評估通常來說,對模型的評價是在驗證集上進行的。若模型在訓(xùn)練集上表現(xiàn)很好,但在驗證集上表現(xiàn)較差,則很可能發(fā)生了“過擬合”現(xiàn)象,即模型學(xué)習(xí)能力過強,以至于將訓(xùn)練數(shù)據(jù)中單個樣本的噪聲、不均勻分布等都進行了學(xué)習(xí),這導(dǎo)致了模型的泛化能力下降,以至于其在未知數(shù)據(jù)上的表現(xiàn)下降。若判斷出現(xiàn)“過擬合”現(xiàn)象,可以考慮給減少數(shù)據(jù)的特征數(shù)量、給模型增加正則化等手段調(diào)節(jié)模型。若模型無論在測試集還是驗證集上都有較大的誤差,則很可能發(fā)生了“欠擬合”現(xiàn)象,即模型過于簡單,無法充分學(xué)習(xí)數(shù)據(jù)的模式。若判斷出現(xiàn)“欠擬合”現(xiàn)象,可以選擇增加模型的復(fù)雜度或添加新的域特有特征和更多特征笛卡爾積,并更改特征處理所用的類型。模型預(yù)測和評估下列代碼首先使用NumPy生成模擬數(shù)據(jù)作為數(shù)據(jù)集,劃分80%為訓(xùn)練集。構(gòu)建線性回歸算法的模型,調(diào)用fit()方法使用訓(xùn)練數(shù)據(jù)訓(xùn)練該模型。調(diào)用predict()方法在測試集上預(yù)測數(shù)據(jù)。最后使用r2_score()計算預(yù)測數(shù)據(jù)和實際數(shù)據(jù)的R-squared分數(shù)。由結(jié)果可知,在測試集上模型的R-squared分數(shù)為0.89802,較為接近1,表示預(yù)測情況和真實情況的吻合度較高。>>>fromsklearn.metricsimportr2_score>>>X,y=np.arange(30).reshape((15,2)),range(15)>>>y+=np.random.randn(15)>>>X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.20)>>>reg=LinearRegression().fit(X_train,y_train)>>>y_predict=reg.predict(X_test)>>>print('在測試集上的R-squared分數(shù)為{:.5f}'.format(r2_score(y_predict,y_test)))在測試集上的R-squared分數(shù)為0.89802實例:手寫數(shù)字識別01問題分析手寫數(shù)字識別是機器學(xué)習(xí)領(lǐng)域中的一個經(jīng)典應(yīng)用,其地位在某種程度上可以相當于入門編程語言時的“HelloWorld”。該任務(wù)的目的是計算機能正確從紙質(zhì)文檔、照片或其他接收來源接受和理解并識別可讀的手寫數(shù)字的的能力。若計算機能達到較高的識別正確率,便可應(yīng)用于信件的郵政編碼自動識別等領(lǐng)域之中。然而,利用傳統(tǒng)的圖像處理手段在該問題上并不能達到較滿意的結(jié)果,雖然只是針對0至9之間的十個數(shù)字的識別,但手寫字體的多樣性、數(shù)字之間的混淆性(如4和9)等因素都造成了識別的困難。在本節(jié)中,將建立數(shù)據(jù)驅(qū)動的機器學(xué)習(xí)算法識別手寫數(shù)字的模式特征,從而達到正確的分類結(jié)果。模塊導(dǎo)入與設(shè)置本案例中將使用到如下的庫與模塊,首先將其進行導(dǎo)入同時,本案例的可視化分析涉及到中文的使用,需要進行設(shè)置>>>importnumpyasnp>>>importmatplotlib.pyplotasplt>>>fromsklearnimportdatasets,metrics>>>fromsklearn.model_selectionimporttrain_test_split>>>fromsklearn.datasetsimportfetch_openml>>>fromsklearn.utilsimportcheck_random_state>>>fromsklearn.preprocessingimportStandardScaler>>>fromsklearn.linear_modelimportLogisticRegression>>>plt.rcParams['font.sans-serif']=['SimHei']>>>plt.rcParams['axes.unicode_minus']=FalseMNIST數(shù)據(jù)集手寫數(shù)字識別的研究歷史可追溯至上世紀,在1988年,著名的MNIST數(shù)據(jù)集(MixedNationalInstituteofStandardsandTechnologyDatabase)問世。該數(shù)據(jù)集由來自高中學(xué)生與人口普查局雇員的手寫數(shù)字構(gòu)成,包括訓(xùn)練與測試在內(nèi)一共有70000張圖像。每張圖像都是單通道的灰度圖像。該數(shù)據(jù)集數(shù)據(jù)量適中,數(shù)據(jù)質(zhì)量較高,直至今日仍被廣泛用于驗證機器學(xué)習(xí)算法的有效性。MNIST數(shù)據(jù)集可以在網(wǎng)站中獲取,作為經(jīng)典的數(shù)據(jù)集,sklearn.datasets中也封裝了自動下載該數(shù)據(jù)集的方法。下列代碼使用fetch_openml方法從機器學(xué)習(xí)數(shù)據(jù)和實驗的公共存儲庫OpenML中下載MNIST數(shù)據(jù)集,并將圖像與標簽數(shù)據(jù)賦值給對應(yīng)的變量X和y,并打印出數(shù)據(jù)集的基本情況。>>>X,y=fetch_openml("mnist_784",version=1,return_X_y=True,as_frame=False)>>>print("數(shù)據(jù)集共包含{}個樣本\n每個輸入數(shù)據(jù)的形狀為{},每個標簽的形狀為{}".format(X.shape[0],X.shape[1],1))數(shù)據(jù)集共包含70000個樣本每個輸入數(shù)據(jù)的形狀為784,每個標簽的形狀為1MNIST數(shù)據(jù)集中各個數(shù)字的數(shù)據(jù)量>>>digits,counts=np.unique(y,return_counts=True)#數(shù)字類型及其數(shù)據(jù)量>>>plt.figure(figsize=(12,8))>>>b=plt.bar(digits,counts,alpha=0.5)>>>plt.bar_label(b,padding=5)#為每個柱狀圖添加標簽>>>plt.xlabel('數(shù)字')>>>plt.ylabel('數(shù)據(jù)量')>>>plt.grid(axis='y')>>>plt.title('MNIST數(shù)據(jù)集各個數(shù)字的數(shù)據(jù)量')>>>plt.show()MNIST數(shù)據(jù)集可視化>>>defplot_digits(data,label,title):...plt.figure(figsize=(12,12))...foriinrange(16):...plt.subplot(4,4,i+1)...plt.imshow(data[i].reshape(28,28),cmap='gray',interpolation='none')...plt.title("數(shù)字:{}".format(label[i]))...plt.xticks([])...plt.yticks([])...plt.suptitle(title)...plt.tight_layout()...plt.show()>>>plot_digits(X,y,'MNIST數(shù)據(jù)集')MNIST數(shù)據(jù)集標準化>>>defscaler_input(data):...scaler=StandardScaler()...data=scaler.fit_transform(data)...returndata>>>X_scaler=scaler_input(X)>>>print('原始輸入數(shù)據(jù)的均值為{:.2f},標準差為{:.2f}\n經(jīng)過標準化處理后數(shù)據(jù)的均值為{:.2f},標準差為{:.2f}'.format(X.mean(),X.std(),X_scaler.mean(),X_scaler.std()))原始輸入數(shù)據(jù)的均值為33.39,標準差為78.65經(jīng)過標準化處理后數(shù)據(jù)的均值為0.00,標準差為0.96>>>plot_digits(X_scaler,y,'MNIST數(shù)據(jù)集(標準化處理后)')MNIST數(shù)據(jù)集劃分>>>deftrain_validation_split(X,y,train_size):...random_state=check_random_state(0)...permutation=random_state.permutation(X.shape[0])...X=X[permutation]...y=y[permutation]...X=X.reshape((X.shape[0],-1))...X_train,X_val,y_train,y_val=train_test_split(...X,y,train_size=train_size)...returnX_train,X_val,y_train,y_val>>>X_train,X_val,y_train,y_val=train_validation_split(X_scaler,y,0.9)>>>print('劃分后,訓(xùn)練集中有{}個樣本,驗證集中有{}個樣本。'.format(X_train.shape[0],X_val.shape[0]))劃分后,訓(xùn)練集中有63000個樣本,驗證集中有7000個樣本.Sigmoid函數(shù)如上小節(jié)介紹,MNIST數(shù)據(jù)集包含了圖像數(shù)據(jù)與其對應(yīng)的數(shù)字類別標簽。由于數(shù)字類別是一種離散數(shù)據(jù),手寫數(shù)字問題的識別本質(zhì)上是監(jiān)督學(xué)習(xí)中的分類問題,即輸入圖片,判斷其屬于數(shù)字0至9之間的哪一類別。在本案例中,將使用機器學(xué)習(xí)分類任務(wù)中的邏輯回歸算法(LogisticRegression),配合正則化技術(shù),實現(xiàn)手寫數(shù)字的分類識別。邏輯回歸盡管以回歸命名算法,但其實際上是分類模型而不是線性模型,在一些文獻資料中,其也被稱為logit回歸、最大熵分類、對數(shù)線性分類器等。對于二分類的邏輯回歸算法,其首先將權(quán)重矩陣與輸入特征向量相乘,得到再將其輸入至Sigmoid映射函數(shù)進行非線性變換得到輸出預(yù)測。Sigmoid函數(shù)的公式如下Sigmoid函數(shù)#定義Sigmoid函數(shù)>>>sigmoid=lambdax:1./(1.+np.exp(-x))>>>x=np.linspace(-5,5,100)>>>plt.figure(figsize=(10,6))#繪制Sigmoid函數(shù)>>>plt.plot(x,sigmoid(x))#以紅色點劃線繪制水平輔助線>>>plt.plot(x,0.5*np.ones_like(x),'r-.')>>>plt.xlim([-5,5])>>>plt.title('Sigmoid函數(shù)')>>>plt.grid()>>>plt.show()多分類領(lǐng)域當分類問題由二分類推廣至多分類領(lǐng)域時,有一種直觀地解決方案稱之為one-versus-rest。其本質(zhì)思想是將一個多分類問題轉(zhuǎn)化為多個二分類問題,即選擇其中一項為正類,其余所有類別為負類。如在手寫數(shù)字識別中,建立10個數(shù)字分類器,每個分類器將對應(yīng)的數(shù)字字符定義為正類,其他字符定義為負類。在預(yù)測時,將利用這10個二分類器進行分類,得到數(shù)據(jù)屬于當前類的概率,選擇其中最大的一個類別作為最終結(jié)果。但該方法在訓(xùn)練樣本分布不均且類別較多的情況下,容易出現(xiàn)正類的數(shù)量遠不及負類的數(shù)量,從而造成分類器的偏向性。one-versus-rest中手寫數(shù)字識別的二分類器方法正類負類二分類器0數(shù)字0數(shù)字1至數(shù)字9二分類器1數(shù)字1數(shù)字0、數(shù)字2至數(shù)字9二分類器2數(shù)字2數(shù)字0至數(shù)值1,數(shù)字3至數(shù)字9……二分類器9數(shù)字9數(shù)字0至數(shù)字8Softmax函數(shù)除此之外,還可以將二分類邏輯回歸通過映射函數(shù)的方式直接變更為多分類邏輯回歸。其將Sigmoid映射函數(shù)更換為Softmax函數(shù),該函數(shù)將特征的加權(quán)求和結(jié)果映射至多個0-1之間的數(shù)值,從而得到概率分布。對于擁有個類別的多分類模型,每個類別的Softmax值為與Sigmoid函數(shù)相似,Softmax同樣是非線性指數(shù)函數(shù)且嚴格遞增,有較好的求導(dǎo)性質(zhì),且該函數(shù)計算每個類別的和為1,對概率分布達到了歸一化。損失函數(shù)邏輯回歸算法通過計算預(yù)測值與真實值之間的交叉熵(Cross-Entropy)作為損失函數(shù),其衡量概率分布之間的相似度,當交叉熵損失函數(shù)值較大時,代表模型效果較差。因此使用數(shù)據(jù)持續(xù)最小化交叉熵損失函數(shù)能夠提升模型的性能。正則化MNIST數(shù)據(jù)集中的每幅圖像的尺寸為(28,28),即共有784個特征。如在9.1.3中所介紹的,機器學(xué)習(xí)中當特征數(shù)量較多時,可能會出導(dǎo)致對訓(xùn)練數(shù)據(jù)的過度擬合,導(dǎo)致高方差,使得模型雖然在訓(xùn)練數(shù)據(jù)集上有較好的表現(xiàn),但在未知樣本的預(yù)測上卻表現(xiàn)較差。為此,可采取在損失函數(shù)中增加正則項的方法,減小高階次項對模型整體的影響,降低模型的復(fù)雜度,以此提升模型的泛化能力。常用的正則化手段有L1正則化與L2正則化。L1正則化在損失函數(shù)上增加正則系數(shù)乘以所有權(quán)重絕對值之和。當權(quán)重更新時,若權(quán)重值過大,則無法有效降低損失函數(shù)值,從而避免某些維度上權(quán)重過大而過分依賴對應(yīng)維度的線性。由于L1正則化采取了絕對值的方式,能進一步加強權(quán)重的稀疏性。與之相比,L2正則化在損失函數(shù)上在損失函數(shù)上加上正則系數(shù)乘以所有權(quán)重的平方和,其同樣可以防止權(quán)重過大,從而降低網(wǎng)絡(luò)復(fù)雜度。但是由于L2正則化平方和的形式,在權(quán)重較小時其平方進一步減小,因此無法像采用絕對值和的L1正則化一樣加強權(quán)重的稀疏性。在一些機器學(xué)習(xí)算法的設(shè)計中,有時也會采用L1正則化與L2正則化相結(jié)合的手段。正則化在sklearn.linear_model的LogisticRegression中已經(jīng)完整地封裝了邏輯回歸的算法,可直接通過關(guān)鍵字參數(shù)定義多分類方法、正則化手段、優(yōu)化器等模型設(shè)置。在本案例中將訓(xùn)練兩個多分類邏輯回歸模型,分別采用L1和L2正則化手段,設(shè)定相同的正則化系數(shù)。選擇SAGA算法作為求解器,該算法是SAG(StochasticAverageGradient)算法的加速版本。當樣本數(shù)量遠大于特征數(shù)量時,該求解器的速度很快,并且能夠優(yōu)化如L1正則項這樣非光滑目標函數(shù)。上述這些在模型開始訓(xùn)練學(xué)習(xí)前設(shè)置的相關(guān)參數(shù)也被稱作“超參數(shù)”,其不是通過訓(xùn)練學(xué)習(xí)得到而是通過人工或網(wǎng)格搜索等技術(shù)得到。在機器學(xué)習(xí)實戰(zhàn)中常提及的“調(diào)參”實質(zhì)上就是對超參數(shù)選取的調(diào)整。帶正則化的分類器#構(gòu)建帶有L1正則化的邏輯回歸模型>>>clf_L1=LogisticRegression(C=0.0001,...penalty="l1",...multi_class="multinomial",...solver="saga")#訓(xùn)練帶有L1正則化的邏輯回歸模型>>>clf_L1.fit(X_train,y_train)#構(gòu)建帶有L2正則化的邏輯回歸模型>>>clf_L1=LogisticRegression(C=0.0001,...penalty="l2",...multi_class="multinomial",...solver="saga")#訓(xùn)練帶有L2正則化的邏輯回歸模型>>>clf_L1.fit(X_train,y_train)結(jié)果分析在完成模型訓(xùn)練后,可以通過測試數(shù)據(jù)對模型的預(yù)測結(jié)果開展分析。在此案例中,重點關(guān)注模型的稀疏性與其在驗證集上分類的正確性。下列代碼接受訓(xùn)練好的模型為輸入,統(tǒng)計模型中權(quán)重為0的權(quán)重個數(shù),通過百分比計算其稀疏性,使用score()方法對計算驗證集上模型預(yù)測與實際標簽的平均準確度進行打印。>>>defscore_print(model,penalty_name):...sparsity=np.mean(model.coef_==0)*100...score=model.score(X_val,y_val)...print("帶%s懲罰項邏輯回歸的稀疏性:%.2f%%"%(penalty_name,sparsity))...print("帶%s懲罰項邏輯回歸的驗證集分數(shù):%.4f"%(penalty_name,score))>>>score_print(clf_L1,'L1')帶L1懲罰項邏輯回歸的稀疏性:85.83%帶L1懲罰項邏輯回歸的驗證集分數(shù):0.9087>>>score_print(clf_L2,'L2')帶L2懲罰項邏輯回歸的稀疏性:8.29%帶L2懲罰項邏輯回歸的驗證集分數(shù):0.9204L1邏輯回歸權(quán)重可視化通過可視化分類向量的權(quán)重可以進一步探究模型的稀疏性。由于該問題有10個類別,因此權(quán)重對應(yīng)為(10,784),每一項代表一個對應(yīng)的分類。下列代碼定義了繪制各個類別權(quán)重的函數(shù)。其使用coef方法獲得模型的權(quán)重,構(gòu)建包含2行5列10張子圖的畫布,對每個類別繪制其對應(yīng)的權(quán)重圖像,>>>defplot_classification_vector(model,title):...coef=model.coef_.copy()...plt.figure(figsize=(12,4))...scale=np.abs(coef).max()...foriinrange(10):...sub_plot=plt.subplot(2,5,i+1)...sub_plot.imshow(coef[i].reshape(28,28),...interpolation="nearest",...cmap=plt.cm.RdGy,...vmin=-scale,vmax=scale)...sub_plot.set_xticks([])...sub_plot.set_yticks([])...sub_plot.set_xlabel("數(shù)字%i"%i)...plt.suptitle(title)...plt.show()e)>>>plot_classification_vector(clf_L1,'L1邏輯回歸的分類向量')L2邏輯回歸權(quán)重可視化>>>plot_classification_vector(clf_L2,'L2邏輯回歸的分類向量')混淆矩陣在監(jiān)督學(xué)習(xí)中,可以通過混淆矩陣(也稱誤差矩陣)的方式可視化評價分類的精度。其縱軸為真實值的類別,橫軸為預(yù)測值的類別,可以直觀地展示多個類別是否有混淆(即其中一個類別被預(yù)測為其他類別),從而明確了解分類模型的表現(xiàn)。在矩陣中,對角線上的位置表示正確分類的類別數(shù)量,對角線以外的位置為模型對該樣本預(yù)測錯誤。在sklearn.metrics中封裝了根據(jù)預(yù)測數(shù)據(jù)與真實標簽顯示混淆矩陣的方法,下列函數(shù)對其進行了封裝。>>>defplot_confusion_matrix(predict,label,title):...disp=metrics.ConfusionMatrixDisplay.from_predictions(label,predict)...disp.figure_.suptitle(title)...plt.show()混淆矩陣>>>predict_l1=clf_L1.predict(X_val)>>>plot_confusion_matrix(predict_l1,y_val,'L1邏輯回歸混淆矩陣')>>>predict_l2=clf_L2.predict(X_val)>>>plot_confusion_matrix(predict_l2,y_val,'L2邏輯回歸混淆矩陣')結(jié)果可視化除此之外,還可以通過定性地可視化分析來直觀感受模型在哪些樣本上出現(xiàn)了錯誤分類。下列代碼定義了可視化模型在數(shù)據(jù)集上錯誤分類樣本圖像的函數(shù)。其首先利用NumPy的高級索引計算模型在驗證集上的預(yù)測值與標簽值不相等樣本的索引。再繪制包含4行4列16個子圖的畫布,可視化驗證集中分類錯誤的前16個樣本,并以每個樣本的真實值與預(yù)測值為對應(yīng)子圖的標題。>>>defplot_wrong_digits(clf,data,label,title):...#計算預(yù)測錯誤樣本的索引...index=np.arange(0,label.shape[0])...target=clf.predict(data)...wrong_index=index[target!=label]...#可視化圖像...plt.figure(figsize=(12,12))...foriinrange(16):...plt.subplot(4,4,i+1)...plt.imshow(data[wrong_index[i]].reshape(28,28),cmap='gray',interpolation='none')...plt.title("真實值:{}\n預(yù)測值:{}".format(label[wrong_index[i]],target[wrong_index[i]]))...plt.xticks([])...plt.yticks([])...plt.suptitle(title)...plt.tight_layout()...plt.show()結(jié)果可視化>>>plot_wrong_digits(clf_L1,X_val,y_val,'L1邏輯回歸驗證集中預(yù)測錯誤的樣本')>>>plot_wrong_digits(clf_L2,X_val,y_val,'L2邏輯回歸驗證集中預(yù)測錯誤的樣本')實例:交通車流量預(yù)測01問題分析城市化的推進顯著提高了城市居民出行的機動化率,但交通擁堵、交通安全、環(huán)境污染、能源消耗等現(xiàn)象與問題也日益突出。準確可靠的交通流量預(yù)測可以為政府的工作與車主的出行規(guī)劃提供極大的幫助,并有效預(yù)防一系列交通問題。交通流量實際上是一種具有周期性、時空性的數(shù)據(jù),在擁有足夠數(shù)據(jù)樣本時,可以通過機器學(xué)習(xí)的方法對交通流量的數(shù)據(jù)模式進行分析與識別,從而達到預(yù)測該路段未來車流量的目的。在本節(jié)案例中,將基于某路段的交通車流量數(shù)據(jù)集,建立能夠預(yù)測車流量的機器學(xué)習(xí)回歸模型。模塊導(dǎo)入與設(shè)置本案例中將使用到如下的庫與模塊,首先將其進行導(dǎo)入同時,本案例的可視化分析涉及到中文的使用,需要進行設(shè)置>>>importnumpyasnp>>>importpandasaspd>>>importmatplotlib.pyplotasplt>>>fromsklearnimportmetrics>>>fromsklearn.kernel_ridgeimportKernelRidge>>>fromsklearn.preprocessingimportMinMaxScale>>>plt.rcParams['font.sans-serif']=['SimHei']>>>plt.rcParams['axes.unicode_minus']=False車流量數(shù)據(jù)讀取本案例中使用到的交通車流量數(shù)據(jù)保存在“Traffic_flow.csv”文件中,首先使用如下代碼將該csv文件通過pandas讀取為DataFrame對象,以便對數(shù)據(jù)進行分析與預(yù)處理。由于文件中有中文,在讀取時選擇編碼方式為“GB18030”可防止亂碼。>>>df=pd.read_csv('Traffic_flow.csv',encoding='GB18030')>>>df#此語句為在交互環(huán)境的顯示方法,在非交互環(huán)境中,需輸入print(df)車流量數(shù)據(jù)分析該數(shù)據(jù)集一共由五個特征組成,分別是:一天中的第幾個小時:由[0,23]之間的整數(shù)構(gòu)成,指代該條車流量信息所屬于哪一小時;一周中的第幾天:由[0,6]之間的整數(shù)構(gòu)成,其中數(shù)字0表示星期天,指代該條車流量信息屬于星期幾;一年中的第幾天:由[0,365]之間的整數(shù)構(gòu)成,指代該條車流量信息屬于哪一天;一年中的幾周:由[0.53]之間的整數(shù)構(gòu)成,指代車該條車流量信息屬于哪一軸;車流量:該小時內(nèi)路段上經(jīng)過車輛的數(shù)量。>>>df.describe()車流量數(shù)據(jù)分析僅觀察數(shù)字仍無法直觀了解數(shù)據(jù)集中數(shù)據(jù)的分布,下列代碼提取車流量特征,將其按照在數(shù)據(jù)集中的順序,繪制數(shù)據(jù)集中所有小時車流量的數(shù)據(jù)>>>data=np.array(df)>>>fig=plt.figure(figsize=(16,6))>>>plt.plot(data[:,4],linewidth=.3)>>>plt.xlim([0,data.shape[0]])>>>plt.xlabel('小時ID')>>>plt.ylabel('車流量')>>>plt.title('交通車流量數(shù)據(jù)')>>>plt.show()全年周內(nèi)每小時平均車流量>>>average_week_flow=df.groupby(["一周中的第幾天","一天中的第幾個小時"]).mean()['車流量']>>>fig,ax=plt.subplots(figsize=(12,4))>>>average_week_flow.plot(ax=ax)>>>ax.grid()>>>ax.set(...title='全年周內(nèi)每小時平均車流量',...xticks=[i*24foriinrange(7)],...xticklabels=["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],...xlabel="星期",...ylabel="平均車流量")>>>plt.show()每小時車流量與最大車流量比例直方圖>>>fig,ax=plt.subplots(figsize=(12,4))>>>fraction=df["車流量"]/df["車流量"].max()>>>fraction.hist(bins=50,ax=ax,alpha=0.5)>>>ax.set(...title='每小時車流量與最大車流量比例直方圖',...xlabel="車流量與最大車流量的比例",...ylabel="小時數(shù)")>>>plt.show()數(shù)據(jù)集預(yù)處理在完成數(shù)據(jù)集的基礎(chǔ)分析后,通過下列代碼構(gòu)建用于機器學(xué)習(xí)模型的訓(xùn)練集與驗證集。其中輸入數(shù)據(jù)為數(shù)據(jù)集中除去車流量的剩余四個特征,由于四個特征的數(shù)據(jù)尺度不一,首先使用sklearn.preprocessing中的MinMaxScaler將其統(tǒng)一縮放至[0,1]區(qū)間內(nèi),輸出的預(yù)測數(shù)據(jù)采用當前小時車流量與數(shù)據(jù)集中最大車流量的比值,其取值亦屬于[0,1]之間的區(qū)間。在劃分時需要注意該數(shù)據(jù)集是一種時間序列,即交通流量與時間先后存在關(guān)系,因此本案例中不對數(shù)據(jù)集進行打亂重組。這里設(shè)置訓(xùn)練集與驗證集的比例為9:1。>>>X=df.drop('車流量',axis='columns')>>>y=fraction#將特征數(shù)值縮放至[0,1]區(qū)間>>>scaler=MinMaxScaler()>>>X_scaler=scaler.fit_transform(X)#劃分數(shù)據(jù)集函數(shù)>>>deftrain_validation_split(X,y,train_size):...data_size=len(y)...idx=int(data_size*train_size)...X_train,X_val=X[:idx,],X[idx:,]...y_train,y_val=y[:idx],y[idx:]...returnX_train,X_val,y_train,y_val#劃分數(shù)據(jù)集>>>X_train,X_val,y_train,y_val=train_validation_split(X_scaler,y,0.9)交通流量數(shù)據(jù)集的劃分>>>fig=plt.figure(figsize=(16,6))>>>plt.plot(y_train,'k-',linewidth=.2)>>>plt.plot(y_val,'k-',linewidth=.3)>>>plt.axvspan(y_val.index[0],y_val.index[-1],alpha=0.2,color='red')>>>plt.xlim([0,data.shape[0]])>>>plt.xlabel('小時ID')>>>plt.ylabel('車流量')>>>plt.title('數(shù)據(jù)集劃分')>>>plt.show()回歸模型的建立本案例中交通車流量預(yù)測模型的任務(wù)是根據(jù)輸入的具體時間段(幾月幾號星期幾第幾個小時),預(yù)測此時間段內(nèi)道路中車流量的情況。不同于9.2節(jié)的分類任務(wù),該模型的輸出是連續(xù)的數(shù)值。在本節(jié)中,將在使用機器學(xué)習(xí)回歸任務(wù)中的嶺回歸算法(RidgeRegression)的基礎(chǔ)上,進一步探究核函數(shù)對預(yù)測結(jié)果的影響,實現(xiàn)交通車流量的預(yù)測。Scikit-learn內(nèi)封裝的常用核函數(shù)核名稱表達式描述linear線性核函數(shù),等同于多項式核函數(shù)階數(shù)取1poly多項式核函數(shù),超參數(shù)
為多項式的階數(shù)rbf徑向基核函數(shù)(高斯核函數(shù)),超參數(shù)
控制徑向作用范圍laplacian拉普拉斯核函數(shù),為徑向基核的變種。計算輸入向量間的曼哈頓距離,超參數(shù)
控制徑向作用范圍回歸模型的建立在本案例中,將比較線性核函數(shù)、三階多項式核函數(shù)、五階多項式核函數(shù)、徑向基核函數(shù)與拉普拉斯核函數(shù)嶺回歸在交通車流量預(yù)測上的表現(xiàn)效果>>>defbuild_train_model():...#保存模型的字典...models={}...forkernelin('linear','poly-3','poly-5','rbf','laplacian'):...#多項式核函數(shù)需根據(jù)名稱中的階數(shù)創(chuàng)建模型...if'poly'inkernel:...clf=KernelRidge(kernel='poly',...gamma=2,...degree=int(kernel[-1]))...#其他核函數(shù)創(chuàng)建模型...else:...clf=KernelRidge(kernel=kernel,...gamma=2)...#使用訓(xùn)練集數(shù)據(jù)訓(xùn)練模型...clf.fit(X_train,y_train)...#將訓(xùn)練完畢的模型添加至字典中...models[kernel]=clf...returnmodels#調(diào)用構(gòu)建并生成模型的函數(shù)>>>models=build_train_model()>>>print(models){'linear':KernelRidge(gamma=2),'poly-3':KernelRidge(gamma=2,kernel='poly'),'poly-5':KernelRidge(degree=5,gamma=2,kernel='poly'),'rbf':KernelRidge(gamma=2,kernel='rbf'),'laplacian':KernelRidge(gamma=2,kernel='laplacian')}回歸模型的預(yù)測分析在Scikit-learn中,在訓(xùn)練好的模型上使用predict()方法可使模型根據(jù)輸入數(shù)據(jù)做出預(yù)測。下列代碼將驗證集的數(shù)據(jù)作為輸入,在每個模型上進行預(yù)測,并將預(yù)測結(jié)果存儲與字典中,并賦值給result變量。>>>defmaek_predict(models,data):...result={}...forname,modelinmodels.items():...result[name]=model.predict(data)...returnresult#調(diào)用定義的函數(shù)預(yù)測模型在驗證集上的車流量(與最大車流量的比值)>>>result=maek_predict(models,X_val)>>>print(result){'linear':array([0.18524845,0.19716828,0.20908811,...,0.4514431,0.46336293,0.47528275]),'poly-3':array([0.08701442,0.1137189,0.1462421,...,0.32175255,0.23544349,0.12949224]),'poly-5':array([0.08485934,0.09647624,0.12591843,...,0.4118781,0.359178,0.30602133]),'rbf':array([0.0819029,0.09476369,0.12099408,...,0.33193726,0.27503546,0.21360745]),'laplacian':array([0.11717616,0.11492388,0.12071438,...,0.05438403,0.03031455,0.01775509])}定量分析>>>defmodels_score(label,predicts):...models_score={}...defcalculate_score(label,predicted):...score={}...score['r2']=metrics.r2_score(label,predicted)...score['mae']=metrics.mean_absolute_error(label,predicted)...score['mse']=metrics.mean_squared_error(label,predicted)...score['max']=metrics.max_error(label,predicted)...returnscore...forname,predictinpredicts.items():...models_score[name]=calculate_score(label,predict)...returnmodels_score#調(diào)用定義的函數(shù)計算模型的指標參數(shù)>>>models_score=models_score(y_val,result)#打印參數(shù)數(shù)據(jù)>>>print(models_score){'linear':{'r2':-19.436096247431077,'mae':0.3346218294413336,'mse':0.6618504152595966,'max':3.57772707239244},'poly-3':{'r2':-56.60262397328022,'mae':0.3885366260368387,'mse':1.8655383168666728,'max':8.888473221178035},'poly-5':{'r2':-40.6707308598833,'mae':0.32196263633066846,'mse':1.3495625676186356,'max':7.959323333043722},'rbf':{'r2':0.38350252495691983,'mae':0.09019113777631395,'mse':0.01996609846242267,'max':0.7053440761732674},'laplacian':{'r2':0.49158932589217763,'mae':0.08529234896469771,'mse':0.01646556229265031,'max':0.5391318333405098}}五種核函數(shù)嶺回歸模型在驗證集上的指標表現(xiàn)>>>colors=['grey','gold','darkviolet','turquoise','salmon']>>>x_label=['線性','三階多項式','五階多項式','徑向基','拉普拉斯']#構(gòu)建畫布>>>fig,ax=plt.subplots(2,2,figsize=(12,12))#構(gòu)建平均絕對誤差MAE>>>bar_mae=ax[0,0].bar(models_score.keys(),[i['mae']foriinmodels_score.values()],color=colors,alpha=0.7)>>>ax[0,0].bar_label(bar_mae,padding=2,fmt="%.3f")>>>ax[0,0].set(title='驗證集平均絕對誤差',...xticklabels=x_label)>>>ax[0,0].grid(axis='y',linestyle='-.',linewidth=0.5)#均方誤差MSE>>>bar_mse=ax[0,1].bar(models_score.keys(),[i['mse']foriinmodels_score.values()],color=colors,alpha=0.7)>>>ax[0,1].bar_label(bar_mse,padding=2,fmt="%.3f")>>>ax[0,1].set(title='驗證集均方誤差',...xticklabels=x_label)>>>ax[0,1].grid(axis='y',linestyle='-.',linewidth=0.5)#最大誤差Max_error>>>bar_max=ax[1,0].bar(models_score.keys(),[i['max']foriinmodels_score.values()],color=colors,alpha=0.7)>>>ax[1,0].bar_label(bar_max,padding=2,fmt="%.3f")>>>ax[1,0].set(title='驗證集最大誤差',...xticklabels=x_label)>>>ax[1,0].grid(axis='y',linestyle='-.',linewidth=0.5)#R2分數(shù)>>>
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 速凍食品抽樣檢驗方案
- 建筑工地安全保障措施方案
- 醫(yī)養(yǎng)結(jié)合機構(gòu)人才培養(yǎng)方案
- 化工仿真實訓(xùn)報告
- 利用數(shù)字化工具提升語文閱讀方案
- 綠色食品儲存方案實踐
- 游戲設(shè)計崗位年度工作總結(jié)
- 幼兒園趣味運動會安全保障預(yù)案
- 醫(yī)院電氣系統(tǒng)SVG設(shè)備施工方案
- 青年志愿者活動糾紛調(diào)解制度
- 控制三高健康生活遠離心腦血管疾病課件(模板)
- 光學(xué)相干斷層成像(OCT)在冠狀動脈介入診斷與治療中的應(yīng)用課件
- 模擬法庭案例腳本:校園欺凌侵權(quán)案 社會法治
- 四年級上冊美術(shù)教案-14漂亮的房間 |蘇少版
- 05 03 第五章第三節(jié) 投身崇德向善的道德實踐
- 安徽省合肥市第四十五中學(xué)2022-2023學(xué)年九年級上學(xué)期數(shù)學(xué)期中考試卷
- 樁基礎(chǔ)工程施工組織方案
- 供水運營管理實施方案(4篇)
- 水土保持工程質(zhì)量評定表
- 水電站基本構(gòu)造原理與類型ppt版(共67)
- 秦朝統(tǒng)一PPT課件教學(xué)
評論
0/150
提交評論