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.
Files changed (204) hide show
  1. linesight-0.1.0/LICENSE +21 -0
  2. linesight-0.1.0/PKG-INFO +160 -0
  3. linesight-0.1.0/README.md +127 -0
  4. linesight-0.1.0/linesight/__init__.py +19 -0
  5. linesight-0.1.0/linesight/base.py +195 -0
  6. linesight-0.1.0/linesight/exceptions/__init__.py +13 -0
  7. linesight-0.1.0/linesight/exceptions/convergence_warning.py +9 -0
  8. linesight-0.1.0/linesight/exceptions/data_warning.py +6 -0
  9. linesight-0.1.0/linesight/exceptions/gradient_error.py +5 -0
  10. linesight-0.1.0/linesight/exceptions/not_fitted_error.py +13 -0
  11. linesight-0.1.0/linesight/exceptions/shape_error.py +18 -0
  12. linesight-0.1.0/linesight/metrics/__init__.py +5 -0
  13. linesight-0.1.0/linesight/metrics/accuracy.py +9 -0
  14. linesight-0.1.0/linesight/metrics/mae.py +5 -0
  15. linesight-0.1.0/linesight/metrics/mse.py +5 -0
  16. linesight-0.1.0/linesight/metrics/r2.py +20 -0
  17. linesight-0.1.0/linesight/metrics/rmse.py +6 -0
  18. linesight-0.1.0/linesight/regression/__init__.py +6 -0
  19. linesight-0.1.0/linesight/regression/elasticnet/__init__.py +1 -0
  20. linesight-0.1.0/linesight/regression/elasticnet/core.py +103 -0
  21. linesight-0.1.0/linesight/regression/elasticnet/engine/__init__.py +0 -0
  22. linesight-0.1.0/linesight/regression/elasticnet/engine/compute_loss.py +8 -0
  23. linesight-0.1.0/linesight/regression/elasticnet/engine/fit.py +72 -0
  24. linesight-0.1.0/linesight/regression/elasticnet/engine/get_history.py +9 -0
  25. linesight-0.1.0/linesight/regression/elasticnet/engine/predict.py +9 -0
  26. linesight-0.1.0/linesight/regression/elasticnet/engine/score.py +13 -0
  27. linesight-0.1.0/linesight/regression/elasticnet/engine/soft_threshold.py +8 -0
  28. linesight-0.1.0/linesight/regression/elasticnet/explain/__init__.py +1 -0
  29. linesight-0.1.0/linesight/regression/elasticnet/explain/explain_coefficients.py +29 -0
  30. linesight-0.1.0/linesight/regression/elasticnet/explain/explain_regularization.py +33 -0
  31. linesight-0.1.0/linesight/regression/elasticnet/visualization/__init__.py +1 -0
  32. linesight-0.1.0/linesight/regression/elasticnet/visualization/animate_l1_ratio_sweep.py +102 -0
  33. linesight-0.1.0/linesight/regression/elasticnet/visualization/compare_regularization_methods.py +100 -0
  34. linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_actual_vs_predicted.py +69 -0
  35. linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_coefficient_shrinkage.py +43 -0
  36. linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_fit.py +36 -0
  37. linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_l1_l2_balance.py +113 -0
  38. linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_learning_curve.py +127 -0
  39. linesight-0.1.0/linesight/regression/elasticnet/visualization/plot_loss_curve.py +27 -0
  40. linesight-0.1.0/linesight/regression/lasso/__init__.py +1 -0
  41. linesight-0.1.0/linesight/regression/lasso/core.py +105 -0
  42. linesight-0.1.0/linesight/regression/lasso/engine/__init__.py +0 -0
  43. linesight-0.1.0/linesight/regression/lasso/engine/compute_loss.py +7 -0
  44. linesight-0.1.0/linesight/regression/lasso/engine/fit.py +71 -0
  45. linesight-0.1.0/linesight/regression/lasso/engine/get_history.py +9 -0
  46. linesight-0.1.0/linesight/regression/lasso/engine/predict.py +9 -0
  47. linesight-0.1.0/linesight/regression/lasso/engine/score.py +13 -0
  48. linesight-0.1.0/linesight/regression/lasso/engine/soft_threshold.py +29 -0
  49. linesight-0.1.0/linesight/regression/lasso/explain/__init__.py +0 -0
  50. linesight-0.1.0/linesight/regression/lasso/explain/explain_coefficients.py +30 -0
  51. linesight-0.1.0/linesight/regression/lasso/explain/explain_regularization.py +30 -0
  52. linesight-0.1.0/linesight/regression/lasso/explain/explain_sparsity.py +36 -0
  53. linesight-0.1.0/linesight/regression/lasso/visualization/__init__.py +0 -0
  54. linesight-0.1.0/linesight/regression/lasso/visualization/animate_coordinate_descent.py +104 -0
  55. linesight-0.1.0/linesight/regression/lasso/visualization/compare_with_linear.py +49 -0
  56. linesight-0.1.0/linesight/regression/lasso/visualization/plot_actual_vs_predicted.py +69 -0
  57. linesight-0.1.0/linesight/regression/lasso/visualization/plot_coefficient_shrinkage.py +44 -0
  58. linesight-0.1.0/linesight/regression/lasso/visualization/plot_constraint_region.py +92 -0
  59. linesight-0.1.0/linesight/regression/lasso/visualization/plot_feature_elimination.py +88 -0
  60. linesight-0.1.0/linesight/regression/lasso/visualization/plot_fit.py +37 -0
  61. linesight-0.1.0/linesight/regression/lasso/visualization/plot_learning_curve.py +127 -0
  62. linesight-0.1.0/linesight/regression/lasso/visualization/plot_loss_curve.py +28 -0
  63. linesight-0.1.0/linesight/regression/lasso/visualization/plot_sparsity_path.py +126 -0
  64. linesight-0.1.0/linesight/regression/linear/__init__.py +1 -0
  65. linesight-0.1.0/linesight/regression/linear/core.py +134 -0
  66. linesight-0.1.0/linesight/regression/linear/engine/__init__.py +0 -0
  67. linesight-0.1.0/linesight/regression/linear/engine/compute_loss.py +23 -0
  68. linesight-0.1.0/linesight/regression/linear/engine/fit.py +59 -0
  69. linesight-0.1.0/linesight/regression/linear/engine/get_history.py +31 -0
  70. linesight-0.1.0/linesight/regression/linear/engine/gradient_step.py +42 -0
  71. linesight-0.1.0/linesight/regression/linear/engine/predict.py +25 -0
  72. linesight-0.1.0/linesight/regression/linear/engine/score.py +38 -0
  73. linesight-0.1.0/linesight/regression/linear/explain/__init__.py +0 -0
  74. linesight-0.1.0/linesight/regression/linear/explain/explain_coefficients.py +39 -0
  75. linesight-0.1.0/linesight/regression/linear/explain/explain_fit.py +66 -0
  76. linesight-0.1.0/linesight/regression/linear/explain/show_equation.py +25 -0
  77. linesight-0.1.0/linesight/regression/linear/visualization/__init__.py +0 -0
  78. linesight-0.1.0/linesight/regression/linear/visualization/animate_loss_surface_path.py +157 -0
  79. linesight-0.1.0/linesight/regression/linear/visualization/animate_training.py +109 -0
  80. linesight-0.1.0/linesight/regression/linear/visualization/compare_learning_rates.py +97 -0
  81. linesight-0.1.0/linesight/regression/linear/visualization/plot_actual_vs_predicted.py +69 -0
  82. linesight-0.1.0/linesight/regression/linear/visualization/plot_fit.py +103 -0
  83. linesight-0.1.0/linesight/regression/linear/visualization/plot_gradient_vectors.py +145 -0
  84. linesight-0.1.0/linesight/regression/linear/visualization/plot_learning_curve.py +126 -0
  85. linesight-0.1.0/linesight/regression/linear/visualization/plot_loss_curve.py +78 -0
  86. linesight-0.1.0/linesight/regression/linear/visualization/plot_loss_surface.py +135 -0
  87. linesight-0.1.0/linesight/regression/linear/visualization/plot_prediction_intervals.py +190 -0
  88. linesight-0.1.0/linesight/regression/linear/visualization/plot_residuals.py +74 -0
  89. linesight-0.1.0/linesight/regression/linear/visualization/plot_sensitivity_analysis.py +195 -0
  90. linesight-0.1.0/linesight/regression/logistic/__init__.py +1 -0
  91. linesight-0.1.0/linesight/regression/logistic/core.py +114 -0
  92. linesight-0.1.0/linesight/regression/logistic/engine/__init__.py +1 -0
  93. linesight-0.1.0/linesight/regression/logistic/engine/compute_loss.py +8 -0
  94. linesight-0.1.0/linesight/regression/logistic/engine/fit.py +88 -0
  95. linesight-0.1.0/linesight/regression/logistic/engine/get_history.py +8 -0
  96. linesight-0.1.0/linesight/regression/logistic/engine/gradient_step.py +21 -0
  97. linesight-0.1.0/linesight/regression/logistic/engine/predict.py +9 -0
  98. linesight-0.1.0/linesight/regression/logistic/engine/predict_proba.py +12 -0
  99. linesight-0.1.0/linesight/regression/logistic/engine/score.py +12 -0
  100. linesight-0.1.0/linesight/regression/logistic/engine/sigmoid.py +32 -0
  101. linesight-0.1.0/linesight/regression/logistic/explain/__init__.py +1 -0
  102. linesight-0.1.0/linesight/regression/logistic/explain/explain_boundary.py +23 -0
  103. linesight-0.1.0/linesight/regression/logistic/explain/explain_coefficients.py +27 -0
  104. linesight-0.1.0/linesight/regression/logistic/explain/explain_sigmoid.py +21 -0
  105. linesight-0.1.0/linesight/regression/logistic/visualization/__init__.py +1 -0
  106. linesight-0.1.0/linesight/regression/logistic/visualization/animate_boundary.py +87 -0
  107. linesight-0.1.0/linesight/regression/logistic/visualization/plot_actual_vs_predicted.py +69 -0
  108. linesight-0.1.0/linesight/regression/logistic/visualization/plot_calibration_curve.py +138 -0
  109. linesight-0.1.0/linesight/regression/logistic/visualization/plot_confusion_matrix.py +105 -0
  110. linesight-0.1.0/linesight/regression/logistic/visualization/plot_decision_boundary.py +106 -0
  111. linesight-0.1.0/linesight/regression/logistic/visualization/plot_learning_curve.py +126 -0
  112. linesight-0.1.0/linesight/regression/logistic/visualization/plot_log_odds.py +129 -0
  113. linesight-0.1.0/linesight/regression/logistic/visualization/plot_loss_curve.py +27 -0
  114. linesight-0.1.0/linesight/regression/logistic/visualization/plot_probability_surface.py +37 -0
  115. linesight-0.1.0/linesight/regression/logistic/visualization/plot_residuals.py +30 -0
  116. linesight-0.1.0/linesight/regression/logistic/visualization/plot_roc_curve.py +118 -0
  117. linesight-0.1.0/linesight/regression/logistic/visualization/plot_sigmoid.py +32 -0
  118. linesight-0.1.0/linesight/regression/logistic/visualization/plot_threshold_sensitivity.py +80 -0
  119. linesight-0.1.0/linesight/regression/multiple/__init__.py +1 -0
  120. linesight-0.1.0/linesight/regression/multiple/core.py +103 -0
  121. linesight-0.1.0/linesight/regression/multiple/engine/__init__.py +0 -0
  122. linesight-0.1.0/linesight/regression/multiple/engine/compute_loss.py +5 -0
  123. linesight-0.1.0/linesight/regression/multiple/engine/fit.py +87 -0
  124. linesight-0.1.0/linesight/regression/multiple/engine/get_history.py +13 -0
  125. linesight-0.1.0/linesight/regression/multiple/engine/gradient_step.py +23 -0
  126. linesight-0.1.0/linesight/regression/multiple/engine/predict.py +11 -0
  127. linesight-0.1.0/linesight/regression/multiple/engine/score.py +17 -0
  128. linesight-0.1.0/linesight/regression/multiple/explain/__init__.py +0 -0
  129. linesight-0.1.0/linesight/regression/multiple/explain/explain_coefficients.py +29 -0
  130. linesight-0.1.0/linesight/regression/multiple/explain/show_equation.py +14 -0
  131. linesight-0.1.0/linesight/regression/multiple/visualization/__init__.py +0 -0
  132. linesight-0.1.0/linesight/regression/multiple/visualization/plot_3d_loss_slice.py +113 -0
  133. linesight-0.1.0/linesight/regression/multiple/visualization/plot_actual_vs_predicted.py +69 -0
  134. linesight-0.1.0/linesight/regression/multiple/visualization/plot_correlation_matrix.py +35 -0
  135. linesight-0.1.0/linesight/regression/multiple/visualization/plot_feature_importance.py +59 -0
  136. linesight-0.1.0/linesight/regression/multiple/visualization/plot_fit.py +62 -0
  137. linesight-0.1.0/linesight/regression/multiple/visualization/plot_learning_curve.py +126 -0
  138. linesight-0.1.0/linesight/regression/multiple/visualization/plot_multicollinearity.py +180 -0
  139. linesight-0.1.0/linesight/regression/multiple/visualization/plot_partial_regression.py +67 -0
  140. linesight-0.1.0/linesight/regression/multiple/visualization/plot_prediction_plane.py +42 -0
  141. linesight-0.1.0/linesight/regression/multiple/visualization/plot_residual_heatmap.py +87 -0
  142. linesight-0.1.0/linesight/regression/polynomial/__init__.py +0 -0
  143. linesight-0.1.0/linesight/regression/polynomial/core.py +93 -0
  144. linesight-0.1.0/linesight/regression/polynomial/engine/__init__.py +0 -0
  145. linesight-0.1.0/linesight/regression/polynomial/engine/expand_features.py +30 -0
  146. linesight-0.1.0/linesight/regression/polynomial/engine/fit.py +117 -0
  147. linesight-0.1.0/linesight/regression/polynomial/engine/predict.py +14 -0
  148. linesight-0.1.0/linesight/regression/polynomial/explain/__init__.py +0 -0
  149. linesight-0.1.0/linesight/regression/polynomial/explain/show_equation.py +29 -0
  150. linesight-0.1.0/linesight/regression/polynomial/visualization/__init__.py +0 -0
  151. linesight-0.1.0/linesight/regression/polynomial/visualization/animate_degree_increase.py +88 -0
  152. linesight-0.1.0/linesight/regression/polynomial/visualization/compare_degrees.py +110 -0
  153. linesight-0.1.0/linesight/regression/polynomial/visualization/plot_actual_vs_predicted.py +69 -0
  154. linesight-0.1.0/linesight/regression/polynomial/visualization/plot_basis_functions.py +138 -0
  155. linesight-0.1.0/linesight/regression/polynomial/visualization/plot_fit.py +59 -0
  156. linesight-0.1.0/linesight/regression/polynomial/visualization/plot_learning_curve.py +126 -0
  157. linesight-0.1.0/linesight/regression/ridge/__init__.py +1 -0
  158. linesight-0.1.0/linesight/regression/ridge/core.py +109 -0
  159. linesight-0.1.0/linesight/regression/ridge/engine/__init__.py +0 -0
  160. linesight-0.1.0/linesight/regression/ridge/engine/compute_loss.py +7 -0
  161. linesight-0.1.0/linesight/regression/ridge/engine/fit.py +87 -0
  162. linesight-0.1.0/linesight/regression/ridge/engine/get_history.py +9 -0
  163. linesight-0.1.0/linesight/regression/ridge/engine/gradient_step.py +28 -0
  164. linesight-0.1.0/linesight/regression/ridge/engine/predict.py +11 -0
  165. linesight-0.1.0/linesight/regression/ridge/engine/score.py +13 -0
  166. linesight-0.1.0/linesight/regression/ridge/explain/__init__.py +0 -0
  167. linesight-0.1.0/linesight/regression/ridge/explain/explain_coefficients.py +32 -0
  168. linesight-0.1.0/linesight/regression/ridge/explain/explain_regularization.py +38 -0
  169. linesight-0.1.0/linesight/regression/ridge/visualization/__init__.py +0 -0
  170. linesight-0.1.0/linesight/regression/ridge/visualization/animate_regularization.py +100 -0
  171. linesight-0.1.0/linesight/regression/ridge/visualization/compare_with_linear.py +58 -0
  172. linesight-0.1.0/linesight/regression/ridge/visualization/plot_actual_vs_predicted.py +69 -0
  173. linesight-0.1.0/linesight/regression/ridge/visualization/plot_bias_variance_tradeoff.py +110 -0
  174. linesight-0.1.0/linesight/regression/ridge/visualization/plot_coefficient_shrinkage.py +75 -0
  175. linesight-0.1.0/linesight/regression/ridge/visualization/plot_constraint_region.py +90 -0
  176. linesight-0.1.0/linesight/regression/ridge/visualization/plot_effective_degrees_of_freedom.py +117 -0
  177. linesight-0.1.0/linesight/regression/ridge/visualization/plot_fit.py +38 -0
  178. linesight-0.1.0/linesight/regression/ridge/visualization/plot_learning_curve.py +126 -0
  179. linesight-0.1.0/linesight/regression/ridge/visualization/plot_loss_curve.py +30 -0
  180. linesight-0.1.0/linesight/utils/__init__.py +13 -0
  181. linesight-0.1.0/linesight/utils/array_utils.py +23 -0
  182. linesight-0.1.0/linesight/utils/colors.py +43 -0
  183. linesight-0.1.0/linesight/utils/environment.py +28 -0
  184. linesight-0.1.0/linesight/utils/history.py +16 -0
  185. linesight-0.1.0/linesight/utils/validators.py +70 -0
  186. linesight-0.1.0/linesight/utils/viz_context.py +51 -0
  187. linesight-0.1.0/linesight.egg-info/PKG-INFO +160 -0
  188. linesight-0.1.0/linesight.egg-info/SOURCES.txt +202 -0
  189. linesight-0.1.0/linesight.egg-info/dependency_links.txt +1 -0
  190. linesight-0.1.0/linesight.egg-info/requires.txt +6 -0
  191. linesight-0.1.0/linesight.egg-info/top_level.txt +1 -0
  192. linesight-0.1.0/pyproject.toml +49 -0
  193. linesight-0.1.0/setup.cfg +4 -0
  194. linesight-0.1.0/setup.py +35 -0
  195. linesight-0.1.0/tests/test_elasticnet_engine.py +43 -0
  196. linesight-0.1.0/tests/test_history.py +60 -0
  197. linesight-0.1.0/tests/test_lasso_engine.py +79 -0
  198. linesight-0.1.0/tests/test_linear_engine.py +268 -0
  199. linesight-0.1.0/tests/test_logistic_engine.py +95 -0
  200. linesight-0.1.0/tests/test_metrics.py +77 -0
  201. linesight-0.1.0/tests/test_multiple_engine.py +102 -0
  202. linesight-0.1.0/tests/test_polynomial_engine.py +40 -0
  203. linesight-0.1.0/tests/test_ridge_engine.py +76 -0
  204. linesight-0.1.0/tests/test_validators.py +137 -0
@@ -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.
@@ -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,9 @@
1
+ import warnings
2
+
3
+ class LineSightConvergenceWarning(UserWarning):
4
+ """
5
+ Issued (not raised) when the model may not have converged.
6
+ Use warnings.warn(..., LineSightConvergenceWarning) to issue it.
7
+ Does not stop execution.
8
+ """
9
+ pass
@@ -0,0 +1,6 @@
1
+ class LineSightDataWarning(UserWarning):
2
+ """
3
+ Issued (not raised) when data has potential issues that will not crash
4
+ the model but may produce poor results.
5
+ """
6
+ pass
@@ -0,0 +1,5 @@
1
+ class LineSightGradientError(Exception):
2
+ """
3
+ Raised when gradient descent diverges and losses go to infinity/NaN.
4
+ """
5
+ pass
@@ -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,5 @@
1
+ from linesight.metrics.mse import mse
2
+ from linesight.metrics.rmse import rmse
3
+ from linesight.metrics.mae import mae
4
+ from linesight.metrics.r2 import r2
5
+ from linesight.metrics.accuracy import accuracy
@@ -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,5 @@
1
+ import numpy as np
2
+
3
+ def mae(y_true: np.ndarray, y_pred: np.ndarray) -> float:
4
+ """Mean Absolute Error. Formula: (1/n) * sum(|y_true - y_pred|)"""
5
+ return float(np.mean(np.abs(y_true - y_pred)))
@@ -0,0 +1,5 @@
1
+ import numpy as np
2
+
3
+ def mse(y_true: np.ndarray, y_pred: np.ndarray) -> float:
4
+ """Mean Squared Error. Formula: (1/n) * sum((y_true - y_pred)^2)"""
5
+ return float(np.mean((y_true - y_pred) ** 2))
@@ -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
+ import numpy as np
2
+ from linesight.metrics.mse import mse
3
+
4
+ def rmse(y_true: np.ndarray, y_pred: np.ndarray) -> float:
5
+ """Root Mean Squared Error. Square root of MSE."""
6
+ return float(np.sqrt(mse(y_true, y_pred)))
@@ -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