linesight 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- linesight-0.1.0/LICENSE +21 -0
- linesight-0.1.0/PKG-INFO +160 -0
- linesight-0.1.0/README.md +127 -0
- linesight-0.1.0/linesight/__init__.py +19 -0
- linesight-0.1.0/linesight/base.py +195 -0
- linesight-0.1.0/linesight/exceptions/__init__.py +13 -0
- linesight-0.1.0/linesight/exceptions/convergence_warning.py +9 -0
- linesight-0.1.0/linesight/exceptions/data_warning.py +6 -0
- linesight-0.1.0/linesight/exceptions/gradient_error.py +5 -0
- linesight-0.1.0/linesight/exceptions/not_fitted_error.py +13 -0
- linesight-0.1.0/linesight/exceptions/shape_error.py +18 -0
- linesight-0.1.0/linesight/metrics/__init__.py +5 -0
- linesight-0.1.0/linesight/metrics/accuracy.py +9 -0
- linesight-0.1.0/linesight/metrics/mae.py +5 -0
- linesight-0.1.0/linesight/metrics/mse.py +5 -0
- linesight-0.1.0/linesight/metrics/r2.py +20 -0
- linesight-0.1.0/linesight/metrics/rmse.py +6 -0
- linesight-0.1.0/linesight/regression/__init__.py +6 -0
- linesight-0.1.0/linesight/regression/elasticnet/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/elasticnet/core.py +103 -0
- linesight-0.1.0/linesight/regression/elasticnet/engine/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/elasticnet/engine/compute_loss.py +8 -0
- linesight-0.1.0/linesight/regression/elasticnet/engine/fit.py +72 -0
- linesight-0.1.0/linesight/regression/elasticnet/engine/get_history.py +9 -0
- linesight-0.1.0/linesight/regression/elasticnet/engine/predict.py +9 -0
- linesight-0.1.0/linesight/regression/elasticnet/engine/score.py +13 -0
- linesight-0.1.0/linesight/regression/elasticnet/engine/soft_threshold.py +8 -0
- linesight-0.1.0/linesight/regression/elasticnet/explain/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/elasticnet/explain/explain_coefficients.py +29 -0
- linesight-0.1.0/linesight/regression/elasticnet/explain/explain_regularization.py +33 -0
- linesight-0.1.0/linesight/regression/elasticnet/visualization/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/elasticnet/visualization/animate_l1_ratio_sweep.py +102 -0
- linesight-0.1.0/linesight/regression/elasticnet/visualization/compare_regularization_methods.py +100 -0
- linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_actual_vs_predicted.py +69 -0
- linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_coefficient_shrinkage.py +43 -0
- linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_fit.py +36 -0
- linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_l1_l2_balance.py +113 -0
- linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_learning_curve.py +127 -0
- linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_loss_curve.py +27 -0
- linesight-0.1.0/linesight/regression/lasso/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/lasso/core.py +105 -0
- linesight-0.1.0/linesight/regression/lasso/engine/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/lasso/engine/compute_loss.py +7 -0
- linesight-0.1.0/linesight/regression/lasso/engine/fit.py +71 -0
- linesight-0.1.0/linesight/regression/lasso/engine/get_history.py +9 -0
- linesight-0.1.0/linesight/regression/lasso/engine/predict.py +9 -0
- linesight-0.1.0/linesight/regression/lasso/engine/score.py +13 -0
- linesight-0.1.0/linesight/regression/lasso/engine/soft_threshold.py +29 -0
- linesight-0.1.0/linesight/regression/lasso/explain/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/lasso/explain/explain_coefficients.py +30 -0
- linesight-0.1.0/linesight/regression/lasso/explain/explain_regularization.py +30 -0
- linesight-0.1.0/linesight/regression/lasso/explain/explain_sparsity.py +36 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/animate_coordinate_descent.py +104 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/compare_with_linear.py +49 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/plot_actual_vs_predicted.py +69 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/plot_coefficient_shrinkage.py +44 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/plot_constraint_region.py +92 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/plot_feature_elimination.py +88 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/plot_fit.py +37 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/plot_learning_curve.py +127 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/plot_loss_curve.py +28 -0
- linesight-0.1.0/linesight/regression/lasso/visualization/plot_sparsity_path.py +126 -0
- linesight-0.1.0/linesight/regression/linear/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/linear/core.py +134 -0
- linesight-0.1.0/linesight/regression/linear/engine/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/linear/engine/compute_loss.py +23 -0
- linesight-0.1.0/linesight/regression/linear/engine/fit.py +59 -0
- linesight-0.1.0/linesight/regression/linear/engine/get_history.py +31 -0
- linesight-0.1.0/linesight/regression/linear/engine/gradient_step.py +42 -0
- linesight-0.1.0/linesight/regression/linear/engine/predict.py +25 -0
- linesight-0.1.0/linesight/regression/linear/engine/score.py +38 -0
- linesight-0.1.0/linesight/regression/linear/explain/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/linear/explain/explain_coefficients.py +39 -0
- linesight-0.1.0/linesight/regression/linear/explain/explain_fit.py +66 -0
- linesight-0.1.0/linesight/regression/linear/explain/show_equation.py +25 -0
- linesight-0.1.0/linesight/regression/linear/visualization/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/linear/visualization/animate_loss_surface_path.py +157 -0
- linesight-0.1.0/linesight/regression/linear/visualization/animate_training.py +109 -0
- linesight-0.1.0/linesight/regression/linear/visualization/compare_learning_rates.py +97 -0
- linesight-0.1.0/linesight/regression/linear/visualization/plot_actual_vs_predicted.py +69 -0
- linesight-0.1.0/linesight/regression/linear/visualization/plot_fit.py +103 -0
- linesight-0.1.0/linesight/regression/linear/visualization/plot_gradient_vectors.py +145 -0
- linesight-0.1.0/linesight/regression/linear/visualization/plot_learning_curve.py +126 -0
- linesight-0.1.0/linesight/regression/linear/visualization/plot_loss_curve.py +78 -0
- linesight-0.1.0/linesight/regression/linear/visualization/plot_loss_surface.py +135 -0
- linesight-0.1.0/linesight/regression/linear/visualization/plot_prediction_intervals.py +190 -0
- linesight-0.1.0/linesight/regression/linear/visualization/plot_residuals.py +74 -0
- linesight-0.1.0/linesight/regression/linear/visualization/plot_sensitivity_analysis.py +195 -0
- linesight-0.1.0/linesight/regression/logistic/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/logistic/core.py +114 -0
- linesight-0.1.0/linesight/regression/logistic/engine/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/logistic/engine/compute_loss.py +8 -0
- linesight-0.1.0/linesight/regression/logistic/engine/fit.py +88 -0
- linesight-0.1.0/linesight/regression/logistic/engine/get_history.py +8 -0
- linesight-0.1.0/linesight/regression/logistic/engine/gradient_step.py +21 -0
- linesight-0.1.0/linesight/regression/logistic/engine/predict.py +9 -0
- linesight-0.1.0/linesight/regression/logistic/engine/predict_proba.py +12 -0
- linesight-0.1.0/linesight/regression/logistic/engine/score.py +12 -0
- linesight-0.1.0/linesight/regression/logistic/engine/sigmoid.py +32 -0
- linesight-0.1.0/linesight/regression/logistic/explain/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/logistic/explain/explain_boundary.py +23 -0
- linesight-0.1.0/linesight/regression/logistic/explain/explain_coefficients.py +27 -0
- linesight-0.1.0/linesight/regression/logistic/explain/explain_sigmoid.py +21 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/animate_boundary.py +87 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_actual_vs_predicted.py +69 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_calibration_curve.py +138 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_confusion_matrix.py +105 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_decision_boundary.py +106 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_learning_curve.py +126 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_log_odds.py +129 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_loss_curve.py +27 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_probability_surface.py +37 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_residuals.py +30 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_roc_curve.py +118 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_sigmoid.py +32 -0
- linesight-0.1.0/linesight/regression/logistic/visualization/plot_threshold_sensitivity.py +80 -0
- linesight-0.1.0/linesight/regression/multiple/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/multiple/core.py +103 -0
- linesight-0.1.0/linesight/regression/multiple/engine/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/multiple/engine/compute_loss.py +5 -0
- linesight-0.1.0/linesight/regression/multiple/engine/fit.py +87 -0
- linesight-0.1.0/linesight/regression/multiple/engine/get_history.py +13 -0
- linesight-0.1.0/linesight/regression/multiple/engine/gradient_step.py +23 -0
- linesight-0.1.0/linesight/regression/multiple/engine/predict.py +11 -0
- linesight-0.1.0/linesight/regression/multiple/engine/score.py +17 -0
- linesight-0.1.0/linesight/regression/multiple/explain/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/multiple/explain/explain_coefficients.py +29 -0
- linesight-0.1.0/linesight/regression/multiple/explain/show_equation.py +14 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/plot_3d_loss_slice.py +113 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/plot_actual_vs_predicted.py +69 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/plot_correlation_matrix.py +35 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/plot_feature_importance.py +59 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/plot_fit.py +62 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/plot_learning_curve.py +126 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/plot_multicollinearity.py +180 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/plot_partial_regression.py +67 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/plot_prediction_plane.py +42 -0
- linesight-0.1.0/linesight/regression/multiple/visualization/plot_residual_heatmap.py +87 -0
- linesight-0.1.0/linesight/regression/polynomial/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/polynomial/core.py +93 -0
- linesight-0.1.0/linesight/regression/polynomial/engine/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/polynomial/engine/expand_features.py +30 -0
- linesight-0.1.0/linesight/regression/polynomial/engine/fit.py +117 -0
- linesight-0.1.0/linesight/regression/polynomial/engine/predict.py +14 -0
- linesight-0.1.0/linesight/regression/polynomial/explain/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/polynomial/explain/show_equation.py +29 -0
- linesight-0.1.0/linesight/regression/polynomial/visualization/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/polynomial/visualization/animate_degree_increase.py +88 -0
- linesight-0.1.0/linesight/regression/polynomial/visualization/compare_degrees.py +110 -0
- linesight-0.1.0/linesight/regression/polynomial/visualization/plot_actual_vs_predicted.py +69 -0
- linesight-0.1.0/linesight/regression/polynomial/visualization/plot_basis_functions.py +138 -0
- linesight-0.1.0/linesight/regression/polynomial/visualization/plot_fit.py +59 -0
- linesight-0.1.0/linesight/regression/polynomial/visualization/plot_learning_curve.py +126 -0
- linesight-0.1.0/linesight/regression/ridge/__init__.py +1 -0
- linesight-0.1.0/linesight/regression/ridge/core.py +109 -0
- linesight-0.1.0/linesight/regression/ridge/engine/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/ridge/engine/compute_loss.py +7 -0
- linesight-0.1.0/linesight/regression/ridge/engine/fit.py +87 -0
- linesight-0.1.0/linesight/regression/ridge/engine/get_history.py +9 -0
- linesight-0.1.0/linesight/regression/ridge/engine/gradient_step.py +28 -0
- linesight-0.1.0/linesight/regression/ridge/engine/predict.py +11 -0
- linesight-0.1.0/linesight/regression/ridge/engine/score.py +13 -0
- linesight-0.1.0/linesight/regression/ridge/explain/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/ridge/explain/explain_coefficients.py +32 -0
- linesight-0.1.0/linesight/regression/ridge/explain/explain_regularization.py +38 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/__init__.py +0 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/animate_regularization.py +100 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/compare_with_linear.py +58 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/plot_actual_vs_predicted.py +69 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/plot_bias_variance_tradeoff.py +110 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/plot_coefficient_shrinkage.py +75 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/plot_constraint_region.py +90 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/plot_effective_degrees_of_freedom.py +117 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/plot_fit.py +38 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/plot_learning_curve.py +126 -0
- linesight-0.1.0/linesight/regression/ridge/visualization/plot_loss_curve.py +30 -0
- linesight-0.1.0/linesight/utils/__init__.py +13 -0
- linesight-0.1.0/linesight/utils/array_utils.py +23 -0
- linesight-0.1.0/linesight/utils/colors.py +43 -0
- linesight-0.1.0/linesight/utils/environment.py +28 -0
- linesight-0.1.0/linesight/utils/history.py +16 -0
- linesight-0.1.0/linesight/utils/validators.py +70 -0
- linesight-0.1.0/linesight/utils/viz_context.py +51 -0
- linesight-0.1.0/linesight.egg-info/PKG-INFO +160 -0
- linesight-0.1.0/linesight.egg-info/SOURCES.txt +202 -0
- linesight-0.1.0/linesight.egg-info/dependency_links.txt +1 -0
- linesight-0.1.0/linesight.egg-info/requires.txt +6 -0
- linesight-0.1.0/linesight.egg-info/top_level.txt +1 -0
- linesight-0.1.0/pyproject.toml +49 -0
- linesight-0.1.0/setup.cfg +4 -0
- linesight-0.1.0/setup.py +35 -0
- linesight-0.1.0/tests/test_elasticnet_engine.py +43 -0
- linesight-0.1.0/tests/test_history.py +60 -0
- linesight-0.1.0/tests/test_lasso_engine.py +79 -0
- linesight-0.1.0/tests/test_linear_engine.py +268 -0
- linesight-0.1.0/tests/test_logistic_engine.py +95 -0
- linesight-0.1.0/tests/test_metrics.py +77 -0
- linesight-0.1.0/tests/test_multiple_engine.py +102 -0
- linesight-0.1.0/tests/test_polynomial_engine.py +40 -0
- linesight-0.1.0/tests/test_ridge_engine.py +76 -0
- linesight-0.1.0/tests/test_validators.py +137 -0
linesight-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 LineSight Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
linesight-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: linesight
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Educational regression library with tutor-style explanations and visualizations
|
|
5
|
+
Home-page: https://github.com/AnshumanTiwari2006/linesight
|
|
6
|
+
Author: Anshuman Tiwari
|
|
7
|
+
License: MIT
|
|
8
|
+
Project-URL: Homepage, https://github.com/AnshumanTiwari2006/linesight
|
|
9
|
+
Project-URL: Bug Tracker, https://github.com/AnshumanTiwari2006/linesight/issues
|
|
10
|
+
Keywords: machine-learning,regression,education,visualization,gradient-descent
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Education
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Requires-Python: >=3.9
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
License-File: LICENSE
|
|
24
|
+
Requires-Dist: numpy>=1.24
|
|
25
|
+
Requires-Dist: matplotlib>=3.6
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
28
|
+
Requires-Dist: pandas>=1.5; extra == "dev"
|
|
29
|
+
Dynamic: author
|
|
30
|
+
Dynamic: home-page
|
|
31
|
+
Dynamic: license-file
|
|
32
|
+
Dynamic: requires-python
|
|
33
|
+
|
|
34
|
+
# LineSight 🔍
|
|
35
|
+
|
|
36
|
+
**LineSight** is an educational, "glass-box" machine learning library built for understanding—not just executing—regression models.
|
|
37
|
+
|
|
38
|
+
Where traditional libraries like `scikit-learn` act as black boxes (you put data in, you get predictions out), LineSight is explicitly designed to teach you **how** the algorithm works under the hood. Every model can visually show you its loss surface, animate its gradient descent path, and explain its mathematical equations in plain English.
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 🏗️ Library Architecture
|
|
43
|
+
|
|
44
|
+
LineSight is built on a strict, pedagogical tri-layer design. Every single model in the library is broken down into three distinct modules:
|
|
45
|
+
|
|
46
|
+
1. **`engine` (The Math)**
|
|
47
|
+
The core implementation using pure NumPy. Instead of opaque, heavily-optimized C-extensions, the engines are written in highly readable Python. We use explicit `weights` and `bias` variables instead of unified `theta` vectors so the code reads exactly like a textbook formula.
|
|
48
|
+
|
|
49
|
+
2. **`explain` (The Interpretation)**
|
|
50
|
+
A suite of functions that translate the mathematical state of the model into plain-English sentences. It explains the effect of the L2 penalty, parses out the slope coefficient, and dynamically tells you what the model learned.
|
|
51
|
+
|
|
52
|
+
3. **`visualization` (The Proof)**
|
|
53
|
+
A massive collection of Matplotlib-based functions. You can visualize the dataset, the residuals, the 3D loss surface, and even generate live animations of the algorithm learning step-by-step.
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
## 🧠 The Models
|
|
58
|
+
|
|
59
|
+
LineSight currently implements 6 foundational regression models, each designed to teach a specific mathematical concept:
|
|
60
|
+
|
|
61
|
+
| Model | Algorithm | What it teaches |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `LinearRegression` | Gradient Descent | The baseline concept of minimizing Mean Squared Error (MSE). |
|
|
64
|
+
| `MultipleLinearRegression` | Gradient Descent | Dealing with planes, hyperplanes, and multicollinearity. |
|
|
65
|
+
| `PolynomialRegression` | Gradient Descent | Basis expansion and the bias-variance tradeoff (underfitting vs overfitting). |
|
|
66
|
+
| `RidgeRegression` | Gradient Descent | L2 Regularization (weight decay) to handle correlated features. |
|
|
67
|
+
| `LassoRegression` | Coordinate Descent | L1 Regularization and automatic feature selection (sparsity). |
|
|
68
|
+
| `ElasticNetRegression` | Coordinate Descent | Blending L1 and L2 penalties via the `l1_ratio`. |
|
|
69
|
+
| `LogisticRegression` | Gradient Descent | Binary classification, the Sigmoid function, and Log Loss. |
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## ⚡ The Unified API
|
|
74
|
+
|
|
75
|
+
All models strictly follow a unified, `scikit-learn`-style API, meaning you already know how to use them.
|
|
76
|
+
|
|
77
|
+
### 1. Core Execution
|
|
78
|
+
```python
|
|
79
|
+
model = RidgeRegression(alpha=0.1, learning_rate=0.01)
|
|
80
|
+
model.fit(X, y) # Trains the model
|
|
81
|
+
predictions = model.predict(X) # Generates predictions
|
|
82
|
+
metrics = model.score(X, y) # Returns {'r2', 'rmse', 'mae', 'mse'}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Context Panels & Explanations
|
|
86
|
+
Every visualization and summary natively includes **Context Panels**—live, dynamically generated text boxes attached directly to the plots that explain the theory, the formula, and how to read the chart.
|
|
87
|
+
```python
|
|
88
|
+
model.summary() # Prints training summary and final metrics
|
|
89
|
+
model.show_equation() # Prints the literal mathematical formula (e.g., y = 3.5x + 1.2)
|
|
90
|
+
model.explain_regularization() # Explains the specific L1/L2 penalty active in the model
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 3. Visualizations & Animations
|
|
94
|
+
Instead of just returning predictions, LineSight lets you look inside the optimization process:
|
|
95
|
+
```python
|
|
96
|
+
# Visualize the exact distance (error) of every point from the line
|
|
97
|
+
model.plot_residuals(X, y)
|
|
98
|
+
|
|
99
|
+
# Watch the line physically shift and tilt as it minimizes loss over epochs
|
|
100
|
+
model.animate_training(X, y)
|
|
101
|
+
|
|
102
|
+
# See the 3D bowl of the loss surface and the path the gradient took
|
|
103
|
+
model.plot_loss_surface(X, y)
|
|
104
|
+
|
|
105
|
+
# (Lasso/Ridge) Watch features get eliminated as the penalty increases
|
|
106
|
+
model.plot_coefficient_shrinkage(X, y)
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## 🚀 Quick Start
|
|
112
|
+
|
|
113
|
+
### Installation
|
|
114
|
+
|
|
115
|
+
For local usage and development:
|
|
116
|
+
```bash
|
|
117
|
+
git clone https://github.com/AnshumanTiwari2006/linesight
|
|
118
|
+
cd linesight
|
|
119
|
+
pip install -e ".[dev]"
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Example Usage
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
import numpy as np
|
|
126
|
+
from linesight import LinearRegression
|
|
127
|
+
|
|
128
|
+
# 1. Generate some dummy data
|
|
129
|
+
X = np.array([[1], [2], [3], [4], [5]])
|
|
130
|
+
y = np.array([2.1, 4.0, 5.8, 8.1, 9.9])
|
|
131
|
+
|
|
132
|
+
# 2. Instantiate and train the model (store_history is required for animations)
|
|
133
|
+
model = LinearRegression(learning_rate=0.01, epochs=1000, store_history=True)
|
|
134
|
+
model.fit(X, y)
|
|
135
|
+
|
|
136
|
+
# 3. Understand what the model learned
|
|
137
|
+
model.show_equation() # Prints: y = 1.9800x + 0.1200
|
|
138
|
+
model.explain_coefficients() # Explains what 1.98 means in plain English
|
|
139
|
+
|
|
140
|
+
# 4. Prove it visually
|
|
141
|
+
model.plot_fit(X, y) # View the regression line
|
|
142
|
+
model.plot_loss_curve() # Ensure the learning rate was stable
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
## 🧪 Running Tests
|
|
148
|
+
|
|
149
|
+
LineSight is heavily tested to ensure mathematical correctness matches `scikit-learn` implementations. To run the test suite:
|
|
150
|
+
|
|
151
|
+
```bash
|
|
152
|
+
pytest tests/ -v
|
|
153
|
+
```
|
|
154
|
+
*(109 tests covering validators, all model engines, training history, metrics, and explanation layers).*
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
## 📄 License
|
|
159
|
+
|
|
160
|
+
MIT License. Built for education, transparency, and the love of math.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# LineSight 🔍
|
|
2
|
+
|
|
3
|
+
**LineSight** is an educational, "glass-box" machine learning library built for understanding—not just executing—regression models.
|
|
4
|
+
|
|
5
|
+
Where traditional libraries like `scikit-learn` act as black boxes (you put data in, you get predictions out), LineSight is explicitly designed to teach you **how** the algorithm works under the hood. Every model can visually show you its loss surface, animate its gradient descent path, and explain its mathematical equations in plain English.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🏗️ Library Architecture
|
|
10
|
+
|
|
11
|
+
LineSight is built on a strict, pedagogical tri-layer design. Every single model in the library is broken down into three distinct modules:
|
|
12
|
+
|
|
13
|
+
1. **`engine` (The Math)**
|
|
14
|
+
The core implementation using pure NumPy. Instead of opaque, heavily-optimized C-extensions, the engines are written in highly readable Python. We use explicit `weights` and `bias` variables instead of unified `theta` vectors so the code reads exactly like a textbook formula.
|
|
15
|
+
|
|
16
|
+
2. **`explain` (The Interpretation)**
|
|
17
|
+
A suite of functions that translate the mathematical state of the model into plain-English sentences. It explains the effect of the L2 penalty, parses out the slope coefficient, and dynamically tells you what the model learned.
|
|
18
|
+
|
|
19
|
+
3. **`visualization` (The Proof)**
|
|
20
|
+
A massive collection of Matplotlib-based functions. You can visualize the dataset, the residuals, the 3D loss surface, and even generate live animations of the algorithm learning step-by-step.
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 🧠 The Models
|
|
25
|
+
|
|
26
|
+
LineSight currently implements 6 foundational regression models, each designed to teach a specific mathematical concept:
|
|
27
|
+
|
|
28
|
+
| Model | Algorithm | What it teaches |
|
|
29
|
+
|---|---|---|
|
|
30
|
+
| `LinearRegression` | Gradient Descent | The baseline concept of minimizing Mean Squared Error (MSE). |
|
|
31
|
+
| `MultipleLinearRegression` | Gradient Descent | Dealing with planes, hyperplanes, and multicollinearity. |
|
|
32
|
+
| `PolynomialRegression` | Gradient Descent | Basis expansion and the bias-variance tradeoff (underfitting vs overfitting). |
|
|
33
|
+
| `RidgeRegression` | Gradient Descent | L2 Regularization (weight decay) to handle correlated features. |
|
|
34
|
+
| `LassoRegression` | Coordinate Descent | L1 Regularization and automatic feature selection (sparsity). |
|
|
35
|
+
| `ElasticNetRegression` | Coordinate Descent | Blending L1 and L2 penalties via the `l1_ratio`. |
|
|
36
|
+
| `LogisticRegression` | Gradient Descent | Binary classification, the Sigmoid function, and Log Loss. |
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## ⚡ The Unified API
|
|
41
|
+
|
|
42
|
+
All models strictly follow a unified, `scikit-learn`-style API, meaning you already know how to use them.
|
|
43
|
+
|
|
44
|
+
### 1. Core Execution
|
|
45
|
+
```python
|
|
46
|
+
model = RidgeRegression(alpha=0.1, learning_rate=0.01)
|
|
47
|
+
model.fit(X, y) # Trains the model
|
|
48
|
+
predictions = model.predict(X) # Generates predictions
|
|
49
|
+
metrics = model.score(X, y) # Returns {'r2', 'rmse', 'mae', 'mse'}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 2. Context Panels & Explanations
|
|
53
|
+
Every visualization and summary natively includes **Context Panels**—live, dynamically generated text boxes attached directly to the plots that explain the theory, the formula, and how to read the chart.
|
|
54
|
+
```python
|
|
55
|
+
model.summary() # Prints training summary and final metrics
|
|
56
|
+
model.show_equation() # Prints the literal mathematical formula (e.g., y = 3.5x + 1.2)
|
|
57
|
+
model.explain_regularization() # Explains the specific L1/L2 penalty active in the model
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### 3. Visualizations & Animations
|
|
61
|
+
Instead of just returning predictions, LineSight lets you look inside the optimization process:
|
|
62
|
+
```python
|
|
63
|
+
# Visualize the exact distance (error) of every point from the line
|
|
64
|
+
model.plot_residuals(X, y)
|
|
65
|
+
|
|
66
|
+
# Watch the line physically shift and tilt as it minimizes loss over epochs
|
|
67
|
+
model.animate_training(X, y)
|
|
68
|
+
|
|
69
|
+
# See the 3D bowl of the loss surface and the path the gradient took
|
|
70
|
+
model.plot_loss_surface(X, y)
|
|
71
|
+
|
|
72
|
+
# (Lasso/Ridge) Watch features get eliminated as the penalty increases
|
|
73
|
+
model.plot_coefficient_shrinkage(X, y)
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
## 🚀 Quick Start
|
|
79
|
+
|
|
80
|
+
### Installation
|
|
81
|
+
|
|
82
|
+
For local usage and development:
|
|
83
|
+
```bash
|
|
84
|
+
git clone https://github.com/AnshumanTiwari2006/linesight
|
|
85
|
+
cd linesight
|
|
86
|
+
pip install -e ".[dev]"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Example Usage
|
|
90
|
+
|
|
91
|
+
```python
|
|
92
|
+
import numpy as np
|
|
93
|
+
from linesight import LinearRegression
|
|
94
|
+
|
|
95
|
+
# 1. Generate some dummy data
|
|
96
|
+
X = np.array([[1], [2], [3], [4], [5]])
|
|
97
|
+
y = np.array([2.1, 4.0, 5.8, 8.1, 9.9])
|
|
98
|
+
|
|
99
|
+
# 2. Instantiate and train the model (store_history is required for animations)
|
|
100
|
+
model = LinearRegression(learning_rate=0.01, epochs=1000, store_history=True)
|
|
101
|
+
model.fit(X, y)
|
|
102
|
+
|
|
103
|
+
# 3. Understand what the model learned
|
|
104
|
+
model.show_equation() # Prints: y = 1.9800x + 0.1200
|
|
105
|
+
model.explain_coefficients() # Explains what 1.98 means in plain English
|
|
106
|
+
|
|
107
|
+
# 4. Prove it visually
|
|
108
|
+
model.plot_fit(X, y) # View the regression line
|
|
109
|
+
model.plot_loss_curve() # Ensure the learning rate was stable
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## 🧪 Running Tests
|
|
115
|
+
|
|
116
|
+
LineSight is heavily tested to ensure mathematical correctness matches `scikit-learn` implementations. To run the test suite:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
pytest tests/ -v
|
|
120
|
+
```
|
|
121
|
+
*(109 tests covering validators, all model engines, training history, metrics, and explanation layers).*
|
|
122
|
+
|
|
123
|
+
---
|
|
124
|
+
|
|
125
|
+
## 📄 License
|
|
126
|
+
|
|
127
|
+
MIT License. Built for education, transparency, and the love of math.
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
from linesight.regression.linear.core import LinearRegression
|
|
2
|
+
from linesight.regression.polynomial.core import PolynomialRegression
|
|
3
|
+
from linesight.regression.multiple.core import MultipleLinearRegression
|
|
4
|
+
from linesight.regression.ridge.core import RidgeRegression
|
|
5
|
+
from linesight.regression.lasso.core import LassoRegression
|
|
6
|
+
from linesight.regression.elasticnet.core import ElasticNetRegression
|
|
7
|
+
from linesight.regression.logistic.core import LogisticRegression
|
|
8
|
+
|
|
9
|
+
__version__ = "0.1.0"
|
|
10
|
+
|
|
11
|
+
__all__ = [
|
|
12
|
+
"LinearRegression",
|
|
13
|
+
"PolynomialRegression",
|
|
14
|
+
"MultipleLinearRegression",
|
|
15
|
+
"RidgeRegression",
|
|
16
|
+
"LassoRegression",
|
|
17
|
+
"ElasticNetRegression",
|
|
18
|
+
"LogisticRegression",
|
|
19
|
+
]
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import matplotlib.pyplot as plt
|
|
2
|
+
from linesight.exceptions import LineSightNotFittedError
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class LineSightBase:
|
|
6
|
+
|
|
7
|
+
_is_fitted: bool = False
|
|
8
|
+
|
|
9
|
+
def _check_fitted(self, method_name: str) -> None:
|
|
10
|
+
if not self._is_fitted:
|
|
11
|
+
raise LineSightNotFittedError(
|
|
12
|
+
f"Call fit(X, y) before calling {method_name}()."
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
def _validate_hyperparams(self) -> None:
|
|
16
|
+
"""Hook for subclasses to validate hyperparams before fitting."""
|
|
17
|
+
if hasattr(self, 'learning_rate') and getattr(self, 'learning_rate') <= 0:
|
|
18
|
+
raise ValueError("learning_rate must be > 0")
|
|
19
|
+
if hasattr(self, 'epochs') and getattr(self, 'epochs') <= 0:
|
|
20
|
+
raise ValueError("epochs must be > 0")
|
|
21
|
+
if hasattr(self, 'alpha') and getattr(self, 'alpha') < 0:
|
|
22
|
+
raise ValueError("alpha must be >= 0")
|
|
23
|
+
if hasattr(self, 'l1_ratio') and not (0 <= getattr(self, 'l1_ratio') <= 1):
|
|
24
|
+
raise ValueError("l1_ratio must be between 0 and 1")
|
|
25
|
+
if hasattr(self, 'degree') and getattr(self, 'degree') < 1:
|
|
26
|
+
raise ValueError("degree must be >= 1")
|
|
27
|
+
if hasattr(self, 'batch_size'):
|
|
28
|
+
bs = getattr(self, 'batch_size')
|
|
29
|
+
if bs is not None and bs <= 0:
|
|
30
|
+
raise ValueError("batch_size must be >= 1 or None")
|
|
31
|
+
|
|
32
|
+
def show(self, animation_obj=None, fig=None):
|
|
33
|
+
"""
|
|
34
|
+
Display a figure or animation correctly for the current environment.
|
|
35
|
+
|
|
36
|
+
THE CORRECT BEHAVIOR — read carefully:
|
|
37
|
+
|
|
38
|
+
For STATIC figures (fig parameter):
|
|
39
|
+
- In Jupyter/Colab: plt.show() closes the figure and triggers
|
|
40
|
+
the inline backend to render it. Do NOT return fig after plt.show()
|
|
41
|
+
because the figure object is now closed. Return None.
|
|
42
|
+
- In script: plt.show() opens the window. Return None.
|
|
43
|
+
- NEVER call IPython.display.display(fig) — causes triple rendering.
|
|
44
|
+
|
|
45
|
+
For ANIMATIONS (animation_obj parameter):
|
|
46
|
+
- In Jupyter/Colab: return HTML(anim.to_jshtml()).
|
|
47
|
+
Do NOT call plt.show() first — it closes the figure.
|
|
48
|
+
- In script: plt.show() runs the animation in a window.
|
|
49
|
+
|
|
50
|
+
This corrects the bug in the original specification where static
|
|
51
|
+
figures returned fig after plt.show() had already closed them.
|
|
52
|
+
"""
|
|
53
|
+
from linesight.utils.environment import _detect_environment
|
|
54
|
+
env = _detect_environment()
|
|
55
|
+
|
|
56
|
+
if animation_obj is not None:
|
|
57
|
+
if env in ('jupyter', 'colab'):
|
|
58
|
+
try:
|
|
59
|
+
from IPython.display import HTML
|
|
60
|
+
plt.close() # close the underlying figure to free memory
|
|
61
|
+
return HTML(animation_obj.to_jshtml())
|
|
62
|
+
except ImportError:
|
|
63
|
+
plt.show()
|
|
64
|
+
return None
|
|
65
|
+
else:
|
|
66
|
+
plt.show()
|
|
67
|
+
return None
|
|
68
|
+
|
|
69
|
+
elif fig is not None:
|
|
70
|
+
# For static figures: plt.show() handles both environments.
|
|
71
|
+
# In Jupyter with %matplotlib inline, plt.show() triggers the
|
|
72
|
+
# inline renderer. In scripts it opens the window.
|
|
73
|
+
# After plt.show(), the figure is closed. Return None always.
|
|
74
|
+
plt.tight_layout()
|
|
75
|
+
plt.show()
|
|
76
|
+
return None
|
|
77
|
+
|
|
78
|
+
return None
|
|
79
|
+
|
|
80
|
+
def save(self, filepath: str, fig=None, animation_obj=None,
|
|
81
|
+
dpi: int = 150, fps: int = 20) -> str:
|
|
82
|
+
"""
|
|
83
|
+
Save a figure or animation to disk.
|
|
84
|
+
|
|
85
|
+
Parameters
|
|
86
|
+
----------
|
|
87
|
+
filepath : str
|
|
88
|
+
Full path including extension.
|
|
89
|
+
For figures: use .png, .pdf, .svg
|
|
90
|
+
For animations: use .gif or .mp4
|
|
91
|
+
Example: "my_plot.png" or "training.gif"
|
|
92
|
+
fig : matplotlib.figure.Figure, optional
|
|
93
|
+
animation_obj : FuncAnimation, optional
|
|
94
|
+
dpi : int, default 150
|
|
95
|
+
Resolution for raster formats (png, gif).
|
|
96
|
+
fps : int, default 20
|
|
97
|
+
Frames per second for animation exports.
|
|
98
|
+
|
|
99
|
+
Returns
|
|
100
|
+
-------
|
|
101
|
+
str — the filepath that was saved to, for confirmation.
|
|
102
|
+
|
|
103
|
+
Usage in visualization methods
|
|
104
|
+
--------------------------------
|
|
105
|
+
To let users save without displaying:
|
|
106
|
+
fig = model.plot_fit(X, y, display=False)
|
|
107
|
+
model.save("fit.png", fig=fig)
|
|
108
|
+
|
|
109
|
+
Or as a one-liner (display=False returns the object):
|
|
110
|
+
model.save("training.gif",
|
|
111
|
+
animation_obj=model.animate_training(X, y, display=False))
|
|
112
|
+
|
|
113
|
+
Raises
|
|
114
|
+
------
|
|
115
|
+
ValueError if neither fig nor animation_obj is provided.
|
|
116
|
+
ImportError with helpful message if saving .mp4 requires ffmpeg.
|
|
117
|
+
"""
|
|
118
|
+
if fig is None and animation_obj is None:
|
|
119
|
+
raise ValueError(
|
|
120
|
+
"Pass either fig= or animation_obj= to save().\n"
|
|
121
|
+
"Get the object by calling the visualization method "
|
|
122
|
+
"with display=False."
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
if fig is not None:
|
|
126
|
+
fig.savefig(filepath, dpi=dpi, bbox_inches='tight')
|
|
127
|
+
print(f"Saved to: {filepath}")
|
|
128
|
+
return filepath
|
|
129
|
+
|
|
130
|
+
if animation_obj is not None:
|
|
131
|
+
if filepath.endswith('.gif'):
|
|
132
|
+
animation_obj.save(filepath, writer='pillow', fps=fps)
|
|
133
|
+
elif filepath.endswith('.mp4'):
|
|
134
|
+
try:
|
|
135
|
+
animation_obj.save(filepath, writer='ffmpeg', fps=fps)
|
|
136
|
+
except Exception:
|
|
137
|
+
raise ImportError(
|
|
138
|
+
"Saving .mp4 requires ffmpeg installed on your system.\n"
|
|
139
|
+
"Install it with: conda install ffmpeg\n"
|
|
140
|
+
"Or save as .gif instead: model.save('training.gif', ...)"
|
|
141
|
+
)
|
|
142
|
+
else:
|
|
143
|
+
animation_obj.save(filepath, fps=fps)
|
|
144
|
+
print(f"Saved to: {filepath}")
|
|
145
|
+
return filepath
|
|
146
|
+
|
|
147
|
+
def summary(self) -> str:
|
|
148
|
+
"""
|
|
149
|
+
Print a complete model summary: parameters, fit quality, coefficients.
|
|
150
|
+
|
|
151
|
+
Every regression class overrides this to include model-specific info.
|
|
152
|
+
The base implementation raises NotFittedError if called before fit().
|
|
153
|
+
|
|
154
|
+
Returns
|
|
155
|
+
-------
|
|
156
|
+
str — the summary text. Also printed (in script mode) or returned
|
|
157
|
+
(in Jupyter, displayed automatically as the cell's last value).
|
|
158
|
+
"""
|
|
159
|
+
self._check_fitted("summary")
|
|
160
|
+
raise NotImplementedError(
|
|
161
|
+
"summary() must be implemented by each regression subclass."
|
|
162
|
+
)
|
|
163
|
+
|
|
164
|
+
def refit(self, X, y):
|
|
165
|
+
"""
|
|
166
|
+
Re-train the model from scratch on new data.
|
|
167
|
+
|
|
168
|
+
Resets ALL state: coefficients, intercept, history, fitted flag.
|
|
169
|
+
Equivalent to creating a new instance with the same hyperparameters
|
|
170
|
+
and calling fit(X, y).
|
|
171
|
+
|
|
172
|
+
Why this exists
|
|
173
|
+
---------------
|
|
174
|
+
If a student calls fit() twice on the same model object, the second
|
|
175
|
+
call continues from where the first left off (coef_ is NOT reset to 0).
|
|
176
|
+
This produces confusing results. refit() makes the intention explicit
|
|
177
|
+
and resets properly.
|
|
178
|
+
|
|
179
|
+
Usage
|
|
180
|
+
-----
|
|
181
|
+
model.fit(X_train, y_train) # initial training
|
|
182
|
+
model.refit(X_new, y_new) # clean reset + retrain on new data
|
|
183
|
+
"""
|
|
184
|
+
# Reset state — subclasses that use theta_ instead of coef_/intercept_
|
|
185
|
+
# must override this to reset theta_ as well
|
|
186
|
+
if hasattr(self, 'coef_'):
|
|
187
|
+
self.coef_ = 0.0
|
|
188
|
+
if hasattr(self, 'intercept_'):
|
|
189
|
+
self.intercept_ = 0.0
|
|
190
|
+
if hasattr(self, 'theta_'):
|
|
191
|
+
self.theta_ = None
|
|
192
|
+
self._is_fitted = False
|
|
193
|
+
from linesight.utils.history import TrainingHistory
|
|
194
|
+
self._history = TrainingHistory(learning_rate=getattr(self, 'learning_rate', 0))
|
|
195
|
+
return self.fit(X, y)
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
from linesight.exceptions.shape_error import LineSightShapeError
|
|
2
|
+
from linesight.exceptions.not_fitted_error import LineSightNotFittedError
|
|
3
|
+
from linesight.exceptions.convergence_warning import LineSightConvergenceWarning
|
|
4
|
+
from linesight.exceptions.data_warning import LineSightDataWarning
|
|
5
|
+
from linesight.exceptions.gradient_error import LineSightGradientError
|
|
6
|
+
|
|
7
|
+
__all__ = [
|
|
8
|
+
"LineSightShapeError",
|
|
9
|
+
"LineSightNotFittedError",
|
|
10
|
+
"LineSightConvergenceWarning",
|
|
11
|
+
"LineSightDataWarning",
|
|
12
|
+
"LineSightGradientError",
|
|
13
|
+
]
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
class LineSightNotFittedError(RuntimeError):
|
|
2
|
+
"""
|
|
3
|
+
Raised when any method that requires a trained model is called before fit().
|
|
4
|
+
|
|
5
|
+
Always constructed with the method name that was called.
|
|
6
|
+
|
|
7
|
+
Example
|
|
8
|
+
-------
|
|
9
|
+
raise LineSightNotFittedError(
|
|
10
|
+
"Call fit(X, y) before calling predict()."
|
|
11
|
+
)
|
|
12
|
+
"""
|
|
13
|
+
pass
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class LineSightShapeError(ValueError):
|
|
2
|
+
"""
|
|
3
|
+
Raised when array shapes are incompatible.
|
|
4
|
+
|
|
5
|
+
Always constructed with a message that includes:
|
|
6
|
+
- What was expected
|
|
7
|
+
- What was actually received
|
|
8
|
+
- A suggested fix
|
|
9
|
+
|
|
10
|
+
Example
|
|
11
|
+
-------
|
|
12
|
+
raise LineSightShapeError(
|
|
13
|
+
"X and y must have the same number of samples.\n"
|
|
14
|
+
f"X has {X.shape[0]} samples, y has {y.shape[0]} samples.\n"
|
|
15
|
+
"Did you forget to align your datasets?"
|
|
16
|
+
)
|
|
17
|
+
"""
|
|
18
|
+
pass
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
def accuracy(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
|
4
|
+
"""
|
|
5
|
+
Classification accuracy. Used only by LogisticRegression.
|
|
6
|
+
Formula: number of correct predictions / total predictions.
|
|
7
|
+
y_pred should be class labels (0 or 1), not probabilities.
|
|
8
|
+
"""
|
|
9
|
+
return float(np.mean(y_true == y_pred))
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
def r2(y_true: np.ndarray, y_pred: np.ndarray) -> float:
|
|
4
|
+
"""
|
|
5
|
+
R-squared (coefficient of determination).
|
|
6
|
+
|
|
7
|
+
Formula: 1 - SS_res / SS_tot
|
|
8
|
+
where SS_res = sum((y_true - y_pred)^2)
|
|
9
|
+
and SS_tot = sum((y_true - mean(y_true))^2)
|
|
10
|
+
|
|
11
|
+
Returns 1.0 for perfect fit.
|
|
12
|
+
Returns 0.0 if model just predicts the mean.
|
|
13
|
+
Can be negative if model is worse than predicting the mean.
|
|
14
|
+
"""
|
|
15
|
+
ss_res = np.sum((y_true - y_pred) ** 2)
|
|
16
|
+
ss_tot = np.sum((y_true - np.mean(y_true)) ** 2)
|
|
17
|
+
if ss_tot == 0:
|
|
18
|
+
# All y values are identical — R^2 is undefined, return 0
|
|
19
|
+
return 0.0
|
|
20
|
+
return float(1 - ss_res / ss_tot)
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
from linesight.regression.linear.core import LinearRegression
|
|
2
|
+
from linesight.regression.multiple.core import MultipleLinearRegression
|
|
3
|
+
from linesight.regression.ridge.core import RidgeRegression
|
|
4
|
+
from linesight.regression.lasso.core import LassoRegression
|
|
5
|
+
from linesight.regression.elasticnet.core import ElasticNetRegression
|
|
6
|
+
from linesight.regression.logistic.core import LogisticRegression
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
from linesight.regression.elasticnet.core import ElasticNetRegression
|