標籤:

scikit learn 里沒有神經網路?


本教程的代碼和數據來自於 Springboard 的博客教程,希望能為你提供幫助。作者為 Jose Portilla,他是網路教育平台 Udemy 一門數據科學類課程的講師。

GitHub 鏈接:https://github.com/Rogerh91/Springboard-Blog-Tutorials/blob/master/Neural%20Networks%20/JMPortilla_SpringBoard_Blog_Neural_Network.ipynb

最受歡迎的 Python 機器學習庫是 SciKit Learn。最新版本(0.18)支持神經網路模型。在本文中,我們將了解神經網路的工作方式以及如何使用 Python 編程語言和最新版本的 SciKit-Learn 來實現它們。了解這篇文章需要 Python 基礎知識,而且它也有助於積累 SciKit Learn 的經驗。
本文的代碼及結果用 Jupyter Notebook 編寫,In [*]: 代表輸入的代碼,Out[*]: 代表程序輸出的結果。

神經網路


人工神經網路是一種模仿生物神經網路學習模式的機器學習框架:可以將它們粗略地近似為人類在學習中的思維活動。生物神經網路具有相互連接的神經元,神經元的樹突結構接收輸入,並基於這些輸入產生輸出信號,通過軸突傳輸到另一個神經元。我們將嘗試通過人工神經網路(ANN,簡稱神經網路)來模擬這個過程。神經網路是深度學習的基礎,它屬於機器學習範疇,是當今最令人興奮的技術進步之一。在利用 Python 創建神經網路之前,讓我們先從最基本形式——單個感知器(perceptron)開始。下面是感知器的介紹。

感知器

一個感知器完整的結構包括一個或多個輸入、偏置、激活函數和一個輸出。感知器接收輸入,並將它們與權重相乘,然後傳遞到激活函數以產生輸出。有許多可能的激活函數可供選擇,如 logistic 函數、三角函數、階躍函數(step function)等。我們需要確保向感知器模型添加偏置(用來調整激活函數的位置),它是不受輸入影響的常數型權重,能使預測模型的擬合效果達到最佳。下面的圖表展示了感知器的結構:


一旦得到輸出,我們可以將其與一個已知的標籤進行比較,並相應地調整權重(開始時通常用隨機數初始化權重值)。重複此過程,直到達到允許的最大迭代次數或可接受的錯誤率。

為了創建一個神經網路,我們可以從疊加多層感知器開始,創建一個神經網路的多層感知器模型。它包含了傳入數據的輸入層和產生結果的輸出層。輸入層和輸出層之間的任何層都被稱為隱藏層,因為它們不能直接「看到」數據的特徵輸入或輸出。下圖直觀地反映了輸入層、隱藏層和輸出層的關係(來源:維基百科)。

由於神經網路的特點,神經網路在 GPU 上的表現往往比 CPU 好。可惜的是,SciKit-learn 框架不支持 GPU 加速優化。如果你想使用 GPU 和分散式模型,請參考其它框架,例如谷歌的開源框架 TensorFlow。

讓我們繼續用 Python 和 SciKit-learn 創建神經網路。

本教程使用了最新版本的 SciKit-Learn(&> 0.18),它可以通過 pip 或 conda 來輕鬆安裝,也可以參考官方安裝文檔(http://scikit-learn.org/stable/install.html)獲取完整的詳細信息。

Anaconda 和 iPython Notebook

Anaconda 的 iPython Notebook(Jupyter Notebook)軟體可以輕鬆地幫助你安裝 SciKit-Learn 以及所需的所有工具。下面的鏈接中有如何安裝這些軟體的教程(https://www.safaribooksonline.com/blog/2013/12/12/start-ipython-notebook/),以便你快速在 Python 中構建神經網路。

數據

本文的分析主題為葡萄酒。葡萄酒偽劣品是一件非常現實的事情,讓我們來看看 Python 的神經網路是否可以幫助解決這個問題。我們將使用 UCI 機器學習庫中的葡萄酒數據集。它具有不同葡萄酒的各種化學特徵,均在義大利同一地區生長,但數據標籤分類為三種不同的品種。我們將嘗試建立一個可以根據其化學特徵對葡萄酒品種進行分類的神經網路模型。

數據集鏈接:https://archive.ics.uci.edu/ml/datasets/Wine

第一步,先導入數據
In [11]:

import pandas as pd

wine = pd.read_csv("wine_data.csv", names = ["Cultivator", "Alchol", "Malic_Acid", "Ash", "Alcalinity_of_Ash", "Magnesium", "Total_phenols", "Falvanoids", "Nonflavanoid_phenols", "Proanthocyanins", "Color_intensity", "Hue", "OD280", "Proline"])


查看數據結構:
In [9]:
wine.head()
Out[9] 為了符合本文的格式,我們截取了部分列(實際數據有更多列):

In [12]:
wine.describe().transpose()
Out[12]為了符合本文的格式,從輸出中去掉了標準偏差(std)和計數列:

In [13]:
# 178 data points with 13 features and 1 label columnwine.shape
Out[13]:
(178, 14)
將數據的標籤設置為 y:

In [14]:

X = wine.drop("Cultivator",axis=1)
y = wine["Cultivator"]
準備訓練集和測試集

下面將數據分成訓練集和測試集,這可以通過使用 SciKit-Learn 的 model_selection 中的 train_test_split 函數輕鬆完成:

In [15]:
from sklearn.model_selection import train_test_split
In [16]:
X_train, X_test, y_train, y_test = train_test_split(X, y)

數據預處理

如果數據沒有經過標準化,則神經網路可能在達到允許的最大迭代次數時仍未收斂。多層感知器對特徵尺度(scale)敏感,因此強烈建議歸一化數據。請注意,測試集採用相同的尺度變換才有意義。有很多不同的數據標準化方法,我們將使用內置的 StandardScaler 進行標準化。

In [17]:
from sklearn.preprocessing import StandardScaler
In [18]:
scaler = StandardScaler()
In [19]:
# Fit only to the training data
scaler.fit(X_train)
Out[19]:
StandardScaler(copy=True, with_mean=True, with_std=True)
In [20]:
# Now apply the transformations to the data:
X_train = scaler.transform(X_train)
X_test = scaler.transform(X_test)
訓練模型

現在我們來訓練模型。SciKit-learn 使用 estimator(估計量)對象。我們將從 SciKit-Learn 的 neural_network 庫導入我們的估計量(多層感知器分類器模型/MLP)。

In [21]:
from sklearn.neural_network import MLPClassifier
接下來我們創建一個模型的實例,可以自定義很多參數,我們將只定義 hidden_layer_sizes 參數。此參數傳入的是一個元組,表示計劃在每個層的神經元數量,其中元組中的第 n 個元素表示 MLP 模型第 n 層中的神經元數量。有很多參數可供選擇,但是為了簡單起見,我們將選擇具有相同數量神經元的 3 層神經網路,每層的神經元數量與數據的特徵數相同(13),並將最大迭代次數設置為 500 次。
In [24]:
mlp = MLPClassifier(hidden_layer_sizes=(13,13,13),max_iter=500)
現在我們已經建立好模型,可以用訓練集來擬合我們的模型,記住這些數據已被預處理和標準化:

In [25]:
mlp.fit(X_train,y_train)
Out[25]:
MLPClassifier(activation="relu", alpha=0.0001, batch_size="auto", beta_1=0.9,
beta_2=0.999, early_stopping=False, epsilon=1e-08,
hidden_layer_sizes=(13, 13, 13), learning_rate="constant",
learning_rate_init=0.001, max_iter=500, momentum=0.9,
nesterovs_momentum=True, power_t=0.5, random_state=None,
shuffle=True, solver="adam", tol=0.0001, validation_fraction=0.1,
verbose=False, warm_start=False)
輸出結果中給出了模型的其它參數的默認值。我鼓勵你嘗試這些參數的不同取值,看看它們對 Python 神經網路有什麼影響。

In [26]:
predictions = mlp.predict(X_test)
現在我們可以用 SciKit-Learn 自帶的評價指標,如分類報告(classification report)和混淆矩陣(confusion matrix)來評估模型的性能:

In [27]:
from sklearn.metrics import classification_report,confusion_matrix
In [28]:
print(confusion_matrix(y_test,predictions))
[[17 0 0]
[ 0 14 1]
[ 0 0 13]]
In [29]:
print(classification_report(y_test,predictions))
precision recall f1-score support

1 1.00 1.00 1.00 17
2 1.00 0.93 0.97 15
3 0.93 1.00 0.96 13

avg / total 0.98 0.98 0.98 45

結果不錯!看來測試集中我們只錯誤分類了 1 瓶葡萄酒!考慮到我們的 Python 神經網路的代碼行很少,這個效果是非常好的。然而,多層感知器模型的缺點在於解釋模型本身。例如,模型的權重和偏差與數據特徵的關係以及哪些特徵最重要將不容易解釋。

如果想查看 MLP 訓練模型得到的權重和偏差,使用 public 屬性 coefs_ 和 intercepts_。

coefs_ 是權重矩陣的列表,其中索引 i 處的權重矩陣表示層 i 和層 i+1 之間的權重。

intercepts_ 是偏差向量的列表,其中索引 i 處的向量表示添加到層 i+1 的偏差值。

In [30]:
len(mlp.coefs_)
Out[30]:
4
In [31]:
len(mlp.coefs_[0])
Out[31]:
13
In [32]:
len(mlp.intercepts_[0])
Out[32]:
13

原文鏈接:A Beginner』s Guide to Neural Networks in Python and SciKit Learn 0.18


用dev版就有,stable 裡面沒有mlp


只有一個RBM,是一個神經網路狀的圖模型,都不知道算不算神經網路,sklearn目前還不提供其他神經網路。如果非要用python的話建議用theano。如果覺得theano麻煩的話可以試一下pylearn2,但是這個包正在建設中,我沒有用過。


scikit-neuralnetwork這個包我一直在做研究時使用,使用下來非常棒,完全兼容scikit-learn,同時基於pylearn2(封裝theano),所以試試吧!


官方文檔鏈接:

API Reference - scikit-learn 0.18.1 documentation

從0.18.1的文檔里看,神經網路只有BernoulliRBM和MLP。

個人覺得,現階段sklearn還是以統計學習方法為主的。

建議題主以後類似的問題可以先參考官方文檔,然後再問具體問題比較合適


現在版本的scikit-learn是0.17,documentation上承諾0.18會出MLP,但是照大半年一更的尿性,0.17是去年十一月份的,新版本估計會在今年暑假出。

1. 可以用sknn代替,完全兼容sklearn,可惜在windows系統不是很兼容,因為還需要安裝mingw和libpython,我自己是因為conda打死裝不上就放棄了。不過可以試一試,如果裝上了請告訴我。附stackoverflow鏈接:python - SKlearn import MLPClassifier fails

2.選用其他的python工具,比如theano,pybrain,FFNN。我現在用的pybrian,參數調用起來略煩。


沒有,可以試試tensorflow


現在已經可以下載scikit-learn 0.18,裡面有MLP,我正在使用


推薦閱讀:

神經網路中,bias有什麼用,為什麼要設置bias,當加權和大於某值時,激活才有意義?
深度學習在自然語言處理中到底發揮了多大作用?有哪些不足或局限?
什麼是 end-to-end 神經網路?
2017年神經機器翻譯(NMT)的一些重要資源匯總?
只有達到 state of the art精度的方法才能發文章嗎?

TAG:神經網路 |