8
8
9
9
/* *
10
10
* @file MultilinearRegression.hpp
11
- * @brief A simple implementation of Multi Linear Regression.
11
+ * @brief A simple implementation of Multilinear Regression with improvements .
12
12
*/
13
13
14
14
/* *
15
- * @class Multilinear Regression
15
+ * @class MultilinearRegression
16
16
* @brief A class that implements Multilinear Regression for predicting values
17
17
* based on multiple features.
18
18
*/
@@ -23,9 +23,10 @@ class MultilinearRegression {
23
23
*
24
24
* @param learningRate The rate at which the model learns (default 0.01).
25
25
* @param iterations The number of iterations for the gradient descent (default 1000).
26
+ * @param regularizationParameter The regularization parameter lambda (default 0.0, no regularization).
26
27
*/
27
- MultilinearRegression (double learningRate = 0.01 , int iterations = 1000 )
28
- : learningRate (learningRate), iterations (iterations) {}
28
+ MultilinearRegression (double learningRate = 0.01 , int iterations = 1000 , double regularizationParameter = 0.0 )
29
+ : learningRate_ (learningRate), iterations_ (iterations), lambda_(regularizationParameter ) {}
29
30
30
31
/* *
31
32
* @brief Trains the Multilinear Regression model on the provided data.
@@ -39,10 +40,23 @@ class MultilinearRegression {
39
40
throw std::invalid_argument (" Features and target data sizes do not match." );
40
41
}
41
42
42
- int numFeatures = features[ 0 ] .size ();
43
- weights. resize ( numFeatures, 0.0 ); // Initialize weights
43
+ size_t numSamples = features.size ();
44
+ size_t numFeatures = features[ 0 ]. size ();
44
45
45
- for (int i = 0 ; i < iterations; ++i) {
46
+ // Validate that all feature vectors have the same size
47
+ for (const auto & feature : features) {
48
+ if (feature.size () != numFeatures) {
49
+ throw std::invalid_argument (" All feature vectors must have the same number of elements." );
50
+ }
51
+ }
52
+
53
+ // Initialize weights and bias if they haven't been initialized yet
54
+ if (weights_.empty ()) {
55
+ weights_.resize (numFeatures, 0.0 );
56
+ bias_ = 0.0 ;
57
+ }
58
+
59
+ for (int iter = 0 ; iter < iterations_; ++iter) {
46
60
gradientDescentStep (features, target);
47
61
}
48
62
}
@@ -54,13 +68,38 @@ class MultilinearRegression {
54
68
* @return The predicted value.
55
69
*/
56
70
double predict (const std::vector<double >& features) const {
57
- return std::inner_product (weights.begin (), weights.end (), features.begin (), 0.0 );
71
+ if (features.size () != weights_.size ()) {
72
+ throw std::invalid_argument (" Feature vector size does not match the number of weights." );
73
+ }
74
+ double result = std::inner_product (weights_.begin (), weights_.end (), features.begin (), 0.0 );
75
+ result += bias_;
76
+ return result;
77
+ }
78
+
79
+ /* *
80
+ * @brief Gets the current weights of the model.
81
+ *
82
+ * @return A vector containing the weights.
83
+ */
84
+ std::vector<double > getWeights () const {
85
+ return weights_;
86
+ }
87
+
88
+ /* *
89
+ * @brief Gets the current bias of the model.
90
+ *
91
+ * @return The bias term.
92
+ */
93
+ double getBias () const {
94
+ return bias_;
58
95
}
59
96
60
97
private:
61
- double learningRate; // /< The learning rate for gradient descent.
62
- int iterations; // /< The number of iterations for training.
63
- std::vector<double > weights; // /< The weights for the model.
98
+ double learningRate_; // /< The learning rate for gradient descent.
99
+ int iterations_; // /< The number of iterations for training.
100
+ double lambda_; // /< Regularization parameter (lambda).
101
+ std::vector<double > weights_; // /< The weights for the model.
102
+ double bias_ = 0.0 ; // /< Bias term.
64
103
65
104
/* *
66
105
* @brief Performs a single iteration of gradient descent to update the model weights.
@@ -69,20 +108,29 @@ class MultilinearRegression {
69
108
* @param target A vector containing the target values.
70
109
*/
71
110
void gradientDescentStep (const std::vector<std::vector<double >>& features, const std::vector<double >& target) {
72
- std::vector<double > gradients (weights.size (), 0.0 );
111
+ size_t numSamples = features.size ();
112
+ size_t numFeatures = weights_.size ();
113
+
114
+ std::vector<double > gradients (numFeatures, 0.0 );
115
+ double biasGradient = 0.0 ;
73
116
74
- for (size_t i = 0 ; i < features. size () ; ++i) {
117
+ for (size_t i = 0 ; i < numSamples ; ++i) {
75
118
double prediction = predict (features[i]);
76
119
double error = prediction - target[i];
77
120
78
- for (size_t j = 0 ; j < weights. size () ; ++j) {
79
- gradients[j] += error * features[i][j];
121
+ for (size_t j = 0 ; j < numFeatures ; ++j) {
122
+ gradients[j] += ( error * features[i][j]) + (lambda_ * weights_[j]) ;
80
123
}
124
+
125
+ biasGradient += error;
81
126
}
82
127
83
- for (size_t j = 0 ; j < weights.size (); ++j) {
84
- weights[j] -= (learningRate / features.size ()) * gradients[j];
128
+ // Update weights and bias
129
+ for (size_t j = 0 ; j < numFeatures; ++j) {
130
+ weights_[j] -= (learningRate_ / numSamples) * gradients[j];
85
131
}
132
+
133
+ bias_ -= (learningRate_ / numSamples) * biasGradient;
86
134
}
87
135
};
88
136
0 commit comments