def Kfold(x, y, z, folds, degree, lambd=None):
        Xtrain, ztrain, Xtest, ztest = Evaluation.CV_split(x, y, z, folds)
        MSE_alltrain = np.zeros(folds)
        MSE_alltest = np.zeros(folds)

        for i in range(folds):
            # picking out the ith fold of training data
            xtrain = Xtrain[i]
            x = xtrain[:, 0]
            y = xtrain[:, 1]
            z = ztrain[i]

            # Finding error for train data
            X_train = Regression.CreateDesignMatrix_X(x, y, degree)
            beta_train = Regression.Beta(X_train, z, lambd)
            ztilde_train = Regression.Prediction(X_train, beta_train)
            MSE_alltrain[i] = Evaluation.MSE(z, ztilde_train)

            # picking out the ith fold for test data
            xtest = Xtest[i]
            x = xtest[:, 0]
            y = xtest[:, 1]
            z = ztest[i]

            # Finding error for test data
            X_test = Regression.CreateDesignMatrix_X(x, y, degree)
            ztilde_test = Regression.Prediction(X_test, beta_train)
            MSE_alltest[i] = Evaluation.MSE(ztest[i], ztilde_test)

        MSEtrain = np.mean(MSE_alltrain)
        MSEtest = np.mean(MSE_alltest)

        return MSEtrain, MSEtest
    def BiasVarTradeOff(x, y, z, folds, degree, lambd=None):
        if len(x.shape) > 1 or len(y.shape) > 1 or len(z.shape) > 1:
            x, y, z = x.flatten(), y.flatten(), z.flatten()
        X = np.transpose(np.array([x, y, z]))

        np.random.shuffle(X)
        z = X[:, 2]

        X = X[:, 0:2]
        x_train, x_test, z_train, z_test = train_test_split(
            X, z, test_size=0.2)  # Make test data that is not used in Kfold CV

        x1 = x_train[:, 0]
        y1 = x_train[:, 1]
        z1 = z_train

        folds = folds - 1  ### obs needs to be done to do splitting. Means Kfold is done with k-1 folds!!!!

        error_alltest = np.zeros(degree)
        bias_alltest = np.zeros(degree)
        var_alltest = np.zeros(degree)

        for d in range(degree):
            Xtrain, ztrain, Xtest, ztest = Evaluation.CV_split(
                x1, y1, z1, folds)
            ztilde_test = np.zeros([len(z_test), folds])
            for i in range(folds):
                xtrain = Xtrain[i]
                x = xtrain[:, 0]
                y = xtrain[:, 1]
                X_train = Regression.CreateDesignMatrix_X(x, y, d)
                beta_train = Regression.Beta(X_train, ztrain[i], lambd)

                x = x_test[:, 0]
                y = x_test[:, 1]
                X_test = Regression.CreateDesignMatrix_X(x, y, d)
                ztilde_test[:, i] = Regression.Prediction(X_test, beta_train)
            z_test = z_test.reshape(z_test.shape[0], 1)
            error_alltest[d] = np.mean(
                np.mean((ztilde_test - z_test)**2, axis=1, keepdims=True))

            bias_alltest[d] = np.mean(
                (z_test - np.mean(ztilde_test, axis=1, keepdims=True))**2)
            var_alltest[d] = np.mean(np.var(ztilde_test, axis=1,
                                            keepdims=True))

        return bias_alltest, var_alltest, error_alltest