Tensorflow入門——Keras處理分類問題
Tensorflow 和 Keras 除了能處理 前一篇 文章提到的迴歸(Regression,擬合&預測)的問題之外,還可以處理分類(Classfication)的問題。
這篇文章我們就介紹一下如何用Keras快速搭建一個線性分類器或神經網路,通過分析病人的生理資料來判斷這個人是否患有糖尿病。
同樣的,為了方便與讀者交流,所有的原始碼都放在了這裡:
https://github.com/zht007/tensorflow-practice/tree/master/2_Classification
1. 資料的匯入
資料的csv檔案已經放在了專案目錄中,也可以去 Kaggle 下載。

image
2.資料預處理
2.1 Normalization(標準化)資料
標準化資料可以用sklearn的工具,但我這裡就直接計算了。要注意的是,這裡沒有標準化年齡。
cols_to_norm = ['Number_pregnant', 'Glucose_concentration', 'Blood_pressure', 'Triceps', 'Insulin', 'BMI', 'Pedigree'] diabetes[cols_to_norm] = diabetes[cols_to_norm].apply(lambda x: (x - x.min()) / (x.max() - x.min()))
2.2 年齡分段
對於向年齡這樣的資料,通常需要按年齡段進行分類,我們先看看資料中的年齡構成。

image
可以通過panda自帶的cut函式對年齡進行分段,我們這裡將年齡分成0-30,30-50,50-70,70-100四段,分別標記為0,1,2,3
bins = [0,30,50,70,100] labels =[0,1,2,3] diabetes["Age_buckets"] = pd.cut(diabetes["Age"],bins=bins, labels=labels, include_lowest=True)
3.4 訓練和測試分組
這一步不用多說,還是用sklearn.model_selection 的 train_test_split工具進行處理。
from sklearn.model_selection import train_test_split X_train, X_test, y_train, y_test = train_test_split(x_data,labels,test_size=0.33, random_state=101)
3. 用Keras搭建線性分類器
與 前一篇 文章中介紹的線性迴歸模型一樣,但線性分類器輸出的Unit 為 2 需要加一個"sorftmax"的啟用函式。
from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense,Activation from tensorflow.keras.optimizers import SGD,Adam from tensorflow.keras.utils import to_categorical model = Sequential() model.add(Dense(2,input_shape = (X_train.shape[1],),activation = 'softmax'))
需要注意的是標籤y需要進行轉換,實際上是將一元資料轉換成二元資料(Binary)的"One Hot"資料。比如原始標籤用"[1]"和"[0]"這樣的一元標籤來標記"是"“否”患病,轉換之後是否患病用"[1 , 0]"和"[0 , 1]"這樣的二元標籤來標記。
y_binary_train= to_categorical(y_train) y_binary_test = to_categorical(y_test)
同樣可以選用SGD的優化器,但是要注意的是,在Compile的時候損失函式要選擇"categorical_crossentropy"
sgd = SGD(0.005) model.compile(loss = 'categorical_crossentropy', optimizer = sgd, metrics=['accuracy'])
4. 分類器的訓練
訓練的時候可以直接將測試資料帶入,以方便評估訓練效果。
H = model.fit(X_train, y_binary_train, validation_data=(X_test, y_binary_test),epochs = 500)
5. 訓練效果驗證
訓練效果可以直接呼叫history檢視損失函式和準確率的變化軌跡,線性分類器的效果還不錯。

image
6. 改用神經網路試試
這裡我在model中搭建一個20x10的兩層全連線的神經網路,優化器選用adam
model = Sequential() model.add(Dense(20,input_shape = (X_train.shape[1],), activation = 'relu')) model.add(Dense(10,activation = 'relu')) model.add(Dense(2, activation = 'softmax')) adam = Adam(0.01)
可以看到,雖然精確度比採用線性分類器稍高,但是在200個epoch之後,明顯出現過擬合(Over fitting)的現象。

image
7. 用模型進行預測
同樣的我們可以用訓練得到的模型對驗證資料進行預測,這裡需要注意的是我們最後需要將二元資料用np.argmax轉換成一元資料。
import numpy as np y_pred_softmax = model.predict(X_test) y_pred = np.argmax(y_pred_softmax, axis=1)