39 :
C(C_), learning_rate(l_rate), max_iterations(max_iters), tolerance(tol) {
43 const std::vector<int> &y_train) {
45 weights.resize(X_train[0].size(), 0.0);
49 for (
int iter = 0; iter < max_iterations; ++iter) {
50 update_weights(X_train, y_train);
53 double loss = compute_loss(X_train, y_train);
54 if (loss < tolerance) {
62 std::vector<int> predictions;
63 for (
const auto &instance : X_test) {
65 for (
size_t i = 0; i < instance.size(); ++i) {
66 score += instance[i] * weights[i];
69 int prediction = (score >= 0) ? 1 : -1;
70 predictions.push_back(prediction);
76 return fmax(0, 1 - label * prediction);
80 const std::vector<int> &y) {
82 for (
size_t i = 0; i < X.size(); ++i) {
83 double prediction = 0.0;
84 for (
size_t j = 0; j < X[i].size(); ++j) {
85 prediction += X[i][j] * weights[j];
88 loss += hinge_loss(prediction, y[i]);
91 for (
double weight : weights) {
92 loss += 0.5 *
C * weight * weight;
94 return loss / X.size();
98 const std::vector<int> &y) {
99 for (
size_t i = 0; i < X.size(); ++i) {
100 double prediction = 0.0;
101 for (
size_t j = 0; j < X[i].size(); ++j) {
102 prediction += X[i][j] * weights[j];
105 double loss_grad = -y[i] * (1 - prediction);
108 for (
size_t j = 0; j < X[i].size(); ++j) {
109 weights[j] -= learning_rate * (
C * weights[j] - y[i] * X[i][j]);
112 bias -= learning_rate * y[i];
119 std::vector<double> probabilities;
120 for (
const auto &instance : X_test) {
122 for (
size_t i = 0; i < instance.size(); ++i) {
123 score += instance[i] * weights[i];
126 double prob = sigmoid(score);
127 probabilities.push_back(prob);
129 return probabilities;
133 const std::vector<int> &y_test) {
134 std::vector<int> predictions = predict(X_test);
135 return accuracy(predictions, y_test);
139 this->kernel_type = k_type;
143 this->kernel_param = k_param;
147 this->random_state = seed;
151 this->verbose = vbose;
155 this->penalty_type = p_type;
159 const std::vector<int> &y,
161 std::vector<int> fold_sizes = k_fold_indices(X.size(), cv);
162 double avg_score = 0.0;
163 for (
int i = 0; i < cv; ++i) {
164 std::vector<std::vector<double>> X_train, X_valid;
165 std::vector<int> y_train, y_valid;
167 for (
int j = 0; j < cv; ++j) {
169 int end = start + fold_sizes[j];
170 for (
int k = start; k < end; ++k) {
171 X_train.push_back(X[k]);
172 y_train.push_back(y[k]);
175 int end = start + fold_sizes[j];
176 for (
int k = start; k < end; ++k) {
177 X_valid.push_back(X[k]);
178 y_valid.push_back(y[k]);
181 start += fold_sizes[j];
183 fit(X_train, y_train);
184 double score_val = score(X_valid, y_valid);
186 std::cout <<
"Cross-validation fold " << i + 1
187 <<
" accuracy: " << score_val << std::endl;
189 avg_score += score_val;
191 return avg_score / cv;
196 const std::vector<int> &y,
197 const std::vector<double> &C_values,
198 const std::vector<double> &kernel_params,
200 std::vector<double> best_params;
201 double best_score = 0.0;
202 for (
double val : C_values) {
203 for (
double param : kernel_params) {
204 set_kernel_parameters(param);
207 double score = cross_val_score(X, y, cv);
208 if (score > best_score) {
210 best_params = {val, param};
218 const std::vector<double> &x2) {
219 if (kernel_type ==
"linear") {
228 const std::vector<double> &x2) {
230 for (
size_t i = 0; i < x1.size(); ++i) {
231 result += x1[i] * x2[i];
237 return 1.0 / (1.0 + exp(-z));
241 std::vector<int> fold_sizes(k, num_instances / k);
242 int remainder = num_instances % k;
243 for (
int i = 0; i < remainder; ++i) {
250 const std::vector<int> &labels) {
252 for (
size_t i = 0; i < predictions.size(); ++i) {
253 if (predictions[i] == labels[i]) {
257 return static_cast<double>(correct) / predictions.size();
void set_random_state(int seed)
Set the random seed for reproducibility.
double dot_product(const std::vector< double > &x1, const std::vector< double > &x2)
Compute the dot product between two vectors.
SVC(double C_=1.0, double l_rate=0.01, int max_iters=1000, double tol=1e-4)
Constructor for SVC class.
void set_verbose(bool vbose)
Enable or disable verbose output during training.
void set_kernel(const std::string &k_type)
Set the kernel type for the SVC.
double score(const std::vector< std::vector< double >> &X_test, const std::vector< int > &y_test)
Calculate the accuracy of the model on given test data.
std::vector< double > predict_proba(const std::vector< std::vector< double >> &X_test)
Predict class probabilities for given test data.
void update_weights(const std::vector< std::vector< double >> &X, const std::vector< int > &y)
Update weights and bias using stochastic gradient descent.
std::vector< int > k_fold_indices(int num_instances, int k)
Generate k-fold indices for cross-validation.
double sigmoid(double z)
Sigmoid activation function.
void fit(const std::vector< std::vector< double >> &X_train, const std::vector< int > &y_train)
Fit the SVC model to the training data.
double cross_val_score(const std::vector< std::vector< double >> &X, const std::vector< int > &y, int cv=5)
Perform k-fold cross-validation on the model.
void set_kernel_parameters(double k_param)
Set the kernel parameters for the SVC.
void set_penalty(const std::string &p_type)
Set the penalty type for regularization.
double kernel(const std::vector< double > &x1, const std::vector< double > &x2)
Compute the kernel function between two vectors.
double hinge_loss(double prediction, int label)
Compute the hinge loss for a given prediction and true label.
double accuracy(const std::vector< int > &predictions, const std::vector< int > &labels)
Compute the accuracy of predictions.
std::vector< double > grid_search(const std::vector< std::vector< double >> &X, const std::vector< int > &y, const std::vector< double > &C_values, const std::vector< double > &kernel_params, int cv=5)
Perform grid search for hyperparameter tuning.
std::vector< int > predict(const std::vector< std::vector< double >> &X_test)
Predict labels for given test data.
double compute_loss(const std::vector< std::vector< double >> &X, const std::vector< int > &y)
Compute the total loss (including regularization) for the model.
int dot_product(const std::vector< int8_t > &vec1, const std::vector< int8_t > &vec2)
Computes the dot product for vectors of signed 8-bit integers.