# R/01-data-preprocessing.R#' Comprehensive feature engineering#'#' @param data Data frame#' @param target_variable Target variable name#' @param preprocessing_config Preprocessing configuration#' @return Preprocessed data and preprocessing objectsfeature_engineering<-function(data,target_variable,preprocessing_config){# Remove target variable from featuresfeature_data<-data[,!names(data)%in%target_variable,drop=FALSE]target_data<-data[[target_variable]]# Handle missing valuesif(preprocessing_config$handle_missing){feature_data<-handle_missing_values(feature_data,preprocessing_config$missing_strategy)}# Encode categorical variablesif(preprocessing_config$encode_categorical){encoding_objects<-encode_categorical_variables(feature_data,preprocessing_config$encoding_method)feature_data<-encoding_objects$encoded_data}# Scale numerical variablesif(preprocessing_config$scale_numerical){scaling_objects<-scale_numerical_variables(feature_data,preprocessing_config$scaling_method)feature_data<-scaling_objects$scaled_data}# Feature selectionif(preprocessing_config$feature_selection){selection_objects<-select_features(feature_data,target_data,preprocessing_config$selection_method)feature_data<-selection_objects$selected_data}# Create feature engineering objectspreprocessing_objects<-list(missing_handling=if(preprocessing_config$handle_missing)encoding_objectselseNULL,encoding=if(preprocessing_config$encode_categorical)encoding_objectselseNULL,scaling=if(preprocessing_config$scale_numerical)scaling_objectselseNULL,selection=if(preprocessing_config$feature_selection)selection_objectselseNULL)return(list(features=feature_data,target=target_data,preprocessing_objects=preprocessing_objects))}#' Handle missing values#'#' @param data Data frame#' @param strategy Missing value handling strategy#' @return Data with handled missing valueshandle_missing_values<-function(data,strategy){if(strategy=="remove"){return(data[complete.cases(data),])}elseif(strategy=="impute_mean"){numeric_cols<-sapply(data,is.numeric)for(colinnames(data)[numeric_cols]){data[[col]][is.na(data[[col]])]<-mean(data[[col]],na.rm=TRUE)}return(data)}elseif(strategy=="impute_median"){numeric_cols<-sapply(data,is.numeric)for(colinnames(data)[numeric_cols]){data[[col]][is.na(data[[col]])]<-median(data[[col]],na.rm=TRUE)}return(data)}elseif(strategy=="impute_mode"){categorical_cols<-sapply(data,function(x)is.character(x)||is.factor(x))for(colinnames(data)[categorical_cols]){mode_value<-names(sort(table(data[[col]]),decreasing=TRUE))[1]data[[col]][is.na(data[[col]])]<-mode_value}return(data)}}#' Encode categorical variables#'#' @param data Data frame#' @param method Encoding method#' @return Encoded data and encoding objectsencode_categorical_variables<-function(data,method="one_hot"){categorical_cols<-sapply(data,function(x)is.character(x)||is.factor(x))if(method=="one_hot"){return(one_hot_encode(data,categorical_cols))}elseif(method=="label"){return(label_encode(data,categorical_cols))}elseif(method=="target"){return(target_encode(data,categorical_cols))}}#' One-hot encoding#'#' @param data Data frame#' @param categorical_cols Categorical column indices#' @return One-hot encoded dataone_hot_encode<-function(data,categorical_cols){encoded_data<-datafor(colinnames(data)[categorical_cols]){# Create dummy variablesdummy_vars<-model.matrix(~.-1,data=data.frame(data[[col]]))colnames(dummy_vars)<-paste0(col,"_",levels(factor(data[[col]])))# Remove original column and add dummy variablesencoded_data<-encoded_data[,!names(encoded_data)%in%col,drop=FALSE]encoded_data<-cbind(encoded_data,dummy_vars)}return(list(encoded_data=encoded_data,encoding_method="one_hot"))}#' Label encoding#'#' @param data Data frame#' @param categorical_cols Categorical column indices#' @return Label encoded datalabel_encode<-function(data,categorical_cols){encoded_data<-dataencoding_maps<-list()for(colinnames(data)[categorical_cols]){unique_values<-unique(data[[col]])encoding_map<-setNames(1:length(unique_values),unique_values)encoded_data[[col]]<-encoding_map[as.character(data[[col]])]encoding_maps[[col]]<-encoding_map}return(list(encoded_data=encoded_data,encoding_maps=encoding_maps,encoding_method="label"))}#' Target encoding#'#' @param data Data frame#' @param categorical_cols Categorical column indices#' @return Target encoded datatarget_encode<-function(data,categorical_cols){# This is a simplified version - in practice, you'd need the target variable# and proper cross-validation to avoid overfittingencoded_data<-datafor(colinnames(data)[categorical_cols]){# Calculate mean target value for each categorycategory_means<-aggregate(data[[col]],by=list(data[[col]]),FUN=mean)encoding_map<-setNames(category_means$x,category_means$Group.1)encoded_data[[col]]<-encoding_map[as.character(data[[col]])]}return(list(encoded_data=encoded_data,encoding_method="target"))}#' Scale numerical variables#'#' @param data Data frame#' @param method Scaling method#' @return Scaled data and scaling objectsscale_numerical_variables<-function(data,method="standardization"){numeric_cols<-sapply(data,is.numeric)scaled_data<-datascaling_params<-list()for(colinnames(data)[numeric_cols]){if(method=="standardization"){mean_val<-mean(data[[col]],na.rm=TRUE)sd_val<-sd(data[[col]],na.rm=TRUE)scaled_data[[col]]<-(data[[col]]-mean_val)/sd_valscaling_params[[col]]<-list(mean=mean_val,sd=sd_val)}elseif(method=="min_max"){min_val<-min(data[[col]],na.rm=TRUE)max_val<-max(data[[col]],na.rm=TRUE)scaled_data[[col]]<-(data[[col]]-min_val)/(max_val-min_val)scaling_params[[col]]<-list(min=min_val,max=max_val)}}return(list(scaled_data=scaled_data,scaling_params=scaling_params,scaling_method=method))}#' Select features#'#' @param data Data frame#' @param target Target variable#' @param method Feature selection method#' @return Selected features and selection objectsselect_features<-function(data,target,method="correlation"){if(method=="correlation"){return(select_features_by_correlation(data,target))}elseif(method=="mutual_information"){return(select_features_by_mutual_information(data,target))}elseif(method=="recursive"){return(select_features_recursively(data,target))}}#' Select features by correlation#'#' @param data Data frame#' @param target Target variable#' @return Selected featuresselect_features_by_correlation<-function(data,target){numeric_cols<-sapply(data,is.numeric)if(sum(numeric_cols)==0)return(data)numeric_data<-data[,numeric_cols,drop=FALSE]correlations<-abs(cor(numeric_data,target,use="complete.obs"))# Select features with correlation > 0.1selected_cols<-rownames(correlations)[correlations>0.1]if(length(selected_cols)==0){return(data)}selected_data<-data[,selected_cols,drop=FALSE]return(list(selected_data=selected_data,selected_features=selected_cols,selection_method="correlation"))}
# R/02-model-training.R#' Comprehensive model training and validation#'#' @param data Preprocessed data#' @param target Target variable#' @param model_config Model configuration#' @return Model training resultstrain_model<-function(data,target,model_config){# Split datadata_split<-split_data(data,target,model_config$split_ratio)# Train modeltrained_model<-fit_model(data_split$train,data_split$train_target,model_config)# Validate modelvalidation_results<-validate_model(trained_model,data_split$test,data_split$test_target)# Cross-validationcv_results<-cross_validate_model(data,target,model_config)# Hyperparameter tuningif(model_config$tune_hyperparameters){tuning_results<-tune_hyperparameters(data,target,model_config)trained_model<-tuning_results$best_model}results<-list(model=trained_model,validation=validation_results,cross_validation=cv_results,tuning=if(model_config$tune_hyperparameters)tuning_resultselseNULL)return(results)}#' Split data into train and test sets#'#' @param data Data frame#' @param target Target variable#' @param split_ratio Train/test split ratio#' @return Data splitsplit_data<-function(data,target,split_ratio=0.8){set.seed(123)n<-nrow(data)train_indices<-sample(1:n,floor(split_ratio*n))return(list(train=data[train_indices,],test=data[-train_indices,],train_target=target[train_indices],test_target=target[-train_indices]))}#' Fit model based on configuration#'#' @param train_data Training data#' @param train_target Training target#' @param model_config Model configuration#' @return Fitted modelfit_model<-function(train_data,train_target,model_config){if(model_config$algorithm=="random_forest"){return(fit_random_forest(train_data,train_target,model_config))}elseif(model_config$algorithm=="gradient_boosting"){return(fit_gradient_boosting(train_data,train_target,model_config))}elseif(model_config$algorithm=="svm"){return(fit_svm(train_data,train_target,model_config))}elseif(model_config$algorithm=="neural_network"){return(fit_neural_network(train_data,train_target,model_config))}}#' Fit random forest model#'#' @param train_data Training data#' @param train_target Training target#' @param model_config Model configuration#' @return Fitted random forest modelfit_random_forest<-function(train_data,train_target,model_config){library(randomForest)model<-randomForest(x=train_data,y=train_target,ntree=model_config$ntree,mtry=model_config$mtry,nodesize=model_config$nodesize,maxnodes=model_config$maxnodes)return(model)}#' Fit gradient boosting model#'#' @param train_data Training data#' @param train_target Training target#' @param model_config Model configuration#' @return Fitted gradient boosting modelfit_gradient_boosting<-function(train_data,train_target,model_config){library(gbm)model<-gbm(formula=train_target~.,data=cbind(train_data,train_target),distribution=model_config$distribution,n.trees=model_config$n_trees,interaction.depth=model_config$interaction_depth,shrinkage=model_config$shrinkage,bag.fraction=model_config$bag_fraction)return(model)}#' Fit SVM model#'#' @param train_data Training data#' @param train_target Training target#' @param model_config Model configuration#' @return Fitted SVM modelfit_svm<-function(train_data,train_target,model_config){library(e1071)model<-svm(x=train_data,y=train_target,kernel=model_config$kernel,cost=model_config$cost,gamma=model_config$gamma,epsilon=model_config$epsilon)return(model)}#' Fit neural network model#'#' @param train_data Training data#' @param train_target Training target#' @param model_config Model configuration#' @return Fitted neural network modelfit_neural_network<-function(train_data,train_target,model_config){library(nnet)model<-nnet(x=train_data,y=train_target,size=model_config$hidden_units,decay=model_config$decay,maxit=model_config$max_iterations,trace=FALSE)return(model)}
# R/02-model-training.R (continued)#' Validate model performance#'#' @param model Fitted model#' @param test_data Test data#' @param test_target Test target#' @return Validation resultsvalidate_model<-function(model,test_data,test_target){# Make predictionspredictions<-predict_model(model,test_data)# Calculate performance metricsperformance_metrics<-calculate_performance_metrics(test_target,predictions)# Create confusion matrix (for classification)if(is.factor(test_target)){confusion_matrix<-table(test_target,predictions)performance_metrics$confusion_matrix<-confusion_matrix}return(list(predictions=predictions,performance_metrics=performance_metrics))}#' Make predictions using model#'#' @param model Fitted model#' @param data Data to predict on#' @return Predictionspredict_model<-function(model,data){if(inherits(model,"randomForest")){return(predict(model,data))}elseif(inherits(model,"gbm")){return(predict(model,data,n.trees=model$n.trees))}elseif(inherits(model,"svm")){return(predict(model,data))}elseif(inherits(model,"nnet")){return(predict(model,data))}}#' Calculate performance metrics#'#' @param actual Actual values#' @param predicted Predicted values#' @return Performance metricscalculate_performance_metrics<-function(actual,predicted){if(is.numeric(actual)){# Regression metricsmse<-mean((actual-predicted)^2)rmse<-sqrt(mse)mae<-mean(abs(actual-predicted))mape<-mean(abs((actual-predicted)/actual))*100r_squared<-1-sum((actual-predicted)^2)/sum((actual-mean(actual))^2)return(list(mse=mse,rmse=rmse,mae=mae,mape=mape,r_squared=r_squared))}else{# Classification metricsaccuracy<-mean(actual==predicted)precision<-calculate_precision(actual,predicted)recall<-calculate_recall(actual,predicted)f1_score<-2*(precision*recall)/(precision+recall)return(list(accuracy=accuracy,precision=precision,recall=recall,f1_score=f1_score))}}#' Calculate precision#'#' @param actual Actual values#' @param predicted Predicted values#' @return Precisioncalculate_precision<-function(actual,predicted){# Calculate precision for each classclasses<-unique(actual)precision_values<-numeric(length(classes))for(iinseq_along(classes)){class<-classes[i]true_positives<-sum(actual==class&predicted==class)false_positives<-sum(actual!=class&predicted==class)if(true_positives+false_positives==0){precision_values[i]<-0}else{precision_values[i]<-true_positives/(true_positives+false_positives)}}return(mean(precision_values))}#' Calculate recall#'#' @param actual Actual values#' @param predicted Predicted values#' @return Recallcalculate_recall<-function(actual,predicted){# Calculate recall for each classclasses<-unique(actual)recall_values<-numeric(length(classes))for(iinseq_along(classes)){class<-classes[i]true_positives<-sum(actual==class&predicted==class)false_negatives<-sum(actual==class&predicted!=class)if(true_positives+false_negatives==0){recall_values[i]<-0}else{recall_values[i]<-true_positives/(true_positives+false_negatives)}}return(mean(recall_values))}#' Cross-validate model#'#' @param data Data frame#' @param target Target variable#' @param model_config Model configuration#' @return Cross-validation resultscross_validate_model<-function(data,target,model_config){set.seed(123)k<-model_config$cv_foldsfolds<-create_cv_folds(nrow(data),k)cv_results<-list()for(iin1:k){train_indices<-unlist(folds[-i])test_indices<-folds[[i]]train_data<-data[train_indices,]test_data<-data[test_indices,]train_target<-target[train_indices]test_target<-target[test_indices]# Train modelmodel<-fit_model(train_data,train_target,model_config)# Validate modelvalidation<-validate_model(model,test_data,test_target)cv_results[[i]]<-validation$performance_metrics}# Aggregate resultsaggregated_results<-aggregate_cv_results(cv_results)return(list(fold_results=cv_results,aggregated_results=aggregated_results))}#' Create cross-validation folds#'#' @param n Number of observations#' @param k Number of folds#' @return List of fold indicescreate_cv_folds<-function(n,k){fold_size<-floor(n/k)remainder<-n%%kfolds<-list()start<-1for(iin1:k){end<-start+fold_size-1if(i<=remainder){end<-end+1}folds[[i]]<-start:endstart<-end+1}return(folds)}#' Aggregate cross-validation results#'#' @param cv_results Cross-validation results#' @return Aggregated resultsaggregate_cv_results<-function(cv_results){# Get metric namesmetric_names<-names(cv_results[[1]])# Calculate mean and standard deviation for each metricaggregated<-list()for(metricinmetric_names){values<-sapply(cv_results,function(x)x[[metric]])aggregated[[paste0(metric,"_mean")]]<-mean(values)aggregated[[paste0(metric,"_sd")]]<-sd(values)}return(aggregated)}
# R/03-hyperparameter-tuning.R#' Comprehensive hyperparameter tuning#'#' @param data Data frame#' @param target Target variable#' @param model_config Model configuration#' @return Hyperparameter tuning resultstune_hyperparameters<-function(data,target,model_config){if(model_config$tuning_method=="grid_search"){return(grid_search_tuning(data,target,model_config))}elseif(model_config$tuning_method=="random_search"){return(random_search_tuning(data,target,model_config))}elseif(model_config$tuning_method=="bayesian"){return(bayesian_tuning(data,target,model_config))}}#' Grid search hyperparameter tuning#'#' @param data Data frame#' @param target Target variable#' @param model_config Model configuration#' @return Grid search resultsgrid_search_tuning<-function(data,target,model_config){# Create parameter gridparam_grid<-create_parameter_grid(model_config$hyperparameters)# Perform grid searchgrid_results<-perform_grid_search(data,target,param_grid,model_config)# Find best parametersbest_params<-find_best_parameters(grid_results)# Train final model with best parametersbest_model_config<-update_model_config(model_config,best_params)best_model<-fit_model(data,target,best_model_config)return(list(grid_results=grid_results,best_parameters=best_params,best_model=best_model))}#' Create parameter grid#'#' @param hyperparameters Hyperparameter specifications#' @return Parameter gridcreate_parameter_grid<-function(hyperparameters){param_names<-names(hyperparameters)param_values<-lapply(hyperparameters,function(x)x$values)# Create all combinationsparam_grid<-expand.grid(param_values,stringsAsFactors=FALSE)names(param_grid)<-param_namesreturn(param_grid)}#' Perform grid search#'#' @param data Data frame#' @param target Target variable#' @param param_grid Parameter grid#' @param model_config Model configuration#' @return Grid search resultsperform_grid_search<-function(data,target,param_grid,model_config){results<-list()for(iin1:nrow(param_grid)){params<-param_grid[i,]# Update model configuration with current parameterscurrent_config<-update_model_config(model_config,params)# Perform cross-validationcv_results<-cross_validate_model(data,target,current_config)# Store resultsresults[[i]]<-list(parameters=params,cv_results=cv_results$aggregated_results)}return(results)}#' Update model configuration with parameters#'#' @param model_config Model configuration#' @param parameters Parameters to update#' @return Updated model configurationupdate_model_config<-function(model_config,parameters){updated_config<-model_configfor(param_nameinnames(parameters)){updated_config[[param_name]]<-parameters[[param_name]]}return(updated_config)}#' Find best parameters#'#' @param grid_results Grid search results#' @return Best parametersfind_best_parameters<-function(grid_results){# Extract performance metricsperformance_metrics<-lapply(grid_results,function(x)x$cv_results)# Find best parameters based on primary metricbest_idx<-which.max(sapply(performance_metrics,function(x)x$accuracy_mean))return(grid_results[[best_idx]]$parameters)}
# R/03-hyperparameter-tuning.R (continued)#' Random search hyperparameter tuning#'#' @param data Data frame#' @param target Target variable#' @param model_config Model configuration#' @return Random search resultsrandom_search_tuning<-function(data,target,model_config){n_iterations<-model_config$n_iterationshyperparameters<-model_config$hyperparametersresults<-list()for(iin1:n_iterations){# Sample random parametersparams<-sample_parameters(hyperparameters)# Update model configurationcurrent_config<-update_model_config(model_config,params)# Perform cross-validationcv_results<-cross_validate_model(data,target,current_config)# Store resultsresults[[i]]<-list(parameters=params,cv_results=cv_results$aggregated_results)}# Find best parametersbest_params<-find_best_parameters(results)# Train final modelbest_model_config<-update_model_config(model_config,best_params)best_model<-fit_model(data,target,best_model_config)return(list(search_results=results,best_parameters=best_params,best_model=best_model))}#' Sample random parameters#'#' @param hyperparameters Hyperparameter specifications#' @return Sampled parameterssample_parameters<-function(hyperparameters){sampled_params<-list()for(param_nameinnames(hyperparameters)){param_spec<-hyperparameters[[param_name]]if(param_spec$type=="categorical"){sampled_params[[param_name]]<-sample(param_spec$values,1)}elseif(param_spec$type=="integer"){sampled_params[[param_name]]<-sample(param_spec$values,1)}elseif(param_spec$type=="float"){min_val<-param_spec$minmax_val<-param_spec$maxsampled_params[[param_name]]<-runif(1,min_val,max_val)}}return(sampled_params)}
# R/04-model-deployment.R#' Serialize model for deployment#'#' @param model Fitted model#' @param preprocessing_objects Preprocessing objects#' @param model_metadata Model metadata#' @return Serialized modelserialize_model<-function(model,preprocessing_objects,model_metadata){# Create model packagemodel_package<-list(model=model,preprocessing_objects=preprocessing_objects,metadata=model_metadata,timestamp=Sys.time(),version="1.0.0")# Serialize modelserialized_model<-serialize(model_package,NULL)return(serialized_model)}#' Save model to file#'#' @param model Fitted model#' @param preprocessing_objects Preprocessing objects#' @param model_metadata Model metadata#' @param file_path File path to save modelsave_model<-function(model,preprocessing_objects,model_metadata,file_path){# Serialize modelserialized_model<-serialize_model(model,preprocessing_objects,model_metadata)# Save to filewriteBin(serialized_model,file_path)return(file_path)}#' Load model from file#'#' @param file_path File path to load model from#' @return Loaded modelload_model<-function(file_path){# Read serialized modelserialized_model<-readBin(file_path,"raw",file.info(file_path)$size)# Deserialize modelmodel_package<-unserialize(serialized_model)return(model_package)}#' Make predictions with deployed model#'#' @param model_package Model package#' @param new_data New data for prediction#' @return Predictionspredict_with_deployed_model<-function(model_package,new_data){# Apply preprocessingpreprocessed_data<-apply_preprocessing(new_data,model_package$preprocessing_objects)# Make predictionspredictions<-predict_model(model_package$model,preprocessed_data)return(predictions)}#' Apply preprocessing to new data#'#' @param data New data#' @param preprocessing_objects Preprocessing objects#' @return Preprocessed dataapply_preprocessing<-function(data,preprocessing_objects){preprocessed_data<-data# Apply missing value handlingif(!is.null(preprocessing_objects$missing_handling)){preprocessed_data<-handle_missing_values(preprocessed_data,preprocessing_objects$missing_handling$strategy)}# Apply encodingif(!is.null(preprocessing_objects$encoding)){preprocessed_data<-apply_encoding(preprocessed_data,preprocessing_objects$encoding)}# Apply scalingif(!is.null(preprocessing_objects$scaling)){preprocessed_data<-apply_scaling(preprocessed_data,preprocessing_objects$scaling)}# Apply feature selectionif(!is.null(preprocessing_objects$selection)){preprocessed_data<-preprocessed_data[,preprocessing_objects$selection$selected_features,drop=FALSE]}return(preprocessed_data)}
# 1. Data preprocessingpreprocessed_data<-feature_engineering(data,"target",preprocessing_config)# 2. Model trainingmodel_results<-train_model(preprocessed_data$features,preprocessed_data$target,model_config)# 3. Hyperparameter tuningtuning_results<-tune_hyperparameters(data,target,model_config)# 4. Model deploymentsave_model(model_results$model,preprocessed_data$preprocessing_objects,model_metadata,"model.rds")# 5. Make predictionsloaded_model<-load_model("model.rds")predictions<-predict_with_deployed_model(loaded_model,new_data)