嗨客案例 | 使用隨機森林進行紅酒品質分類
導讀
2017年9月,數據嗨客推出了全新的案例模塊。數據嗨客的案例不僅僅是一份報告,同時集成了數據、代碼和分析環境。用戶可以方便地在線進行大數據案例的創作、運行和分享。本期公眾號文章我們摘選數據嗨客平台的優質案例「使用隨機森林進行紅酒品質分類」,向讀者演示如何利用Python中的Sklearn工具,建立分類模型預測紅酒的品質。對大數據感興趣的小夥伴可以掃描文末的二維碼進入數據嗨客技術交流群。
隨著人們生活水平不斷的提高,紅酒越來越受到人們的喜愛。紅酒的產量越來越大,然而紅酒品質鑒定的手段還是僅靠品酒師的人工品嘗打分來判定紅酒質量的好壞,顯然這種鑒定方式難以滿足當今市場的需求。現在有不少學者運用一些機器學習的演算法來對紅酒質量進行預測研究,使得紅酒品質鑒定的速度得到大幅提升並且有著較高的準確率。
對於紅酒品質的分類,可以基於紅酒的理化指標(例如:酒精的濃度、pH值、糖的含量、非揮發性酸含量、 揮發性酸含量、檸檬酸含量等)作為特徵,建立分類模型,然後對紅酒品質進行預測。本案例中,我們將使用UCI資料庫中的 Wine Quality Data Set 數據集,利用隨機森林分類演算法來進行紅酒品質的分類。
1 數據源
我們使用一份包含1599個樣本的關於葡萄牙的Vinho Verde葡萄酒數據集。 每個樣本包含12個變數,其中最後一個變數quality為預測變數。 變數列表如下:
2 數據探索和預處理
首先,使用pandas中的 read_csv 函數將數據載入到數據框中:
import numpy as npimport pandas as pddf = pd.read_csv("./input/winequality-red.csv",sep=;)df.head(5)
通過初步觀察,發現所有的變數中不存在缺失值(missing value)。 我們可以使用驗證數據中確實沒有缺失值。
df_value_ravel = df.values.ravel()print u缺失值數量:,len(df_value_ravel[df_value_ravel==np.nan])缺失值數量: 0
2.1 處理不平衡數據
由於這是一個分類問題,我們需要查看數據集中的數據是否平衡。又以下代碼可以得到每個類別有多少個樣本:
print(數據中的各類別樣本分布:)print(df[quality].value_counts().sort_index())數據中的各類別樣本分布:3 104 535 6816 6387 1998 18
我們可以看出,數據中的屬於不同類別的樣本的分布是不平衡的。 這裡我們選擇過採樣的方法來使數據變得平衡。 在Python中imbalanced-learn包可以用來對不平衡數據進行處理。
from imblearn.over_sampling import RandomOverSamplerX = df.iloc[:,:-1].valuesy = df[quality].valuesros = RandomOverSampler()X, y = ros.fit_sample(X, y)
過採樣後的類別分布為:
print(pd.DataFrame(y)[0].value_counts().sort_index())3 6814 6815 6816 6817 6818 681
可見,不同類別的樣本數量變得平衡。
3 模型訓練
為了實現紅酒品質分類,我們使用 sklearn.ensemble 包中的 RandomForestClassifier 類。 RandomForestClassifier 的 n_estimators 參數為隨機森林中單棵決策樹的數目。 在本案例中,我們將決策樹的棵數 n_estimators 設置為100。
將數據切分成80%的數據作為訓練集,20%的數據作為測試集。
from sklearn.ensemble import RandomForestClassifierfrom sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.2,random_state=0)
然後,利用訓練集訓練隨機森林模型。
clf = RandomForestClassifier(n_estimators=100)clf.fit(X_train,y_train)
4 模型性能評估
首先,使用predict()函數得到上一節訓練的隨機森林模型在測試集合上的預測結果,然後使用 sklearn.metrics中的相關函數對模型的性能進行評估。
from sklearn import metricsy_predict = clf.predict(X_test)print(metrics.classification_report(y_test, y_predict))print(metrics.confusion_matrix(y_test,y_predict)) precision recall f1-score support 3 0.98 1.00 0.99 126 4 1.00 1.00 1.00 127 5 0.77 0.80 0.79 150 6 0.77 0.65 0.70 145 7 0.89 0.99 0.94 132 8 0.99 1.00 1.00 138avg / total 0.90 0.90 0.90 818[[126 0 0 0 0 0] [ 0 127 0 0 0 0] [ 2 0 120 27 1 0] [ 0 0 35 94 15 1] [ 0 0 0 1 131 0] [ 0 0 0 0 0 138]]
上述混淆矩陣中對角線的元素表示模型正確預測數,對角元素之和表示模型整體預測正確的樣本數。 現在,讓我們來通過這個來計算模型在測試集中的預測正確率。
print("Accuracy:", metrics.accuracy_score(y_test, y_predict))(Accuracy:, 0.89975550122249393)
可見,訓練得到的模型在原始集的20%的測試樣本中,預測的正確率(Accuaray)為89.9%左右。
5 隨機森林的分類間隔(Margins)
隨機森林的分類間隔是指森林中正確分類樣本的決策樹的比例減去錯誤分類樣本決策樹的比例。通過平均隨機森林在各個樣本上的分類間隔得到隨機森林的分類間隔。實際中,我們希望分類間隔越大越好,因為大的分類間隔表示我們的分類效果比較穩定,泛化效果更好。代碼如下:
average_margin = 0total_num = len(X_test)for x,y in zip(X_test,y_test): correct_num = 0 wrong_num = 0 for tree in clf.estimators_: if tree.predict(x.reshape(1,11))+3 == y: correct_num += 1 else: wrong_num += 1 average_margin += (correct_num - wrong_num)+0.0 / (correct_num + wrong_num)print 平均分類間隔Margin:,average_margin/total_num平均分類間隔Margin: 67.1222493888
6 隨機森林的袋外錯誤率(Out-Of-Bag Error)
對隨機森林的每一棵樹來說,都有部分樣本沒有被抽樣到進入訓練的樣本,它們叫做袋外樣本。隨機森林對袋外樣本的預測錯誤比率被稱為袋外錯誤率。代碼如下:
import matplotlib.pyplot as pltplt.style.use(ggplot)RANDOM_STATE = 123clf2 = RandomForestClassifier(warm_start=True, max_features=None,oob_score=True,andom_state=RANDOM_STATE)# 隨機森林中樹的數量範圍min_estimators = 15max_estimators = 175pair_list = []for i in range(min_estimators, max_estimators + 1): clf2.set_params(n_estimators=i) clf2.fit(X_train, y_train) oob_error = 1 - clf2.oob_score_ pair_list.append((i, oob_error))#生成袋外錯誤率和樹的數量的關係圖 xs, ys = zip(*pair_list)plt.plot(xs, ys)plt.xlim(min_estimators, max_estimators)plt.xlabel("n_estimators")plt.ylabel("OOB error rate")plt.legend(loc="upper right")plt.show()
7 模型的可解釋性
隨機森林的可解釋性通過變數的重要性來進行刻畫。某些變數對於模型訓練的重要性比較高,有些變數則顯得沒那麼重要。變數的重要程度在隨機森林的生成過程中已經獲得。在訓練好的模型的feature_importances屬性之中。通過matplotlib.pyplot包用以下代碼作圖:
importances = clf.feature_importances_#計算隨機森林中所有的樹的每個變數的重要性的標準差std = np.std([tree.feature_importances_ for tree in clf.estimators_],axis=0)#按照變數的重要性排序後的索引indices = np.argsort(importances)[::-1]# 繪圖過程plt.figure()plt.figure(figsize=(10,5))plt.title("Feature importances")plt.bar(range(X.shape[1]), importances[indices],color="r", yerr=std[indices], align="center")plt.xticks(fontsize=14) plt.xticks(range(X.shape[1]), df.columns.values[:-1][indices],rotation=40)plt.xlim([-1, X.shape[1]])plt.tight_layout()plt.show()
可以看出,最重要的屬性前3名依次為:alcohol (酒精濃度),volatile acidity (揮發性酸含量),以及sulphates (硫酸鹽)。
免費註冊賬號,登錄數據嗨客,在線運行本案例:
掃描下方二維碼,加入數據嗨客技術交流群
https://weixin.qq.com/g/ARMVyxml1NUDkF-8 (二維碼自動識別)
推薦閱讀:
※數值預測,映射,矩陣乘法
※求助一個問題!!!大佬們,幫幫我!!!Coursera Machine Learning疑惑與解答-第3篇-Week5 Assignments
※微分享回放 | 機器學習在攜程酒店服務領域的實踐
※【ML專欄】不同應用場景下ML煉丹工的不同生活
※大數據與機器學習(1)
TAG:機器學習 |