python中通過RF預測紅酒質量初探

從UCI上獲取到了一份winequality的數據來作為小練習的數據源,大家可以去Index of /ml/machine-learning-databases/wine-quality 下載選擇red紅酒的csv數據下載即可。

一、首先先進行數據的導入,探索與預處理:

import numpy as npnimport pandas as pdndf=pd.read_csv(C:UsersAdministratorDownloadswinequality-red.csv,encoding=utf-8) #後續再括弧中需要添加sep=;ndf.sample()n

觀察到表有問題,實際上這個csv文件通過分號分割,所以導入時需要添加:sep=;,即可正常讀取數據。繼續初步觀察下來,得知數據集中,不存在空值。

df.isnull().any()n

關於以上這些列的含義有一個中英對照表:

二、處理數據是否分布平衡

數據是否平衡是在機器學習建模過程前需要考慮的一個問題,其主要本質是分類,在這個數據集中是quality,可能部分在訓練數據中,絕大多數都是quality是3,而只有極少部分是4,則這時候訓練出來的模型只需要都歸為3,也可以獲得很好的準確度,但這個時候實際上這個模型就沒有意義了。針對這種數據可以有多種處理方法,可以重新整體採樣,也可以對小類別的數據進行過採樣(即多加一個同類的副本)或者對大類別中刪去一定數量的樣本,使得最後總體各個類別的數據幾乎差不多。對於這個數據集先觀察一下目前各個quality(我們想要預測的這個變數)的分布情況。

print(df[quality].value_counts())n輸出為:n5 681n6 638n7 199n4 53n8 18n3 10nName: quality, dtype: int64n

顯然quality為5的數據樣本有太多,而quality為3的數據樣本又太少,這時候可以考慮過採樣,python現在有個新包叫imbalanced-learn可以進行處理,這個Anaconda不自帶,需要自行pip install一下。

from imblearn.over_sampling import RandomOverSamplernX = df.iloc[:,:-1].values #iloc方法根據位置選擇,即選擇所有行,所有列去掉右數第一列ny = df[quality].valuesnros = RandomOverSampler() #構造過採樣方法nX,y = ros.fit_sample(X, y)nprint(pd.DataFrame(y)[0].value_counts().sort_index()) #得到的x,y是數組,通過DataFrame轉化為DataFrame格式n

3 681

4 681

5 681

6 681

7 681

8 681

Name: 0, dtype: int64

可以看到都根據樣本數最多的那個quality=5進行了過採樣,樣本數量不夠分類的會進行複製使其數量達到681,這種操作可能會造成後續的數據會有偏向性以及所謂過擬合,這個後續還可以通過交叉檢驗進行驗證。

先用LR回歸嘗試一下,這裡也權當複習,先可以嘗試把所有特徵都用上,利用交叉檢驗,看看預測結果如何

import sklearnnimport numpy as npnfrom sklearn import linear_modelnlm=linear_model.LogisticRegression()nfeatures=[fixed acidity,volatile acidity,citric acid,residual sugar,chlorides,free sulfur dioxide,total sulfur dioxide,density,pH,sulphates,alcohol]nX=df[features]ny=df[quality]nfrom sklearn.model_selection import cross_val_scoren#logistic中的scoring參數指定為accuracynscores=cross_val_score(lm,X,y,cv=5,scoring=accuracy)nprint(np.mean(scores))n

輸出結果為0.57可以看到如果直接在原始不平衡數據上把所有特徵都用上,使用LR回歸幾乎對預測這個多分類的quality沒有什麼幫助,後來再過採樣後的數據上也用了LR回歸同樣準確率很不理想。那查閱資料知道Logistics回歸一般做的是二分類即預測變數只有兩個結果,對於多分類的y一般預測並不準確,但同時也要認知到Logistics回歸在金融預測,諸如是否發信用卡等方面仍然還是十分常用的,準確度高,訓練速度快。

由於也是邊學邊做,起先的時候以為可能是由於特徵的多重共線性導致的,所以有差看一下所有使用的特徵的相關性,這個可以利用seaborn快速可視化的實現這一效果,代碼如下:

import matplotlib.pyplot as plt nimport seaborn as snsndata = df.corr() nsns.heatmap(data) nplt.show() n

顯示如下:可以看到多數變數之間實際上相關係數都在0.4以下,不存在高度相關

通過查閱更多的資料得知,Logistics回歸的一些優缺點:

Logistic回歸分析的優點:

1.適合需要得到一個分類概率的場景

2.實現效率較高

3.對邏輯回歸而言,多重共線性並不是問題,它可以結合L2正則化來解決;

4.邏輯回歸廣泛的應用於工業問題上

邏輯回歸的缺點:

1.當特徵空間很大時,邏輯回歸的性能不是很好;

2.不能很好地處理大量多類特徵或變數;

4.對於非線性特徵,需要進行轉換;

5.依賴於全部的數據特徵,當特徵有缺失的時候表現效果不好

對於這個紅酒問題而言,預測變數的類別顯得有些太多了,估計是模型效果不佳的一個主要原因。接下來引入隨機森林,要理解隨機森林先要理解決策樹,決策樹的原理如下:實際上就是對樣本通過特徵條件判斷不斷細分,形成像樹狀一樣的結構,最後使得最後的子樹中類別越純,則說明分類的效果越好。

隨機森林就是通過集成學習的思想將多棵樹集成的一種演算法,它的基本單元是決策樹,而它的本質屬於機器學習的一大分支——集成學習(Ensemble Learning)方法。因為決策樹本質上可以有很多的決策條件所以可以形成很多不同的決策樹,對樣本的分類也會不盡相同,隨機森林可以集成許多決策樹分類的結果取多數的一個結果作為隨機森林模型得到的結果,這樣的方法會使最終的結果的準確率高於單個的決策樹的準確率。實際使用的話仍然可以通過sklearn中簡單調取相關方法即可。

from sklearn import ensemblen#設定隨機森林分類模型nrf=ensemble.RandomForestClassifier(100) #設定包含100個決策樹nfrom sklearn.model_selection import cross_val_scorenscore=cross_val_score(rf,X,y,cv=5,scoring=accuracy)nprint(np.mean(score))n

得到結果是86%,大大超過了Logistics回歸的準確率。這種交叉檢驗的方法是訓練集是所有樣本都使用了,在檢驗測試的時候分為5個部分,四個部分進行訓練,一個部分作為測試集,會得到5次測試結果後取平均準確度得到86%,還有通常的做法會一開始就將所有樣本先拆分為訓練集和測試集,通過訓練集的模型直接放到測試集上去測試效果,得到準確率,我們也來看一下這種方法預測後的結果如何。

將數據切分成80%的數據作為訓練集,20%的數據作為測試集。

from sklearn.ensemble import RandomForestClassifiernfrom sklearn.model_selection import train_test_splitnX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.2,random_state=0)n

關於train_test_split的用法參考如下:

  • 一般形式

train_test_split是交叉驗證中常用的函數,功能是從樣本中隨機的按比例選取train data和testdata,形式為:

X_train,X_test, y_train, y_test =

cross_validation.train_test_split(train_data,train_target,test_size=0.4, random_state=0)

  • 參數解釋

train_data:所要劃分的樣本特徵集

train_target:所要劃分的樣本結果

test_size:樣本佔比,如果是整數的話就是樣本的數量

random_state:是隨機數的種子。

隨機數種子:其實就是該組隨機數的編號,在需要重複試驗的時候,保證得到一組一樣的隨機數。比如你每次都填1,其他參數一樣的情況下你得到的隨機數組是一樣的。但填0或不填,每次都會不一樣。

隨機數的產生取決於種子,隨機數和種子之間的關係遵從以下兩個規則:

種子不同,產生不同的隨機數;種子相同,即使實例不同也產生相同的隨機數。

那麼首先,使用predict()函數得到上一節訓練的隨機森林模型在測試集合上的預測結果,然後使用 sklearn.metrics中的相關函數對模型的性能進行評估。

from sklearn import metricsny_predict = rf.predict(X_test)nprint(metrics.classification_report(y_test, y_predict))nprint(metrics.confusion_matrix(y_test,y_predict))nprint("Accuracy:", metrics.accuracy_score(y_test, y_predict))n

得到的結果如下:

precision recall f1-score support

3 0.99 1.00 0.99 142

4 1.00 1.00 1.00 129

5 0.80 0.81 0.80 150

6 0.77 0.66 0.71 146

7 0.87 0.98 0.92 125

8 0.99 1.00 1.00 126

avg / total 0.90 0.90 0.90 818

[[142 0 0 0 0 0]

[ 0 129 0 0 0 0]

[ 2 0 121 26 1 0]

[ 0 0 31 96 18 1]

[ 0 0 0 2 123 0]

[ 0 0 0 0 0 126]]

上述混淆矩陣中對角線的元素表示模型正確預測數,對角元素之和表示模型整體預測正確的樣本數。

Accuracy: 0.90097799511

準確度在90%左右,由於前面在抽取訓練集和測試集時random_state設置為0,我們可以測試多次,會選取到不同的訓練集和測試集,測算多個準確度求平均值進行比較,經過測試仍然維持在90%左右。

推薦閱讀:

9、續7--文章的編寫頁面(略)
GitHub 上有什麼值得學習,簡單的,易讀的 Python 項目?
百年百圖の中國(1900-1999):另類python爬蟲和PIL拼圖

TAG:Python | 数据挖掘 |