Keras入门示范

Xiao Song

https://xsong.ltd/

As a beginner, it’s necessary to write some simple guides using simple data.

import warnings
warnings.filterwarnings('ignore')
import numpy as np 
import pandas as pd

X_train = pd.read_csv('E:/some_code/py_basic/house_price/data/train1.csv') # prepare data
X_test = pd.read_csv('E:/some_code/py_basic/house_price/data/test1.csv')

Y_train = np.array(X_train['SalePrice'])
Y_train = np.log1p(Y_train)

X_train.drop(['SalePrice'],axis = 1, inplace = True)
Y_train
#> array([12.24769912, 12.10901644, 12.31717117, ..., 12.25486757,
#>        12.49313327, 11.86446927])
X_train.shape
#> (1436, 109)
X_test.shape
#> (1459, 109)

Feature Standardization

Standardize features by removing the mean and scaling to unit variance: \[z = {{x - u} \over s}\]

\(z\) is standardize feature of \(x\), u is the mean of \(x\), and \(s\) is the standard deviation of \(x\).

#from sklearn.preprocessing import RobustScaler
from sklearn.preprocessing import StandardScaler

def standardize(df):
    '''standardize features'''
    transformer = StandardScaler().fit(df) 
    newX = transformer.transform(df)
    X = pd.DataFrame(newX,columns = df.columns)
    return X

X_train = standardize(X_train) # X train
X_test = standardize(X_test) 
X_train
#>       MSSubClass  MSZoningRM  ...  SaleTypeWD  SaleConditionOth
#> 0       0.074674   -0.517138  ...    0.389312         -0.465778
#> 1      -0.874282   -0.517138  ...    0.389312         -0.465778
#> 2       0.074674   -0.517138  ...    0.389312         -0.465778
#> 3       0.311913   -0.517138  ...    0.389312          2.146946
#> 4       0.074674   -0.517138  ...    0.389312         -0.465778
#> ...          ...         ...  ...         ...               ...
#> 1431   -0.874282    1.933720  ...    0.389312         -0.465778
#> 1432    0.074674   -0.517138  ...    0.389312         -0.465778
#> 1433   -0.874282   -0.517138  ...    0.389312         -0.465778
#> 1434    0.311913   -0.517138  ...    0.389312         -0.465778
#> 1435   -0.874282   -0.517138  ...    0.389312         -0.465778
#> 
#> [1436 rows x 109 columns]
X_train.describe()
#>          MSSubClass    MSZoningRM  ...    SaleTypeWD  SaleConditionOth
#> count  1.436000e+03  1.436000e+03  ...  1.436000e+03      1.436000e+03
#> mean  -5.721205e-17  3.101821e-16  ... -3.223203e-16     -1.622039e-16
#> std    1.000348e+00  1.000348e+00  ...  1.000348e+00      1.000348e+00
#> min   -8.742817e-01 -5.171379e-01  ... -2.568635e+00     -4.657780e-01
#> 25%   -8.742817e-01 -5.171379e-01  ...  3.893119e-01     -4.657780e-01
#> 50%   -1.625649e-01 -5.171379e-01  ...  3.893119e-01     -4.657780e-01
#> 75%    3.119131e-01 -5.171379e-01  ...  3.893119e-01     -4.657780e-01
#> max    3.158781e+00  1.933720e+00  ...  3.893119e-01      2.146946e+00
#> 
#> [8 rows x 109 columns]
X_train.shape[1]
#> 109

Neural Network Building

from keras import models
#> Using TensorFlow backend.
from keras import layers

model = models.Sequential()
model.add(layers.Dense(64, activation='relu',input_shape=(X_train.shape[1],)))
model.add(layers.Dense(64, activation='relu'))
model.add(layers.Dense(1))

model.compile(optimizer='rmsprop', loss='mse', metrics=['mae'])
model.summary()
#> Model: "sequential_1"
#> _________________________________________________________________
#> Layer (type)                 Output Shape              Param #   
#> =================================================================
#> dense_1 (Dense)              (None, 64)                7040      
#> _________________________________________________________________
#> dense_2 (Dense)              (None, 64)                4160      
#> _________________________________________________________________
#> dense_3 (Dense)              (None, 1)                 65        
#> =================================================================
#> Total params: 11,265
#> Trainable params: 11,265
#> Non-trainable params: 0
#> _________________________________________________________________
#?models.Sequential.fit
model.fit(X_train,Y_train,
    epochs = 20, # Number of epochs to train the model
    batch_size = 512) # Number of samples per gradient update.
#> Epoch 1/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 155.3925 - mae: 12.4410
#> 1436/1436 [==============================] - 0s 130us/step - loss: 141.8419 - mae: 11.8801
#> Epoch 2/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 120.9269 - mae: 10.9759
#> 1436/1436 [==============================] - 0s 8us/step - loss: 114.5524 - mae: 10.6760
#> Epoch 3/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 101.0041 - mae: 10.0214
#> 1436/1436 [==============================] - 0s 12us/step - loss: 95.1813 - mae: 9.7202
#> Epoch 4/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 82.7641 - mae: 9.0533
#> 1436/1436 [==============================] - 0s 21us/step - loss: 78.1950 - mae: 8.7888
#> Epoch 5/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 66.5168 - mae: 8.0900
#> 1436/1436 [==============================] - 0s 42us/step - loss: 62.8788 - mae: 7.8424
#> Epoch 6/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 53.1013 - mae: 7.1717
#> 1436/1436 [==============================] - 0s 19us/step - loss: 49.3402 - mae: 6.8834
#> Epoch 7/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 40.5059 - mae: 6.1747
#> 1024/1436 [====================>.........] - ETA: 0s - loss: 39.2861 - mae: 6.0604
#> 1436/1436 [==============================] - 0s 96us/step - loss: 37.7007 - mae: 5.9199
#> Epoch 8/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 30.1289 - mae: 5.2018
#> 1436/1436 [==============================] - 0s 33us/step - loss: 28.0882 - mae: 4.9802
#> Epoch 9/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 22.6676 - mae: 4.3443
#> 1436/1436 [==============================] - 0s 6us/step - loss: 20.5223 - mae: 4.1081
#> Epoch 10/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 16.2448 - mae: 3.5311
#> 1436/1436 [==============================] - 0s 5us/step - loss: 14.8127 - mae: 3.3574
#> Epoch 11/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 11.3709 - mae: 2.8576
#> 1436/1436 [==============================] - 0s 6us/step - loss: 10.7030 - mae: 2.7638
#> Epoch 12/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 8.4014 - mae: 2.4070
#> 1436/1436 [==============================] - 0s 6us/step - loss: 7.8423 - mae: 2.3118
#> Epoch 13/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 6.2350 - mae: 2.0244
#> 1436/1436 [==============================] - 0s 5us/step - loss: 5.9073 - mae: 1.9799
#> Epoch 14/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 4.6460 - mae: 1.7458
#> 1436/1436 [==============================] - 0s 6us/step - loss: 4.5811 - mae: 1.7272
#> Epoch 15/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 3.7946 - mae: 1.5703
#> 1436/1436 [==============================] - 0s 6us/step - loss: 3.6796 - mae: 1.5343
#> Epoch 16/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 3.3029 - mae: 1.4636
#> 1436/1436 [==============================] - 0s 5us/step - loss: 3.0489 - mae: 1.3934
#> Epoch 17/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 2.5761 - mae: 1.2628
#> 1436/1436 [==============================] - 0s 5us/step - loss: 2.5894 - mae: 1.2791
#> Epoch 18/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 2.3425 - mae: 1.2194
#> 1436/1436 [==============================] - 0s 5us/step - loss: 2.2409 - mae: 1.1893
#> Epoch 19/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 2.1216 - mae: 1.1526
#> 1436/1436 [==============================] - 0s 5us/step - loss: 1.9715 - mae: 1.1085
#> Epoch 20/20
#> 
#>  512/1436 [=========>....................] - ETA: 0s - loss: 1.7365 - mae: 1.0519
#> 1436/1436 [==============================] - 0s 5us/step - loss: 1.7552 - mae: 1.0434
#> <keras.callbacks.callbacks.History object at 0x0000000055D48860>
#> 
#> WARNING:tensorflow:From C:\ProgramData\Anaconda3\lib\site-packages\keras\backend\tensorflow_backend.py:422: The name tf.global_variables is deprecated. Please use tf.compat.v1.global_variables instead.

Validation data

first I create validation set:

x_val = X_train[:1000]
partial_x_train = X_train[1000:]
y_val = Y_train[:1000]
partial_y_train = Y_train[1000:]
history = model.fit(partial_x_train,partial_y_train,
    epochs=20,
    batch_size=512,
    validation_data=(x_val, y_val))
#> Train on 436 samples, validate on 1000 samples
#> Epoch 1/20
#> 
#> 436/436 [==============================] - 0s 85us/step - loss: 1.4483 - mae: 0.9401 - val_loss: 1.6381 - val_mae: 1.0069
#> Epoch 2/20
#> 
#> 436/436 [==============================] - 0s 21us/step - loss: 1.3434 - mae: 0.9046 - val_loss: 1.6135 - val_mae: 0.9987
#> Epoch 3/20
#> 
#> 436/436 [==============================] - 0s 18us/step - loss: 1.2534 - mae: 0.8741 - val_loss: 1.5917 - val_mae: 0.9912
#> Epoch 4/20
#> 
#> 436/436 [==============================] - 0s 16us/step - loss: 1.1738 - mae: 0.8458 - val_loss: 1.5716 - val_mae: 0.9843
#> Epoch 5/20
#> 
#> 436/436 [==============================] - 0s 18us/step - loss: 1.1024 - mae: 0.8195 - val_loss: 1.5531 - val_mae: 0.9781
#> Epoch 6/20
#> 
#> 436/436 [==============================] - 0s 32us/step - loss: 1.0375 - mae: 0.7949 - val_loss: 1.5359 - val_mae: 0.9723
#> Epoch 7/20
#> 
#> 436/436 [==============================] - 0s 16us/step - loss: 0.9780 - mae: 0.7718 - val_loss: 1.5196 - val_mae: 0.9671
#> Epoch 8/20
#> 
#> 436/436 [==============================] - 0s 16us/step - loss: 0.9231 - mae: 0.7504 - val_loss: 1.5042 - val_mae: 0.9621
#> Epoch 9/20
#> 
#> 436/436 [==============================] - 0s 16us/step - loss: 0.8719 - mae: 0.7303 - val_loss: 1.4897 - val_mae: 0.9574
#> Epoch 10/20
#> 
#> 436/436 [==============================] - 0s 16us/step - loss: 0.8241 - mae: 0.7109 - val_loss: 1.4759 - val_mae: 0.9530
#> Epoch 11/20
#> 
#> 436/436 [==============================] - 0s 14us/step - loss: 0.7790 - mae: 0.6922 - val_loss: 1.4626 - val_mae: 0.9488
#> Epoch 12/20
#> 
#> 436/436 [==============================] - 0s 16us/step - loss: 0.7364 - mae: 0.6739 - val_loss: 1.4500 - val_mae: 0.9448
#> Epoch 13/20
#> 
#> 436/436 [==============================] - 0s 11us/step - loss: 0.6963 - mae: 0.6559 - val_loss: 1.4376 - val_mae: 0.9404
#> Epoch 14/20
#> 
#> 436/436 [==============================] - 0s 14us/step - loss: 0.6588 - mae: 0.6383 - val_loss: 1.4260 - val_mae: 0.9362
#> Epoch 15/20
#> 
#> 436/436 [==============================] - 0s 11us/step - loss: 0.6232 - mae: 0.6210 - val_loss: 1.4144 - val_mae: 0.9319
#> Epoch 16/20
#> 
#> 436/436 [==============================] - 0s 11us/step - loss: 0.5895 - mae: 0.6044 - val_loss: 1.4033 - val_mae: 0.9278
#> Epoch 17/20
#> 
#> 436/436 [==============================] - 0s 14us/step - loss: 0.5577 - mae: 0.5881 - val_loss: 1.3926 - val_mae: 0.9241
#> Epoch 18/20
#> 
#> 436/436 [==============================] - 0s 14us/step - loss: 0.5278 - mae: 0.5726 - val_loss: 1.3820 - val_mae: 0.9203
#> Epoch 19/20
#> 
#> 436/436 [==============================] - 0s 14us/step - loss: 0.4996 - mae: 0.5574 - val_loss: 1.3720 - val_mae: 0.9167
#> Epoch 20/20
#> 
#> 436/436 [==============================] - 0s 11us/step - loss: 0.4729 - mae: 0.5428 - val_loss: 1.3618 - val_mae: 0.9129

Extract cross validation information:

history_dict = history.history
loss_values = history_dict['loss']
val_loss_values = history_dict['val_loss']
epochs = range(1, len(loss_values) + 1)
cv_info = pd.DataFrame({'epochs':epochs,'loss_values':loss_values,'val_loss_values':val_loss_values})  
cv_info
#>     epochs  loss_values  val_loss_values
#> 0        1     1.448276         1.638064
#> 1        2     1.343392         1.613477
#> 2        3     1.253372         1.591659
#> 3        4     1.173802         1.571612
#> 4        5     1.102398         1.553143
#> 5        6     1.037460         1.535872
#> 6        7     0.977973         1.519616
#> 7        8     0.923061         1.504239
#> 8        9     0.871926         1.489711
#> 9       10     0.824143         1.475908
#> 10      11     0.779022         1.462641
#> 11      12     0.736392         1.449981
#> 12      13     0.696348         1.437634
#> 13      14     0.658771         1.425955
#> 14      15     0.623234         1.414390
#> 15      16     0.589503         1.403301
#> 16      17     0.557725         1.392590
#> 17      18     0.527814         1.382006
#> 18      19     0.499623         1.372013
#> 19      20     0.472888         1.361787
cv_info = pd.melt(cv_info, id_vars=['epochs'], value_vars=['loss_values', 'val_loss_values']) 
from plotnine import *

(
ggplot(cv_info,aes('epochs','value',color = 'variable')) +
geom_line() +
geom_point()
)
#> <ggplot: (112676044)>

Prediction

Y_pred = model.predict(X_test)
Y_pred
#> array([[11.550178],
#>        [13.072351],
#>        [11.186147],
#>        ...,
#>        [13.100971],
#>        [ 9.631788],
#>        [11.013977]], dtype=float32)
Y_pred.shape
#> (1459, 1)
Y_pred = np.concatenate(Y_pred).ravel() # to flatten 2 dimition array
Y_pred = np.expm1(Y_pred)
Y_pred
#> array([103794.47 , 475608.03 ,  72123.33 , ..., 489416.53 ,  15240.668,
#>         60715.883], dtype=float32)
test = pd.read_csv('E:/some_code/py_basic/house_price/data/test.csv')
submission = pd.DataFrame({'id': test['Id'], 'SalePrice': Y_pred})
submission.head(10)
#>      id      SalePrice
#> 0  1461  103794.468750
#> 1  1462  475608.031250
#> 2  1463   72123.328125
#> 3  1464   56685.023438
#> 4  1465   46361.867188
#> 5  1466  109739.531250
#> 6  1467   83739.242188
#> 7  1468  177004.093750
#> 8  1469  165609.843750
#> 9  1470  522844.250000
#submission.to_csv('./output/keras.csv',index = False) # save result