Applying K-fold cross validation to ANN - python

I developed an ANN based on a Machine Learning course that goes as follows:
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import tensorflow as tf
dataset = pd.read_excel('CHURN DATA (2).xlsx')
dataset.replace([np.inf, -np.inf], np.nan, inplace=True)
dataset = dataset.fillna(0)
X = dataset.iloc[:, 2:45].values
y = dataset.iloc[:, 45].values
from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
X[:, 1] = le.fit_transform(X[:,1])
X[:, 2] = le.fit_transform(X[:,2])
X[:, 3] = le.fit_transform(X[:,3])
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder
ct = ColumnTransformer(transformers=[('encoder', OneHotEncoder(),[0])], remainder = 'passthrough')
X = np.array(ct.fit_transform(X))
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2)
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
ann = tf.keras.models.Sequential()
ann.add(tf.keras.layers.Dense(units = 43, activation = 'relu'))
ann.add(tf.keras.layers.Dense(units = 43, activation = 'relu'))
ann.add(tf.keras.layers.Dense(units = 1, activation = 'sigmoid'))
ann.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics = ['accuracy'])
ann.fit(X_train, y_train, batch_size = 256, epochs = 100)
y_pred = ann.predict(X_test)
y_pred = (y_pred > 0.5)
from sklearn.metrics import confusion_matrix, accuracy_score
cm = confusion_matrix(y_test, y_pred)
print(cm)
accuracy_score(y_test, y_pred)
However, when trying to add kfold crossvalidation like so
from sklearn.model_selection import cross_val_score
accuracies = cross_val_score(ann, X = X_train, y = y_train, cv = 10)
mean = accuracies.mean()
variance = accuracies.std()
I get the follow error:
TypeError: If no scoring is specified, the estimator passed should have a 'score' method. The estimator <tensorflow.python.keras.engine.sequential.Sequential object at 0x000001A52F049F88> does not.
When I try using accuracy for scoring as
accuracies = cross_val_score(estimator = ann,scoring = "accuracy", X = X_train, y = y_train, cv = 10)
I get the following error:
Cannot clone object '<tensorflow.python.keras.engine.sequential.Sequential object at 0x000001A52F049F88>' (type <class 'tensorflow.python.keras.engine.sequential.Sequential'>): it does not seem to be a scikit-learn estimator as it does not implement a 'get_params' methods.

The error message says it all. You can't just pass a Keras model in Sklearn. There is a Keras wrapper for Sklearn, so both can indeed be used together. It's tensorflow.keras.wrappers.scikit_learn.KerasClassifier.
Here's a reproducible example with the MNIST:
import tensorflow as tf
from tensorflow.keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import cross_val_score
(X_train, y_train), (_, _) = tf.keras.datasets.mnist.load_data()
X_train = X_train[..., None]
def build_model():
model = tf.keras.models.Sequential([
tf.keras.layers.Flatten(input_shape=(28, 28, 1)),
tf.keras.layers.Dense(32, activation='relu'),
tf.keras.layers.Dense(10, activation='softmax')])
model.compile(loss='sparse_categorical_crossentropy',
optimizer='adam', metrics=['accuracy'])
return model
model = build_model()
history = model.fit(X_train, y_train, epochs=1)
keras_clf = KerasClassifier(build_model)
accuracies = cross_val_score(estimator=keras_clf, scoring="accuracy",
X=X_train, y=y_train, cv=5)
print(accuracies)
array([0.74008333, 0.65 , 0.71075 , 0.561 , 0.66683333])

Related

Cross-entropy validation losses comes out as a straight line

I'm trying to calculate cross-entropy losses using the Iris dataset, but when I ran my model and fired up my plots, both my losses and validation losses remained a straight line at zero. I don't know what I'm doing wrong. This is my code:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from tensorflow import keras
from keras import Sequential
from keras.layers import BatchNormalization, Dense, Dropout
from keras.callbacks import EarlyStopping
iris = sns.load_dataset('iris')
X = iris.iloc[:,:4]
y = iris.species.replace({'setosa': 0, 'versicolor': 1, 'virginica': 2})
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=.3, random_state=69)
sc = StandardScaler()
sc.fit_transform(X_train)
sc.fit_transform(X_test)
nn_model = Sequential([Dense(4, activation='relu', input_shape=[X.shape[1]]),
BatchNormalization(),
Dropout(.3),
Dense(4, activation='relu'),
BatchNormalization(),
Dropout(.3),
Dense(1, activation='sigmoid')])
nn_model.compile(optimizer='sgd', loss='categorical_crossentropy', metrics=['categorical_accuracy'])
early_stopping = EarlyStopping(min_delta=1e-3, patience=10, restore_best_weights=True)
fit = nn_model.fit(X_train, y_train, validation_data=(X_test,y_test),
batch_size=16, epochs=200, callbacks=[early_stopping], verbose=1)
losses = pd.DataFrame(fit.history)
And this is what the plots look like:
Any reason why it's doing this?
The fit transformation of StandardScaler() isn't in-place operation. You have to do as follows
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
Also, you have 3 outputs (check: y_train.value_counts()), so the output layer should be:
nn_model = Sequential([ ...,
Dropout(.3),
Dense(3, activation='softmax')])
Lastly, the loss function should be sparse_categorical_crossentropy for your integer target.
nn_model.compile(optimizer='sgd',
loss='sparse_categorical_crossentropy',
metrics=['accuracy'])

loss becomes 'nan' in all of epochs in Keras ANN (regression)

I have a regression problem and I've made a Keras ANN.
All of my data type (both feature and target matrix) are float;
I have 3 layers(5 input nodes, two hidden_layers with 3 nodes, and 1 output node);
optimizer='adam', batch_size='10', loss='mean_squared_error' and activation functions are 'relu' except the last one which is 'linear'.
due to training, all of my epochs losses are 'nan', and also my predicted values are all 'nan'!
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
dataset = pd.read_csv('/content/drive/MyDrive/Miss Derakhshan data (1).csv')
X = dataset.iloc[:, 1:6].values
y = dataset.iloc[:, 8].values
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.20)
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
import keras
from keras.models import Sequential
from keras.layers import Dense
regression = Sequential()
regression.add(Dense(units = 4, input_dim = 5, kernel_initializer= 'uniform',
activation = 'relu'))
regression.add(Dense(units = 3, kernel_initializer = 'uniform' , activation = 'relu'))
regression.add(Dense(units = 1 , kernel_initializer = 'uniform', activation = 'linear'))
regression.compile(optimizer = 'adam', loss = 'mean_squared_error' , metrics = ['accuracy'])
regression.fit(X_train, y_train, batch_size = 5 , epochs = 100)
y_pred = regression.predict(X_test)
print(y_pred)

Regression problems in Keras

I am applying ML based regression techniques for developing prediction model for my experimental setup.
I applied various models : LR, Decision Tree and Random Forest.
I am getting 84% accuracy for RF model. I now want to improve this score with Keras DL mode.
Can anyone guide me for approaching regression based techniques using DL with Keras.
I used following model but accuracy could not go beyond 70%:
model = Sequential()
model.add(Dense(20,input_dim=5, activation='relu'))
#second hidden layer
model.add(Dense(20, activation='relu'))
#output layer
model.add(Dense(1, activation='linear'))
#compile ANN
model.compile(optimizer="Adam", loss='mean_squared_error', metrics=['accuracy'])
How can one apply DL for regression techniques.
Here is both regression and classification, with Keras and TF. The data set is available from the link at the end of this post.
import pandas as pd
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
# %matplotlib inline
import seaborn as sns
sns.set(style="darkgrid")
# Classification with TensorFlow 2.0
cols = ['price', 'maint', 'doors', 'persons', 'lug_capacity', 'safety','output']
cars = pd.read_csv(r'C:/your_path/car_evaluation.csv', names=cols, header=None)
cars.head()
plot_size = plt.rcParams["figure.figsize"]
plot_size [0] = 8
plot_size [1] = 6
plt.rcParams["figure.figsize"] = plot_size
cars.output.value_counts().plot(kind='pie', autopct='%0.05f%%', colors=['lightblue', 'lightgreen', 'orange', 'pink'], explode=(0.05, 0.05, 0.05,0.05))
price = pd.get_dummies(cars.price, prefix='price')
maint = pd.get_dummies(cars.maint, prefix='maint')
doors = pd.get_dummies(cars.doors, prefix='doors')
persons = pd.get_dummies(cars.persons, prefix='persons')
lug_capacity = pd.get_dummies(cars.lug_capacity, prefix='lug_capacity')
safety = pd.get_dummies(cars.safety, prefix='safety')
labels = pd.get_dummies(cars.output, prefix='condition')
X = pd.concat([price, maint, doors, persons, lug_capacity, safety] , axis=1)
labels.head()
y = labels.values
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.20, random_state=42)
#Model Training
from tensorflow.keras.layers import Input, Dense, Activation,Dropout
from tensorflow.keras.models import Model
input_layer = Input(shape=(X.shape[1],))
dense_layer_1 = Dense(15, activation='relu')(input_layer)
dense_layer_2 = Dense(10, activation='relu')(dense_layer_1)
output = Dense(y.shape[1], activation='softmax')(dense_layer_2)
model = Model(inputs=input_layer, outputs=output)
model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['acc'])
print(model.summary())
history = model.fit(X_train, y_train, batch_size=8, epochs=50, verbose=1, validation_split=0.2)
score = model.evaluate(X_test, y_test, verbose=1)
print("Test Score:", score[0])
print("Test Accuracy:", score[1])
# Regression with TensorFlow 2.0
petrol_cons = pd.read_csv(r'C:/your_path/petrol_consumption.csv')
petrol_cons.head()
X = petrol_cons.iloc[:, 0:4].values
y = petrol_cons.iloc[:, 4].values
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
from sklearn.preprocessing import StandardScaler
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
input_layer = Input(shape=(X.shape[1],))
dense_layer_1 = Dense(100, activation='relu')(input_layer)
dense_layer_2 = Dense(50, activation='relu')(dense_layer_1)
dense_layer_3 = Dense(25, activation='relu')(dense_layer_2)
output = Dense(1)(dense_layer_3)
model = Model(inputs=input_layer, outputs=output)
model.compile(loss="mean_squared_error" , optimizer="adam", metrics=["mean_squared_error"])
history = model.fit(X_train, y_train, batch_size=2, epochs=100, verbose=1, validation_split=0.2)
from sklearn.metrics import mean_squared_error
from math import sqrt
pred_train = model.predict(X_train)
print(np.sqrt(mean_squared_error(y_train,pred_train)))
pred = model.predict(X_test)
print(np.sqrt(mean_squared_error(y_test,pred)))
# path to dataset
# https://www.kaggle.com/elikplim/car-evaluation-data-set

Calculating mean square error return y_true and y_pred have different number of output (1!=10)

I am really new with deep learning. I want to do a task which asks: Evaluate the model on the test data and compute the mean squared error between the predicted concrete strength and the actual concrete strength. You can use the mean_squared_error function from Scikit-learn.
here is my code:
import pandas as pd
from tensorflow.python.keras import Sequential
from tensorflow.python.keras.layers import Dense
from sklearn.model_selection import train_test_split
concrete_data = pd.read_csv('https://cocl.us/concrete_data')
n_cols = concrete_data.shape[1]
model = Sequential()
model.add(Dense(units=10, activation='relu', input_shape=(n_cols-1,)))
model.compile(loss='mean_squared_error',
optimizer='adam')
y = concrete_data.Cement
x = concrete_data.drop('Cement', axis=1)
xTrain, xTest, yTrain, yTest = train_test_split(x, y, test_size = 0.3)
model.fit(xTrain, yTrain, epochs=50)
and now to evaluate mean square error I wrote this :
from sklearn.metrics import mean_squared_error
predicted_y = model.predict(xTest)
mean_squared_error(yTest, predicted_y)
and I got this error:
y_true and y_pred have different number of output (1!=10)
my predicted_y shape is : (309, 10)
I googled it and I really couldn't find an answer to solve this problem. I don't know what is wrong with my code.
Your y_test data shape is (N, 1) but because you put 10 neurons in output layer, your model makes 10 different predictions which is the error.
You need to change the number of neurons in the output layer to 1 or add a new output layer which has only 1 neuron.
The below code probably works for you.
import pandas as pd
from tensorflow.python.keras import Sequential
from tensorflow.python.keras.layers import Dense
from sklearn.model_selection import train_test_split
concrete_data = pd.read_csv('https://cocl.us/concrete_data')
n_cols = concrete_data.shape[1]
model = Sequential()
model.add(Dense(units=10, activation='relu', input_shape=(n_cols-1,)))
model.add(Dense(units=1))
model.compile(loss='mean_squared_error',
optimizer='adam')
y = concrete_data.Cement
x = concrete_data.drop('Cement', axis=1)
xTrain, xTest, yTrain, yTest = train_test_split(x, y, test_size = 0.3)
model.fit(xTrain, yTrain, epochs=50)
Actually, what you are trying to check is the mean_squared_error of y_test and the predicted_y
You have to check what your model predict on x_test, which is the prediction :
predicted_y = model.predict(x_test)
Then you can calculate the error:
mean_squared_error(y_test, predicted_y)
y_pred = model.predict(x_test).sum(axis=1)
Try this, it worked for me

Using a trained Keras model to make predictions on new csv data

so I'm making a project where basically i have to predict whether or not a house price is above or below its median price and to do that, I'm using this dataset from Kaggle(https://drive.google.com/file/d/1GfvKA0qznNVknghV4botnNxyH-KvODOC/view). 1 means "Above Median" and 0 means "Below Median". I wrote this code to train a neural network and save it as a .h5 file:
import pandas as pd
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense
import h5py
df = pd.read_csv('housepricedata.csv')
dataset = df.values
X = dataset[:,0:10]
Y = dataset[:,10]
min_max_scaler = preprocessing.MinMaxScaler()
X_scale = min_max_scaler.fit_transform(X)
X_train, X_val_and_test, Y_train, Y_val_and_test = train_test_split(X_scale, Y, test_size=0.3)
X_val, X_test, Y_val, Y_test = train_test_split(X_val_and_test, Y_val_and_test, test_size=0.5)
model = Sequential([
Dense(32, activation='relu', input_shape=(10,)),
Dense(32, activation='relu'),
Dense(1, activation='sigmoid'),
])
model.compile(optimizer='sgd',
loss='binary_crossentropy',
metrics=['accuracy'])
hist = model.fit(X_train, Y_train,
batch_size=32, epochs=100,
validation_data=(X_val, Y_val))
model.save("house_price.h5")
After running it, it successfully saves the .h5 file to my directory. What I want to do now is use my trained model to make predictions on a new .csv file and determine whether or not each of those are above or below median price. This is an image of the csv file in VSCode that i want it to make predictions on:
csv file image As you can see, this file doesn't contain a 1(above median) or 0(below median) because that's what I want it to predict. This is the code I wrote to do that:
import pandas as pd
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from keras.models import Sequential
from keras.layers import Dense
from keras.models import load_model
import h5py
df = pd.read_csv('data.csv')
dataset = df.values
X = dataset[:,0:10]
Y = dataset[:,10]
min_max_scaler = preprocessing.MinMaxScaler()
X_scale = min_max_scaler.fit_transform(X)
X_train, X_val_and_test, Y_train, Y_val_and_test = train_test_split(X_scale, Y, test_size=0.3)
X_val, X_test, Y_val, Y_test = train_test_split(X_val_and_test, Y_val_and_test, test_size=0.5)
model = load_model("house_price.h5")
y_pred = model.predict(X_test)
print(y_pred)
It's output is [[0.00101464]] I have no clue what that is and why it's only returning one value even though the csv file has 4 rows. Does anyone know how I can fix that and be able to predict either a 1 or a 0 for each row in the csv file?
Thank You!
As much I understand what you want!
Let's Try ! This code work for me
import tensorflow
model = tensorflow.keras.models.load_model("house_price.h5")
y_pred=model.predict(X_test)
still you are not able to get visit following site
1:answer1
2:answer2
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
# Importing the dataset
dataset = pd.read_csv('C:\\Users\\acer\\Downloads\\housepricedata.csv')
dataset.head()
X=dataset.iloc[:,0:10]
y=dataset.iloc[:,10]
X.head()
from sklearn.preprocessing import StandardScaler
obj=StandardScaler()
X=obj.fit_transform(X)
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test=train_test_split
(X,y,random_state=2020,test_size=0.25)
print(X_train.shape)
print(X_test.shape)
print(y_train.shape)
print(y_test.shape)
import keras
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
classifier = Sequential()
# Adding the input layer and the first hidden layer
classifier.add(Dense(units = 6, kernel_initializer = 'uniform', activation =
'relu', input_dim = 10))
# classifier.add(Dropout(p = 0.1))
# Adding the second hidden layer
classifier.add(Dense(units = 6, kernel_initializer = 'uniform', activation
= 'relu'))
# classifier.add(Dropout(p = 0.1))
# Adding the output layer
classifier.add(Dense(units = 1, kernel_initializer = 'uniform', activation
= 'sigmoid'))
# Compiling the ANN
classifier.compile(optimizer = 'adam', loss = 'binary_crossentropy', metrics
= ['accuracy'])
classifier.fit(X_train, y_train, batch_size = 10, epochs = 100)
y_pred = classifier.predict(X_test)
y_pred = (y_pred > 0.5)
print(y_pred)
classifier.save("house_price.h5")
import tensorflow
model = tensorflow.keras.models.load_model("house_price.h5")
y_pred=model.predict(X_test)
y_pred = (y_pred > 0.5)
print(y_pred)
Both y_pred produce same output for me
Here one thing you not y_pred not contain 0 and 1 because you use sigmoid function which determine predication in probability
so if(y_pred>0.5) it mean value is one
#True rep one
#false rep zero
#you can use replace function or map function of pandas to get convert true
into 1

Categories