def main(ifname='winequality-red.csv', delimiter=';', has_header=True, folds = 10): Train_Data, Test_Data = split_data(ifname, delimiter, has_header, [0,1,2,3,4,5,6,7,8,9,10]) Train_Targets, Test_Targets = split_data(ifname, delimiter, has_header, [11]) Train_Second = second_degree_designmtx(Train_Data) Test_Data_Second = second_degree_designmtx(Test_Data) Train_Third = third_degree_designmtx(Train_Data) Test_Data_Third = third_degree_designmtx(Test_Data) Train_Fourth = fourth_degree_designmtx(Train_Data) Test_Data_Fourth = fourth_degree_designmtx(Test_Data) #print("Second degree polynomial regression") #evaluate_reg_param(Train_Second, Train_Targets, create_cv_folds(len(Train_Second), folds), reg_params = np.logspace(-2,5)) #print("Third degree polynomial regression") #evaluate_reg_param(Train_Third, Train_Targets, create_cv_folds(len(Train_Third), folds), reg_params = np.logspace(2,7)) #print("Fourth degree polynomial regression") #evaluate_reg_param(Train_Fourth, Train_Targets, create_cv_folds(len(Train_Third), folds), reg_params = np.logspace(6,10)) #print("Second degree polynomial regression (normalized)") reg_second = evaluate_reg_param(normalize(Train_Second), Train_Targets, create_cv_folds(len(Train_Second), folds), reg_params = np.logspace(-1,3)) #print("Third degree polynomial regression (normalized)") reg_third = evaluate_reg_param(normalize(Train_Third), Train_Targets, create_cv_folds(len(Train_Third), folds), reg_params = np.logspace(-1,3)) #print("Fourth degree polynomial regression (normalized)") reg_fourth =evaluate_reg_param(normalize(Train_Fourth), normalize(Train_Targets), create_cv_folds(len(Train_Third), folds), reg_params = np.logspace(-1,3)) print("Train, Test error (degree 2): ", train_and_test(normalize(Train_Second), Train_Targets, normalize(Test_Data_Second), Test_Targets, reg_param = reg_second)) print("Train, Test error (degree 3): ", train_and_test(normalize(Train_Third), Train_Targets, normalize(Test_Data_Third), Test_Targets, reg_param = reg_third)) print("Train, Test error (degree 4): ", train_and_test(normalize(Train_Fourth), Train_Targets, normalize(Test_Data_Fourth), Test_Targets, reg_param = reg_fourth))
def parameter_search_rbf(inputs, targets, test_fraction): """ """ N = inputs.shape[0] # run all experiments on the same train-test split of the data train_part, test_part = train_and_test_split(N, test_fraction=test_fraction) # for the centres of the basis functions sample 10% of the data sample_fraction = 0.15 p = (1 - sample_fraction, sample_fraction) centres = inputs[np.random.choice([False, True], size=N, p=p), :] print("centres.shape = %r" % (centres.shape, )) scales = np.logspace(0, 2, 17) # of the basis functions reg_params = np.logspace(-15, -4, 11) # choices of regularisation strength # create empty 2d arrays to store the train and test errors train_errors = np.empty((scales.size, reg_params.size)) test_errors = np.empty((scales.size, reg_params.size)) # iterate over the scales for i, scale in enumerate(scales): # i is the index, scale is the corresponding scale # we must recreate the feature mapping each time for different scales feature_mapping = construct_rbf_feature_mapping(centres, scale) designmtx = feature_mapping(inputs) # partition the design matrix and targets into train and test train_designmtx, train_targets, test_designmtx, test_targets = \ train_and_test_partition( designmtx, targets, train_part, test_part) # iteratre over the regularisation parameters for j, reg_param in enumerate(reg_params): # j is the index, reg_param is the corresponding regularisation # parameter # train and test the data train_error, test_error = train_and_test(train_designmtx, train_targets, test_designmtx, test_targets, reg_param=reg_param) # store the train and test errors in our 2d arrays train_errors[i, j] = train_error test_errors[i, j] = test_error # we have a 2d array of train and test errors, we want to know the (i,j) # index of the best value best_i = np.argmin(np.argmin(test_errors, axis=1)) best_j = np.argmin(test_errors[i, :]) print("Best joint choice of parameters:") print("\tscale %.2g and lambda = %.2g" % (scales[best_i], reg_params[best_j])) # now we can plot the error for different scales using the best # regulariation choice fig, ax = plot_train_test_errors("scale", scales, train_errors[:, best_j], test_errors[:, best_j]) ax.set_xscale('log') # ...and the error for different regularisation choices given the best # scale choice fig, ax = plot_train_test_errors("$\lambda$", reg_params, train_errors[best_i, :], test_errors[best_i, :]) ax.set_xscale('log')
def cv_evaluation_linear_model(inputs, targets, folds, reg_param=None): """ Will split inputs and targets into train and test parts, then fit a linear model to the training part, and test on the both parts. Inputs can be a data matrix (or design matrix), targets should be real valued. parameters ---------- inputs - the input design matrix !!!!!!!!!!!!!!!!!!!!(any feature mapping should already be applied) targets - the targets as a vector num_folds - the number of folds reg_param (optional) - the regularisation strength. If provided, then regularised least squares fitting is uses with this regularisation strength. Otherwise, (non-regularised) least squares is used. returns ------- train_errors - the training errors for the approximation test_errors - the test errors for the approximation """ # get the number of datapoints N = inputs.shape[0] # get th number of folds num_folds = len(folds) train_errors = np.empty(num_folds) test_errors = np.empty(num_folds) for f,fold in enumerate(folds): # f is the fold id, fold is the train-test split train_part, test_part = fold # break the data into train and test sets train_inputs, train_targets, test_inputs, test_targets = \ train_and_test_partition(inputs, targets, train_part, test_part) # now train and evaluate the error on both sets train_error, test_error,weights = train_and_test( train_inputs, train_targets, test_inputs, test_targets, reg_param=reg_param) #print("train_error = %r" % (train_error,)) #print("test_error = %r" % (test_error,)) train_errors[f] = train_error test_errors[f] = test_error return train_errors, test_errors,weights
def parameter_search_rbf(inputs, targets, test_fraction): """ """ n = inputs.shape[0] # run all experiments on the same train-test split of the data train_part, test_part = train_and_test_split(n, test_fraction=test_fraction) # for the centres of the basis functions sample 10% of the data sample_fraction = 0.10 p = (1 - sample_fraction, sample_fraction) centres = inputs[np.random.choice([False, True], size=n, p=p), :] print("\ncentres.shape = %r" % (centres.shape, )) scales = np.logspace(0, 6, 20) # of the basis functions reg_params = np.logspace(-15, 5, 20) # choices of regularisation strength # create empty 2d arrays to store the train and test errors train_errors = np.empty((scales.size, reg_params.size)) test_errors = np.empty((scales.size, reg_params.size)) # iterate over the scales for i, scale in enumerate(scales): # i is the index, scale is the corresponding scale # we must recreate the feature mapping each time for different scales feature_mapping = construct_rbf_feature_mapping(centres, scale) designmtx = feature_mapping(inputs) # partition the design matrix and targets into train and test train_designmtx, train_targets, test_designmtx, test_targets = \ train_and_test_partition( designmtx, targets, train_part, test_part) # iterating over the regularisation parameters for j, reg_param in enumerate(reg_params): # j is the index, reg_param is the corresponding regularisation # parameter # train and test the data train_error, test_error = train_and_test(train_designmtx, train_targets, test_designmtx, test_targets, reg_param=reg_param) # store the train and test errors in our 2d arrays train_errors[i, j] = train_error test_errors[i, j] = test_error # we have a 2d array of train and test errors, we want to know the (i,j) # index of the best value best_i = np.argmin(np.argmin(test_errors, axis=1)) best_j = np.argmin(test_errors[i, :]) min_place = np.argmin(test_errors) best_i_correct = (int)(min_place / test_errors.shape[1]) best_j_correct = min_place % test_errors.shape[1] print(best_i) print(best_j) print(best_i_correct) print(best_j_correct) min = test_errors[test_errors != 0].min() ij_min = np.where(test_errors == min) ij_min = tuple([i.item() for i in ij_min]) print(ij_min[1]) print("\nBest joint choice of parameters:") print("\tscale %.2g and lambda = %.2g" % (scales[best_i_correct], reg_params[best_j_correct])) # now we can plot the error for different scales using the best # regularisation choice fig, ax = plot_train_test_errors("scale", scales, train_errors[:, best_j_correct], test_errors[:, best_j_correct]) ax.set_xscale('log') ax.set_title('Train vs Test Error Across Scales') fig.savefig("../plots/rbf_searching_scales.pdf", fmt="pdf") # ...and the error for different regularisation choices given the best # scale choice fig, ax = plot_train_test_errors("$\lambda$", reg_params, train_errors[best_i_correct, :], test_errors[best_i_correct, :]) ax.set_xscale('log') ax.set_title('Train vs Test Error Across Reg Params') fig.savefig("../plots/rbf_searching_reg_params.pdf", fmt="pdf") # using the best parameters found above, # we now vary the number of centres and evaluate the performance reg_param = reg_params[best_j_correct] scale = scales[best_i_correct] n_centres_seq = np.arange(1, 20) train_errors = [] test_errors = [] for n_centres in n_centres_seq: # constructing the feature mapping anew for each number of centres centres = np.linspace(0, 1, n_centres) feature_mapping = construct_rbf_feature_mapping(centres, scale) design_matrix = feature_mapping(inputs) train_designmtx, train_targets, test_designmtx, test_targets = \ train_and_test_partition( design_matrix, targets, train_part, test_part) # evaluating the test and train error for the given regularisation parameter and scale train_error, test_error = train_and_test(train_designmtx, train_targets, test_designmtx, test_targets, reg_param) # collecting the errors train_errors.append(train_error) test_errors.append(test_error) # plotting the results fig, ax = plot_train_test_errors("no. centres", n_centres_seq, train_errors, test_errors) ax.set_title('Train vs Test Error Across Centre Number') fig.savefig("../plots/rbf_searching_number_centres.pdf", fmt="pdf")
def main(ifname, delimiter=None, columns=None, has_header=True, test_fraction=0.25): data, field_names = import_data(ifname, delimiter=delimiter, has_header=has_header, columns=columns) #Exploratory Data Analysis (EDA) raw_data = pd.read_csv('datafile.csv', sep=";") # view correlation efficieny result where |r|=1 has the strongest relation and |r|=0 the weakest df = pd.DataFrame(data=raw_data) print(df.corr()) # view data if it is normally distributed plt.hist(raw_data["quality"], range=(1, 10), edgecolor='black', linewidth=1) plt.xlabel('quality') plt.ylabel('amount of samples') plt.title("distribution of red wine quality") # feature selection import scipy.stats as stats from scipy.stats import chi2_contingency class ChiSquare: def __init__(self, dataframe): self.df = dataframe self.p = None # P-Value self.chi2 = None # Chi Test Statistic self.dof = None self.dfObserved = None self.dfExpected = None def _print_chisquare_result(self, colX, alpha): result = "" if self.p < alpha: result = "{0} is IMPORTANT for Prediction".format(colX) else: result = "{0} is NOT an important predictor. (Discard {0} from model)".format( colX) print(result) def TestIndependence(self, colX, colY, alpha=0.05): X = self.df[colX].astype(str) Y = self.df[colY].astype(str) self.dfObserved = pd.crosstab(Y, X) chi2, p, dof, expected = stats.chi2_contingency( self.dfObserved.values) self.p = p self.chi2 = chi2 self.dof = dof self.dfExpected = pd.DataFrame(expected, columns=self.dfObserved.columns, index=self.dfObserved.index) self._print_chisquare_result(colX, alpha) print('self:%s' % (self), self.chi2, self.p) # Initialize ChiSquare Class cT = ChiSquare(raw_data) # Feature Selection testColumns = [ "fixed acidity", "volatile acidity", "citric acid", "residual sugar", "chlorides", "free sulfur dioxide", "total sulfur dioxide", "density", "pH", "sulphates", "alcohol" ] for var in testColumns: cT.TestIndependence(colX=var, colY="quality") # split data into inputs and targets inputs = data[:, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]] targets = data[:, 11] # mean normalisation fixed_acidity = inputs[:, 0] volatile_acidity = inputs[:, 1] citric_acid = inputs[:, 2] residual_sugar = inputs[:, 3] chlorides = inputs[:, 4] free_sulfur_dioxide = inputs[:, 5] total_sulfur_dioxide = inputs[:, 6] density = inputs[:, 7] ph = inputs[:, 8] sulphates = inputs[:, 9] alcohol = inputs[:, 10] # draw plot of data set normalised_data = np.column_stack((inputs, targets)) exploratory_plots(normalised_data, field_names) # add a colum of x0.ones inputs[:, 0] = np.ones(len(targets)) # normalize data inputs[:, 1] = (volatile_acidity - np.mean(volatile_acidity)) / np.std(volatile_acidity) inputs[:, 2] = (citric_acid - np.mean(citric_acid)) / np.std(citric_acid) inputs[:, 7] = (density - np.mean(density)) / np.std(density) inputs[:, 9] = (sulphates - np.mean(sulphates)) / np.std(sulphates) inputs[:, 10] = (alcohol - np.mean(alcohol)) / np.std(alcohol) # run all experiments on the same train-test split of the data train_part, test_part = train_and_test_split(inputs.shape[0], test_fraction=test_fraction) # another evaluation function def rsquare(test_targets, test_predicts): y_mean = np.mean(test_targets) ss_tot = sum((test_targets - y_mean)**2) ss_res = sum((test_targets - test_predicts)**2) rsquare = 1 - (ss_res / ss_tot) return rsquare print( '---------------------------Linear Regression-----------------------------------' ) # linear regression # add a column of 1 to the data matrix inputs = inputs[:, [0, 1, 2, 7, 9, 10]] #train_part, test_part = train_and_test_split(inputs.shape[0], test_fraction=test_fraction) train_inputs, train_targets, test_inputs, test_targets = train_and_test_partition( inputs, targets, train_part, test_part) weights = ml_weights(train_inputs, train_targets) train_predicts = linear_model_predict(train_inputs, weights) test_predicts = linear_model_predict(test_inputs, weights) train_error = root_mean_squared_error(train_targets, train_predicts) test_error = root_mean_squared_error(test_targets, test_predicts) print("LR-train_weights", weights) print("LR-train_error", train_error) print("LR-test_error", test_error) print("LR-rsquare score", rsquare(test_targets, test_predicts)) print("LR-prediction:", test_predicts[:20], "LR-original", test_targets[:20]) print( '----------------Regularised Linear Regression-----------------------------' ) #regularised linear regression reg_params = np.logspace(-15, -4, 11) train_errors = [] test_errors = [] for reg_param in reg_params: # print("RLR-Evaluating reg_para " + str(reg_param)) train_inputs, train_targets, test_inputs, test_targets = train_and_test_partition( inputs, targets, train_part, test_part) reg_weights = regularised_ml_weights(train_inputs, train_targets, reg_param) train_predicts = linear_model_predict(train_inputs, reg_weights) test_predicts = linear_model_predict(test_inputs, reg_weights) train_error = root_mean_squared_error(train_targets, train_predicts) test_error = root_mean_squared_error(test_targets, test_predicts) train_errors.append(train_error) test_errors.append(test_error) #best lambda test_errors = np.array(test_errors) best_l = np.argmin(test_errors) print("RLR-Best joint choice of parameters:") print("RLR-lambda = %.2g" % (reg_params[best_l])) # plot train_test_errors in different reg_params fig, ax = plot_train_test_errors("$\lambda$", reg_params, train_errors, test_errors) ax.set_xscale('log') reg_weights = regularised_ml_weights(train_inputs, train_targets, best_l) print("RLR-train_weights", reg_weights) print("RLR-train_error", train_errors[best_l]) print("RLR-test_error", test_errors[best_l]) print("RLR-rsquare score", rsquare(test_targets, test_predicts)) print("RLR-prediction:", test_predicts[:20], "RLR-original", test_targets[:20]) print( '-----------------------------kNN Regression------------------------------------' ) # KNN-regression # tip out the x0=1 column inputs = inputs[:, [1, 2, 3, 4, 5]] train_errors = [] test_errors = [] K = range(2, 9) for k in K: train_inputs, train_targets, test_inputs, test_targets = train_and_test_partition( inputs, targets, train_part, test_part) knn_approx = construct_knn_approx(train_inputs, train_targets, k) train_knn_predicts = knn_approx(train_inputs) train_error = root_mean_squared_error(train_knn_predicts, train_targets) test_knn_predicts = knn_approx(test_inputs) test_error = root_mean_squared_error(test_knn_predicts, test_targets) train_errors.append(train_error) test_errors.append(test_error) # print("knn_predicts: ", np.around(test_knn_predicts), "knn-original", test_targets) #best k train_errors = np.array(train_errors) test_errors = np.array(test_errors) best_k = np.argmin(test_errors) print("Best joint choice of parameters:") print("k = %.2g" % (K[best_k])) fig, ax = plot_train_test_errors("K", K, train_errors, test_errors) ax.set_xticks(np.arange(min(K), max(K) + 1, 1.0)) print("kNN-train_error", train_errors[-1]) print("kNN-test_error", test_errors[-1]) knn_approx = construct_knn_approx(train_inputs, train_targets, k=3) test_predicts = knn_approx(test_inputs) print("kNN-rsquare score", rsquare(test_targets, test_predicts)) print("kNN-y_predicts", test_predicts[:20], 'y_original', test_targets[:20]) print( '----------------------------RBF Function-------------------------------------' ) # Radinal Basis Functions # for the centres of the basis functions sample 15% of the data sample_fraction = 0.15 p = (1 - sample_fraction, sample_fraction) centres = inputs[np.random.choice([False, True], size=inputs.shape[0], p=p), :] # !!! print("centres.shape = %r" % (centres.shape, )) scales = np.logspace(0, 2, 17) # of the basis functions reg_params = np.logspace(-15, -4, 11) # choices of regularisation strength # create empty 2d arrays to store the train and test errors train_errors = np.empty((scales.size, reg_params.size)) test_errors = np.empty((scales.size, reg_params.size)) # iterate over the scales for i, scale in enumerate(scales): # i is the index, scale is the corresponding scale # we must recreate the feature mapping each time for different scales feature_mapping = construct_rbf_feature_mapping(centres, scale) designmtx = feature_mapping(inputs) # partition the design matrix and targets into train and test train_designmtx, train_targets, test_designmtx, test_targets = \ train_and_test_partition(designmtx, targets, train_part, test_part) # iteratre over the regularisation parameters for j, reg_param in enumerate(reg_params): # j is the index, reg_param is the corresponding regularisation # parameter # train and test the data train_error, test_error = train_and_test(train_designmtx, train_targets, test_designmtx, test_targets, reg_param=reg_param) # store the train and test errors in our 2d arrays train_errors[i, j] = train_error test_errors[i, j] = test_error # we have a 2d array of train and test errors, we want to know the (i,j) # index of the best value best_i = np.argmin(np.argmin(test_errors, axis=1)) best_j = np.argmin(test_errors[i, :]) print("Best joint choice of parameters:") print("\tscale= %.2g and lambda = %.2g" % (scales[best_i], reg_params[best_j])) # now we can plot the error for different scales using the best # regulariation choice fig, ax = plot_train_test_errors("scale", scales, train_errors[:, best_j], test_errors[:, best_j]) ax.set_xscale('log') # ...and the error for different regularisation choices given the best # scale choice fig, ax = plot_train_test_errors("$\lambda$", reg_params, train_errors[best_i, :], test_errors[best_i, :]) ax.set_xscale('log') feature_mapping = construct_rbf_feature_mapping(centres, scales[best_i]) reg_weights = regularised_ml_weights(train_designmtx, train_targets, reg_params[best_j]) # test function test_predicts = np.matrix(test_designmtx) * np.matrix(reg_weights).reshape( (len(reg_weights), 1)) test_predicts = np.array(test_predicts).flatten() print("RBF-train_error", train_errors[best_i, best_j]) print("RBF-test_error", test_errors[best_i, best_j]) print("RBF-rsquare score", rsquare(test_targets, test_predicts)) print('RBF_y_predicts: ', test_predicts[:20], 'rbf_y_originals: ', test_targets[:20]) print( '-----------------------------Polynomial---------------------------------------' ) # Polynomial Basis Function # set input features as 'alcohol' degrees = range(1, 10) train_errors = [] test_errors = [] for degree in degrees: processed_inputs = 0 for i in range(inputs.shape[1]): processed_input = expand_to_monomials(inputs[:, i], degree) processed_inputs += processed_input processed_inputs = np.array(processed_inputs) # split data into train and test set processed_train_inputs, train_targets, processed_test_inputs, test_targets = train_and_test_partition\ (processed_inputs, targets, train_part, test_part) train_error, test_error = train_and_test(processed_train_inputs, train_targets, processed_test_inputs, test_targets, reg_param=None) weights = regularised_least_squares_weights(processed_train_inputs, train_targets, reg_param) train_errors.append(train_error) test_errors.append(test_error) train_errors = np.array(train_errors) test_errors = np.array(test_errors) print("Polynomial-train error: ", train_errors[-1]) print("Polynomial-test error: ", test_errors[-1]) best_d = np.argmin(test_errors) print("Best joint choice of degree:") final_degree = degrees[best_d] print("degree = %.2g" % (final_degree)) fig, ax = plot_train_test_errors("Degree", degrees, train_errors, test_errors) ax.set_xticks(np.arange(min(degrees), max(degrees) + 1, 1.0)) # test functionality with the final degree processed_inputs = 0 for i in range(inputs.shape[1]): processed_input = expand_to_monomials(inputs[:, i], final_degree) processed_inputs += processed_input processed_inputs = np.array(processed_inputs) processed_train_inputs, train_targets, processed_test_inputs, test_targets = train_and_test_partition \ (processed_inputs, targets, train_part, test_part) train_error, test_error = train_and_test(processed_train_inputs, train_targets, processed_test_inputs, test_targets, reg_param=None) weights = regularised_least_squares_weights(processed_train_inputs, train_targets, reg_param) # print("processed_train_inputs.shape", processed_train_inputs.shape) # print('weights: ', weights, 'weights shape: ', weights.shape) test_predicts = prediction_function(processed_test_inputs, weights, final_degree) print("Polynomial-rsquare score", rsquare(test_targets, test_predicts)) print('Polynomial-y_predicts: ', test_predicts[:20], 'Polynomial-y_original: ', test_targets[:20]) plt.show()
def main(): """ This function contains example code that demonstrates how to use the functions defined in poly_fit_base for fitting polynomial curves to data. """ # specify the centres of the rbf basis functions centres = np.linspace(0,1,7) # the width (analogous to standard deviation) of the basis functions scale = 0.15 print("centres = %r" % (centres,)) print("scale = %r" % (scale,)) feature_mapping = construct_rbf_feature_mapping(centres,scale) datamtx = np.linspace(0,1, 51) designmtx = feature_mapping(datamtx) fig = plt.figure() ax = fig.add_subplot(1,1,1) for colid in range(designmtx.shape[1]): ax.plot(datamtx, designmtx[:,colid]) ax.set_xlim([0,1]) ax.set_xticks([0,1]) ax.set_yticks([0,1]) # choose number of data-points and sample a pair of vectors: the input # values and the corresponding target values N = 20 inputs, targets = sample_data(N, arbitrary_function_1, seed=37) # define the feature mapping for the data feature_mapping = construct_rbf_feature_mapping(centres,scale) # now construct the design matrix designmtx = feature_mapping(inputs) # # find the weights that fit the data in a least squares way weights = ml_weights(designmtx, targets) # use weights to create a function that takes inputs and returns predictions # in python, functions can be passed just like any other object # those who know MATLAB might call this a function handle rbf_approx = construct_feature_mapping_approx(feature_mapping, weights) fig, ax, lines = plot_function_data_and_approximation( rbf_approx, inputs, targets, arbitrary_function_1) ax.legend(lines, ['true function', 'data', 'linear approx']) ax.set_xticks([]) ax.set_yticks([]) fig.tight_layout() fig.savefig("regression_rbf.pdf", fmt="pdf") # for a single choice of regularisation strength we can plot the # approximating function reg_param = 10**-3 reg_weights = regularised_ml_weights( designmtx, targets, reg_param) rbf_reg_approx = construct_feature_mapping_approx(feature_mapping, reg_weights) fig, ax, lines = plot_function_data_and_approximation( rbf_reg_approx, inputs, targets, arbitrary_function_1) ax.set_xticks([]) ax.set_yticks([]) fig.tight_layout() fig.savefig("regression_rbf_basis_functions_reg.pdf", fmt="pdf") # to find a good regularisation parameter, we can performa a parameter # search (a naive way to do this is to simply try a sequence of reasonable # values within a reasonable range. # sample some training and testing inputs train_inputs, train_targets = sample_data(N, arbitrary_function_1, seed=37) # we need to use a different seed for our test data, otherwise some of our # sampled points will be the same test_inputs, test_targets = sample_data(100, arbitrary_function_1, seed=82) # convert the raw inputs into feature vectors (construct design matrices) train_designmtx = feature_mapping(train_inputs) test_designmtx = feature_mapping(test_inputs) # now we're going to evaluate train and test error for a sequence of # potential regularisation strengths storing the results reg_params = np.logspace(-5,1) train_errors = [] test_errors = [] for reg_param in reg_params: # evaluate the test and train error for this regularisation parameter train_error, test_error = train_and_test( train_designmtx, train_targets, test_designmtx, test_targets, reg_param=reg_param) # collect the errors train_errors.append(train_error) test_errors.append(test_error) # plot the results fig, ax = plot_train_test_errors( "$\lambda$", reg_params, train_errors, test_errors) ax.set_xscale('log') # we may also be interested in choosing the right number of centres, or # the right width/scale of the rbf functions. # Here we vary the width and evaluate the performance reg_param = 10**-3 scales = np.logspace(-2,0) train_errors = [] test_errors = [] for scale in scales: # we must construct the feature mapping anew for each scale feature_mapping = construct_rbf_feature_mapping(centres,scale) train_designmtx = feature_mapping(train_inputs) test_designmtx = feature_mapping(test_inputs) # evaluate the test and train error for this regularisation parameter train_error, test_error = train_and_test( train_designmtx, train_targets, test_designmtx, test_targets, reg_param=reg_param) # collect the errors train_errors.append(train_error) test_errors.append(test_error) # plot the results fig, ax = plot_train_test_errors( "scale", scales, train_errors, test_errors) ax.set_xscale('log') # Here we vary the number of centres and evaluate the performance reg_param = 10**-3 scale = 0.15 n_centres_seq = np.arange(3,20) train_errors = [] test_errors = [] for n_centres in n_centres_seq: # we must construct the feature mapping anew for each number of centres centres = np.linspace(0,1,n_centres) feature_mapping = construct_rbf_feature_mapping(centres,scale) train_designmtx = feature_mapping(train_inputs) test_designmtx = feature_mapping(test_inputs) # evaluate the test and train error for this regularisation parameter train_error, test_error = train_and_test( train_designmtx, train_targets, test_designmtx, test_targets, reg_param=reg_param) # collect the errors train_errors.append(train_error) test_errors.append(test_error) # plot the results fig, ax = plot_train_test_errors( "Num. Centres", n_centres_seq, train_errors, test_errors) plt.show()
def parameter_search_rbf_without_cross(inputs, targets, test_fraction,test_error_linear,normalize=True): """ """ if(normalize): # normalise inputs (meaning radial basis functions are more helpful) for i in range(inputs.shape[1]): inputs[:,i]=(inputs[:,i]-np.mean(inputs[:,i]))/np.std(inputs[:,i]) N = inputs.shape[0] # for the centres of the basis functions sample 10% of the data sample_fractions = np.array([0.05,0.1,0.15,0.2,0.25]) scales = np.logspace(0,4,20 ) # of the basis functions reg_params = np.logspace(-16,-1, 20) # choices of regularisation strength. # create empty 3d arrays to store the train and test errors train_mean_errors = np.empty((sample_fractions.size,scales.size,reg_params.size)) test_mean_errors = np.empty((sample_fractions.size,scales.size,reg_params.size)) #Randomly generates a train/test split for data of size N. Returns a 2 arrays of boolean true/false. train_part, test_part = train_and_test_split(N, test_fraction=test_fraction) best_k=0 best_i=0 best_j=0 test_error_temp=10**100 #loop through the possible centres as a percentage (5%, 10%,15%, 20%, 25%) for k,sample_fraction in enumerate(sample_fractions): p = (1-sample_fraction,sample_fraction) centres = inputs[np.random.choice([False,True], size=N, p=p),:] # iterate over the scales for i,scale in enumerate(scales): # i is the index, scale is the corresponding scale # we must recreate the feature mapping each time for different scales feature_mapping = construct_rbf_feature_mapping(centres,scale) designmtx = feature_mapping(inputs) # partition the design matrix and targets into train and test. This effectively takes as inputs the boolean arrays train_part, test_part and the whole design matrix and #creates 2 subsets of the design matrix (train matrix, test matrix). The test data are splitted as well but the values are not affected train_designmtx, train_targets, test_designmtx, test_targets = train_and_test_partition(designmtx, targets, train_part, test_part) # iteratre over the regularisation parameters for j, reg_param in enumerate(reg_params): # j is the index, reg_param is the corresponding regularisation # parameter # train and test the data train_error, test_error,weights = train_and_test(train_designmtx, train_targets, test_designmtx, test_targets,reg_param=reg_param) # store the train and test errors in our 2d arrays train_mean_errors[k,i,j] = train_error test_mean_errors[k,i,j] = test_error #When we've found a lowest than stores test error value, we store it's indices if (np.mean(test_error)<test_error_temp): test_error_temp=test_error best_k=k best_i=i best_j=j print ("The value with the lowest error is:",test_mean_errors[best_k][best_i][best_j]) print("Best joint choice of parameters: sample fractions %.2g scale %.2g and lambda = %.2g" % (sample_fractions[best_k],scales[best_i],reg_params[best_j])) # now we can plot the error for different scales using the best # regularization choice # now we can plot the error for different scales using the best regularization choice and centres percentage fig , ax = plot_train_test_errors("scale", scales, train_mean_errors[best_k,:,best_j], test_mean_errors[best_k,:,best_j]) ax.set_xscale('log') fig.suptitle('RBF regression for the best reg. parameter & centres', fontsize=10) xlim = ax.get_xlim()#get the xlim to graph the linear regression ax.plot(xlim, test_error_linear*np.ones(2), 'g:') #graph the linear regression # ...and the error for different regularisation choices given the best scale choice and centres percentage fig , ax = plot_train_test_errors("$\lambda$", reg_params, train_mean_errors[best_k,best_i,:], test_mean_errors[best_k,best_i,:]) ax.set_xscale('log') fig.suptitle('RBF regression for the best scale parameter & centres', fontsize=10) xlim = ax.get_xlim()#get the xlim to graph the linear regression ax.plot(xlim, test_error_linear*np.ones(2), 'g:') # #ax.set_ylim([0,20]) # ...and the error for different centres given the best reg.parameter and the best scale choice fig , ax = plot_train_test_errors("sample fractions", sample_fractions, train_mean_errors[:,best_i,best_j], test_mean_errors[:,best_i,best_j]) fig.suptitle('RBF regression for the best scale parameter & reg. parameter', fontsize=10) ax.set_xlim([0.05, 0.25]) xlim = ax.get_xlim()#get the xlim to graph the linear regression ax.plot(xlim, test_error_linear*np.ones(2), 'g:')