本文的文字及圖片來源於網絡,僅供學習、交流使用,不具有任何商業用途,版權歸原作者所有,如有問題請及時聯系我們以作處理。
作者: Python高校
PS:如有需要Python學習資料的小伙伴可以加點擊下方鏈接自行獲取
http://note.youdao.com/noteshare?id=3054cce4add8a909e784ad934f956cef
項目描述
利用馬薩諸塞州波士頓郊區的房屋信息數據訓練和測試一個模型,並對模型的性能和預測能力進行測試;
項目分析
數據集字段解釋:
-
RM: 住宅平均房間數量;
-
LSTAT: 區域中被認為是低收入階層的比率;
-
PTRATIO: 鎮上學生與教師數量比例;
-
MEDV: 房屋的中值價格(目標特征,即我們要預測的值);
其實現在回過頭來看,前三個特征應該都是挖掘后的組合特征,比如RM,通常在原始數據中會分為多個特征:一樓房間、二樓房間、廚房、卧室個數、地下室房間等等,這里應該是為了教學簡單化了;
MEDV為我們要預測的值,屬於回歸問題,另外數據集不大(不到500個數據點),小數據集上的回歸問題,現在的我初步考慮會用SVM,稍后讓我們看看當時的選擇;
Step 1 導入數據
注意點:
1、如果數據在多個csv中(比如很多銷售項目中,銷售數據和店鋪數據是分開兩個csv的,類似數據庫的兩張表),這里一般要連接起來; 2、訓練數據和測試數據連接起來,這是為了后續的數據處理的一致,否則訓練模型時會有問題(比如用訓練數據訓練的模型,預測測試數據時報錯維度不一致); 3、觀察下數據量,數據量對於后續選擇算法、可視化方法等有比較大的影響,所以一般會看一下; 4、pandas內存優化,這一點項目中目前沒有,但是我最近的項目有用到,簡單說一下,通過對特征字段的數據類型向下轉換(比如int64轉為int8)降低對內存的使用,這里很重要,數據量大時很容易撐爆個人電腦的內存存儲;
上代碼:
1 # 載入波士頓房屋的數據集 2 data = pd.read_csv('housing.csv') 3 prices = data['MEDV'] 4 features = data.drop('MEDV', axis = 1) 5 # 完成 6 7 print"Boston housing dataset has {} data points with {} variables each.".format(*data.shape)
tep 2 分析數據
加載數據后,不要直接就急匆匆的上各種處理手段,加各種模型,先慢一點,對數據進行一個初步的了解,了解其各個特征的統計值、分布情況、與目標特征的關系,最好進行可視化,這樣會看到很多意料之外的東西;
基礎統計運算
統計運算用於了解某個特征的整體取值情況,它的最大最小值,平均值中位數,百分位數等等,這些都是最簡單的對一個字段進行了解的手段;
上代碼:
特征觀察
這里主要考慮各個特征與目標之間的關系,比如是正相關還是負相關,通常都是通過對業務的了解而來的,這里就延伸出一個點,機器學習項目通常來說,對業務越了解,越容易得到好的效果,因為所謂的特征工程其實就是理解業務、深挖業務的過程;
比如這個問題中的三個特征:
-
RM:房間個數明顯應該是與房價正相關的;
-
LSTAT:低收入比例一定程度上表示着這個社區的級別,因此應該是負相關;
-
PTRATIO:學生/教師比例越高,說明教育資源越緊缺,也應該是負相關;
上述這三個點,同樣可以通過可視化的方式來驗證,事實上也應該去驗證而不是只靠主觀猜想,有些情況下,主觀感覺與客觀事實是完全相反的,這里要注意;
Step 3 數據划分
為了驗證模型的好壞,通常的做法是進行cv,即交叉驗證,基本思路是將數據平均划分N塊,取其中N-1塊訓練,並對另外1塊做預測,並比對預測結果與實際結果,這個過程反復N次直到每一塊都作為驗證數據使用過;
上代碼:
1 # 提示:導入train_test_split 2 from sklearn.model_selection import train_test_split 3 X_train, X_test, y_train, y_test = train_test_split(features, prices, test_size=0.2, random_state=RANDOM_STATE) 4 print X_train.shape 5 print X_test.shape 6 print y_train.shape 7 print y_test.shape
Step 4 定義評價函數
這里主要是根據問題來定義,比如分類問題用的最多的是准確率(精確率、召回率也有使用,具體看業務場景中更重視什么),回歸問題用RMSE(均方誤差)等等,實際項目中根據業務特點經常會有需要去自定義評價函數的時候,這里就比較靈活;
Step 5 模型調優
通過GridSearch對模型參數進行網格組合搜索最優,注意這里要考慮數據量以及組合后的可能個數,避免運行時間過長哈。
上代碼:
1 from sklearn.model_selection importKFold,GridSearchCV 2 from sklearn.tree importDecisionTreeRegressor 3 from sklearn.metrics import make_scorer 4 5 def fit_model(X, y): 6 """ 基於輸入數據 [X,y],利於網格搜索找到最優的決策樹模型""" 7 cross_validator = KFold() 8 regressor = DecisionTreeRegressor() 9 params = {'max_depth':[1,2,3,4,5,6,7,8,9,10]} 10 scoring_fnc = make_scorer(performance_metric) 11 12 grid = GridSearchCV(estimator=regressor, param_grid=params, scoring=scoring_fnc,cv=cross_validator) 13 14 # 基於輸入數據 [X,y],進行網格搜索 15 grid = grid.fit(X, y) 16 # 返回網格搜索后的最優模型 17 return grid.best_estimator_
可以看到當時項目中選擇的是決策樹模型,現在看,樹模型在這種小數據集上其實是比較容易過擬合的,因此可以考慮用SVM代替,你也可以試試哈,我估計是SVM效果最好;
學習曲線
通過繪制分析學習曲線,可以對模型當前狀態有一個基本了解,如下圖:
可以看到,超參數max_depth為1和3時,明顯訓練分數過低,這說明此時模型有欠擬合的情況,而當max_depth為6和10時,明顯訓練分數和驗證分析差距過大,說明出現了過擬合,因此我們初步可以猜測,最佳參數在3和6之間,即4,5中的一個,其他參數一樣可以通過學習曲線來進行可視化分析,判斷是欠擬合還是過擬合,再分別進行針對處理;