diff --git a/Algorithms.Tests/MachineLearning/LinearRegressionTests.cs b/Algorithms.Tests/MachineLearning/LinearRegressionTests.cs
new file mode 100644
index 00000000..c43fc41b
--- /dev/null
+++ b/Algorithms.Tests/MachineLearning/LinearRegressionTests.cs
@@ -0,0 +1,85 @@
+using Algorithms.MachineLearning;
+
+namespace Algorithms.Tests.MachineLearning;
+
+///
+/// Unit tests for the LinearRegression class.
+///
+public class LinearRegressionTests
+{
+ [Test]
+ public void Fit_ThrowsException_WhenInputIsNull()
+ {
+ var lr = new LinearRegression();
+ Assert.Throws(() => lr.Fit(null!, new List { 1 }));
+ Assert.Throws(() => lr.Fit(new List { 1 }, null!));
+ }
+
+ [Test]
+ public void Fit_ThrowsException_WhenInputIsEmpty()
+ {
+ var lr = new LinearRegression();
+ Assert.Throws(() => lr.Fit(new List(), new List()));
+ }
+
+ [Test]
+ public void Fit_ThrowsException_WhenInputLengthsDiffer()
+ {
+ var lr = new LinearRegression();
+ Assert.Throws(() => lr.Fit(new List { 1 }, new List { 2, 3 }));
+ }
+
+ [Test]
+ public void Fit_ThrowsException_WhenXVarianceIsZero()
+ {
+ var lr = new LinearRegression();
+ Assert.Throws(() => lr.Fit(new List { 1, 1, 1 }, new List { 2, 3, 4 }));
+ }
+
+ [Test]
+ public void Predict_ThrowsException_IfNotFitted()
+ {
+ var lr = new LinearRegression();
+ Assert.Throws(() => lr.Predict(1.0));
+ Assert.Throws(() => lr.Predict(new List { 1.0 }));
+ }
+
+ [Test]
+ public void FitAndPredict_WorksForSimpleData()
+ {
+ // y = 2x + 1
+ var x = new List { 1, 2, 3, 4 };
+ var y = new List { 3, 5, 7, 9 };
+ var lr = new LinearRegression();
+ lr.Fit(x, y);
+ Assert.That(lr.IsFitted, Is.True);
+ Assert.That(lr.Intercept, Is.EqualTo(1.0).Within(1e-6));
+ Assert.That(lr.Slope, Is.EqualTo(2.0).Within(1e-6));
+ Assert.That(lr.Predict(5), Is.EqualTo(11.0).Within(1e-6));
+ }
+
+ [Test]
+ public void FitAndPredict_WorksForNegativeSlope()
+ {
+ // y = -3x + 4
+ var x = new List { 0, 1, 2 };
+ var y = new List { 4, 1, -2 };
+ var lr = new LinearRegression();
+ lr.Fit(x, y);
+ Assert.That(lr.Intercept, Is.EqualTo(4.0).Within(1e-6));
+ Assert.That(lr.Slope, Is.EqualTo(-3.0).Within(1e-6));
+ Assert.That(lr.Predict(3), Is.EqualTo(-5.0).Within(1e-6));
+ }
+
+ [Test]
+ public void Predict_List_WorksCorrectly()
+ {
+ var x = new List { 1, 2, 3 };
+ var y = new List { 2, 4, 6 };
+ var lr = new LinearRegression();
+ lr.Fit(x, y); // y = 2x
+ var predictions = lr.Predict(new List { 4, 5 });
+ Assert.That(predictions[0], Is.EqualTo(8.0).Within(1e-6));
+ Assert.That(predictions[1], Is.EqualTo(10.0).Within(1e-6));
+ }
+}
diff --git a/Algorithms/MachineLearning/LinearRegression.cs b/Algorithms/MachineLearning/LinearRegression.cs
new file mode 100644
index 00000000..4e586376
--- /dev/null
+++ b/Algorithms/MachineLearning/LinearRegression.cs
@@ -0,0 +1,100 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Algorithms.MachineLearning;
+
+///
+/// Implements simple linear regression for one independent variable (univariate).
+/// Linear regression is a supervised learning algorithm used to model the relationship
+/// between a scalar dependent variable (Y) and an independent variable (X).
+/// The model fits a line: Y = a + bX, where 'a' is the intercept and 'b' is the slope.
+///
+public class LinearRegression
+{
+ // Intercept (a) and slope (b) of the fitted line
+ public double Intercept { get; private set; }
+
+ public double Slope { get; private set; }
+
+ public bool IsFitted { get; private set; }
+
+ ///
+ /// Fits the linear regression model to the provided data.
+ ///
+ /// List of independent variable values.
+ /// List of dependent variable values.
+ /// Thrown if input lists are null, empty, or of different lengths.
+ public void Fit(IList x, IList y)
+ {
+ if (x == null || y == null)
+ {
+ throw new ArgumentException("Input data cannot be null.");
+ }
+
+ if (x.Count == 0 || y.Count == 0)
+ {
+ throw new ArgumentException("Input data cannot be empty.");
+ }
+
+ if (x.Count != y.Count)
+ {
+ throw new ArgumentException("Input lists must have the same length.");
+ }
+
+ // Calculate means
+ double xMean = x.Average();
+ double yMean = y.Average();
+
+ // Calculate slope (b) and intercept (a)
+ double numerator = 0.0;
+ double denominator = 0.0;
+ for (int i = 0; i < x.Count; i++)
+ {
+ numerator += (x[i] - xMean) * (y[i] - yMean);
+ denominator += (x[i] - xMean) * (x[i] - xMean);
+ }
+
+ const double epsilon = 1e-12;
+ if (Math.Abs(denominator) < epsilon)
+ {
+ throw new ArgumentException("Variance of X must not be zero.");
+ }
+
+ Slope = numerator / denominator;
+ Intercept = yMean - Slope * xMean;
+ IsFitted = true;
+ }
+
+ ///
+ /// Predicts the output value for a given input using the fitted model.
+ ///
+ /// Input value.
+ /// Predicted output value.
+ /// Thrown if the model is not fitted.
+ public double Predict(double x)
+ {
+ if (!IsFitted)
+ {
+ throw new InvalidOperationException("Model must be fitted before prediction.");
+ }
+
+ return Intercept + Slope * x;
+ }
+
+ ///
+ /// Predicts output values for a list of inputs using the fitted model.
+ ///
+ /// List of input values.
+ /// List of predicted output values.
+ /// Thrown if the model is not fitted.
+ public IList Predict(IList xValues)
+ {
+ if (!IsFitted)
+ {
+ throw new InvalidOperationException("Model must be fitted before prediction.");
+ }
+
+ return xValues.Select(Predict).ToList();
+ }
+}
diff --git a/README.md b/README.md
index cb1358d0..37165565 100644
--- a/README.md
+++ b/README.md
@@ -106,6 +106,8 @@ find more than one implementation for the same objective but using different alg
* [SoftMax Function](./Algorithms/Numeric/SoftMax.cs)
* [RecommenderSystem](./Algorithms/RecommenderSystem)
* [CollaborativeFiltering](./Algorithms/RecommenderSystem/CollaborativeFiltering)
+ * [Machine Learning](./Algorithms/MachineLearning)
+ * [Linear Regression](./Algorithms/MachineLearning/LinearRegression.cs)
* [Searches](./Algorithms/Search)
* [A-Star](./Algorithms/Search/AStar/)
* [Binary Search](./Algorithms/Search/BinarySearcher.cs)