Skip to content

Commit 08a6a8d

Browse files
committed
Resolve merge conflicts: Keep upstream code, keep local doc improvements
1 parent c63c165 commit 08a6a8d

3 files changed

Lines changed: 236 additions & 123 deletions

File tree

doc/source/autoapi/rehline/index.rst

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -573,13 +573,13 @@ Classes
573573

574574
Attributes
575575
----------
576-
coef\_ : ndarray of shape (n_features,)
576+
coef_ : ndarray of shape (n_features,)
577577
Coefficients excluding the intercept.
578578

579-
intercept\_ : float
579+
intercept_ : float
580580
Intercept term. 0.0 if ``fit_intercept=False``.
581581

582-
classes\_ : ndarray of shape (2,)
582+
classes_ : ndarray of shape (2,)
583583
Unique class labels in the original label space.
584584

585585
_label_encoder : LabelEncoder
@@ -692,7 +692,7 @@ Classes
692692
- ``{'name': 'nonnegative'}`` or ``{'name': '>=0'}``
693693
- ``{'name': 'fair', 'sen_idx': list[int], 'tol_sen': list[float]}``
694694
- ``{'name': 'custom', 'A': ndarray[K, d], 'b': ndarray[K]}``
695-
695+
696696
Note: when ``fit_intercept=True``, a constant column is appended **as the last column**;
697697
since you index sensitive columns by ``sen_idx`` on the *original* features, indices stay valid.
698698
C : float, default=1.0
@@ -722,11 +722,11 @@ Classes
722722

723723
Attributes
724724
----------
725-
coef\_ : ndarray of shape (n_features,)
725+
coef_ : ndarray of shape (n_features,)
726726
Learned linear coefficients (excluding the intercept term).
727-
intercept\_ : float
727+
intercept_ : float
728728
Intercept term extracted from the last coefficient when ``fit_intercept=True``, otherwise 0.0.
729-
n_features_in\_ : int
729+
n_features_in_ : int
730730
Number of input features seen during :meth:`fit` (before intercept augmentation).
731731

732732
Notes
@@ -748,7 +748,7 @@ Classes
748748
* - :py:obj:`fit <rehline.plq_Ridge_Regressor.fit>`\ (X, y, sample_weight)
749749
- If ``fit_intercept=True``, a constant column (value = ``intercept_scaling``) is appended
750750
* - :py:obj:`decision_function <rehline.plq_Ridge_Regressor.decision_function>`\ (X)
751-
- Compute f(X) = X @ coef\_ + intercept\_.
751+
- Compute f(X) = X @ coef_ + intercept_.
752752
* - :py:obj:`predict <rehline.plq_Ridge_Regressor.predict>`\ (X)
753753
- Predict targets as the linear decision function.
754754

@@ -782,7 +782,7 @@ Classes
782782

783783
.. py:method:: decision_function(X)
784784
785-
Compute f(X) = X @ coef\_ + intercept\_.
785+
Compute f(X) = X @ coef_ + intercept_.
786786

787787
Parameters
788788
----------
@@ -798,6 +798,7 @@ Classes
798798
.. py:method:: predict(X)
799799
800800
Predict targets as the linear decision function.
801+
801802
Parameters
802803
----------
803804
X : ndarray of shape (n_samples, n_features)
@@ -811,17 +812,17 @@ Classes
811812

812813

813814

814-
.. py:class:: plqMF_Ridge(n_users, n_items, loss, constraint=[], biased=True, rank=10, C=1.0, rho=0.5, init_mean=0.0, init_sd=0.1, random_state=None, max_iter=10000, tol=0.0001, shrink=1, trace_freq=100, max_iter_CD=10, tol_CD=0.0001, verbose=0)
815+
.. py:class:: plqMF_Ridge(n_users, n_items, loss, biased=True, constraint_user=[], constraint_item=[], rank=10, C=1.0, rho=0.5, init_mean=0.0, init_sd=0.1, random_state=None, max_iter=10000, tol=0.0001, shrink=1, trace_freq=100, max_iter_CD=10, tol_CD=0.0001, verbose=0)
815816
816817
Bases: :py:obj:`rehline._base._BaseReHLine`, :py:obj:`sklearn.base.BaseEstimator`
817818

818819
Matrix Factorization (MF) with a piecewise linear-quadratic objective and ridge penalty.
819820

820821
.. math::
821822
\min_{\substack{
822-
\mathbf{P} \in \mathbb{R}^{n \times r}\
823+
\mathbf{P} \in \mathbb{R}^{n \times k}\
823824
\pmb{\alpha} \in \mathbb{R}^n \\
824-
\mathbf{Q} \in \mathbb{R}^{m \times r}\
825+
\mathbf{Q} \in \mathbb{R}^{m \times k}\
825826
\pmb{\beta} \in \mathbb{R}^m
826827
}}
827828
\left[
@@ -835,21 +836,15 @@ Classes
835836
836837
.. math::
837838
\ \text{ s.t. } \
838-
\mathbf{A} \begin{bmatrix}
839-
\pmb{\alpha} & \mathbf{P}
840-
\end{bmatrix}^T +
841-
\mathbf{b}\mathbf{1}_{n}^T \geq \mathbf{0}
842-
\ \text{ and } \
843-
\mathbf{A} \begin{bmatrix}
844-
\pmb{\beta} & \mathbf{Q}
845-
\end{bmatrix}^T +
846-
\mathbf{b}\mathbf{1}_{m}^T \geq \mathbf{0}
839+
\mathbf{A}_{\text{user}} \begin{pmatrix} \alpha_u \\ \mathbf{p}_u \end{pmatrix} + \mathbf{b}_{\text{user}} \geq \mathbf{0},\ u = 1,\dots,n
840+
\quad \text{and} \quad
841+
\mathbf{A}_{\text{item}} \begin{pmatrix} \beta_i \\ \mathbf{q}_i \end{pmatrix} + \mathbf{b}_{\text{item}} \geq \mathbf{0},\ i = 1,\dots,m
847842
848843
The function supports various loss functions, including:
849844
- 'hinge', 'svm' or 'SVM'
850845
- 'MAE' or 'mae' or 'mean absolute error'
851-
- 'hinge square' or 'svm square' or 'SVM square'
852-
- 'MSE' or 'mse' or 'mean square error'
846+
- 'squared hinge' or 'squared svm' or 'squared SVM'
847+
- 'MSE' or 'mse' or 'mean squared error'
853848

854849
The following constraint types are supported:
855850
* 'nonnegative' or '>=0': A non-negativity constraint.
@@ -867,8 +862,12 @@ Classes
867862
loss : dict
868863
A dictionary specifying the loss function parameters.
869864

870-
constraint : list of dict
871-
A list of dictionaries, where each dictionary represents a constraint.
865+
constraint_user : list of dict
866+
A list of dictionaries, where each dictionary represents a constraint to user side parameters.
867+
Each dictionary must contain a 'name' key, which specifies the type of constraint.
868+
869+
constraint_item : list of dict
870+
A list of dictionaries, where each dictionary represents a constraint to item side parameters.
872871
Each dictionary must contain a 'name' key, which specifies the type of constraint.
873872

874873
biased : bool, default=True
@@ -965,7 +964,7 @@ Classes
965964
decision_function(X)
966965
The decision function evaluated on the given dataset.
967966

968-
obj(X, y, loss))
967+
obj(X, y)
969968
Compute the values of loss term and objective function.
970969

971970
Notes
@@ -987,7 +986,7 @@ Classes
987986
- Fit the model based on the given training data.
988987
* - :py:obj:`decision_function <rehline.plqMF_Ridge.decision_function>`\ (X)
989988
- The decision function evaluated on the given dataset
990-
* - :py:obj:`obj <rehline.plqMF_Ridge.obj>`\ (X, y, loss)
989+
* - :py:obj:`obj <rehline.plqMF_Ridge.obj>`\ (X, y)
991990
- Compute the values of loss term and objective function.
992991

993992

@@ -1034,7 +1033,7 @@ Classes
10341033
Predicted ratings for the input pairs.
10351034

10361035

1037-
.. py:method:: obj(X, y, loss)
1036+
.. py:method:: obj(X, y)
10381037
10391038
Compute the values of loss term and objective function.
10401039

@@ -1045,9 +1044,6 @@ Classes
10451044

10461045
y : array-like of shape (n_ratings,)
10471046
Actual rating values.
1048-
1049-
loss : dict
1050-
A dictionary specifying the loss function parameters.
10511047

10521048
Returns
10531049
-------
Lines changed: 86 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,103 @@
11
Constraint
22
**********
33

4-
Supported linear constraints in ReHLine are listed in the table below.
4+
ReHLine allows you to impose various linear constraints on the model coefficients.
55

6-
Usage
7-
-----
6+
Usage Pattern
7+
-------------
88

9-
.. code:: python
9+
Define constraints as a list of dictionaries:
1010

11-
# list of
12-
# name (str): name of the custom linear constraints
13-
# loss_kwargs: more keys and values for constraint parameters
14-
constraint = [{'name': <constraint_name>, <**constraint_kwargs>}, ...]
11+
.. code-block:: python
1512
16-
.. list-table::
17-
:align: left
18-
:widths: 5 20 15
19-
:header-rows: 1
13+
# list of constraint dictionaries
14+
constraint = [{'name': <constraint_name>, **kwargs}, ...]
2015
21-
* - constraint
22-
- | args
23-
- | Example
2416
25-
* - **nonnegative**
26-
- | ``name``: 'nonnegative' or '>=0'
27-
- | ``constraint=[{'name': '>=0'}]``
17+
Supported Constraints
18+
---------------------
2819

29-
* - **fair**
30-
- | ``name``: 'fair' or 'fairness'
31-
| ``sen_idx``: a list contains column indices for sensitive attributes
32-
| ``tol_sen``: 1d array [p] of tolerance for fairness
33-
- | ``constraint=[{'name': 'fair', 'sen_idx': sen_idx, 'tol_sen': tol_sen}]``
20+
Non-negative
21+
^^^^^^^^^^^^
22+
Constrains all coefficients to be non-negative (:math:`\beta_j \ge 0`) [1]_.
3423

35-
* - **monotonic**
36-
- | ``name``: 'monotonic' or 'monotonicity'
37-
| ``decreasing`` (*bool*): False (default)
38-
- | ``constraint=[{'name': 'monotonic', 'decreasing': True}]``
24+
* **Names**: ``'nonnegative'``, ``'>=0'``
25+
* **Parameters**: None
3926

40-
* - **custom**
41-
- | ``name``: 'custom'
42-
| ``A``: 2d array [K x d] for linear constraint coefficients
43-
| ``b``: 1d array [K] of constraint intercepts
44-
- | ``constraint=[{'name': 'custom', 'A': A, 'b': b}]``
27+
.. code-block:: python
4528
46-
Related Examples
47-
----------------
29+
constraint = [{'name': '>=0'}]
30+
31+
**Related Example**
4832

4933
.. nblinkgallery::
50-
:caption: Constraints
51-
:name: rst-link-gallery
34+
:name: nmf-gallery
5235

53-
../examples/FairSVM.ipynb
5436
../examples/NMF.ipynb
37+
38+
Fairness
39+
^^^^^^^^
40+
Constrains the correlation between predictions and sensitive attributes to be within a tolerance [2]_.
41+
42+
* **Names**: ``'fair'``, ``'fairness'``
43+
* **Parameters**:
44+
* ``sen_idx`` (*list of int*): Column indices of sensitive attributes in ``X``.
45+
* ``tol_sen`` (*list of float*): Tolerance thresholds for each sensitive attribute.
46+
47+
.. code-block:: python
48+
49+
# Example: Constrain fairness w.r.t. feature at index 0 with tolerance 0.01
50+
constraint = [{'name': 'fair', 'sen_idx': [0], 'tol_sen': [0.01]}]
51+
52+
**Related Example**
53+
54+
.. nblinkgallery::
55+
:name: fair-gallery
56+
57+
../examples/FairSVM.ipynb
58+
59+
Monotonicity
60+
^^^^^^^^^^^^
61+
Constrains coefficients to be monotonically increasing or decreasing [3]_.
62+
Increasing: :math:`\beta_i \le \beta_{i+1}`. Decreasing: :math:`\beta_i \ge \beta_{i+1}`.
63+
64+
* **Names**: ``'monotonic'``, ``'monotonicity'``
65+
* **Parameters**:
66+
* ``decreasing`` (*bool*, default=False): If ``True``, enforces decreasing monotonicity.
67+
68+
.. code-block:: python
69+
70+
# Monotonically increasing
71+
constraint = [{'name': 'monotonic'}]
72+
73+
# Monotonically decreasing
74+
constraint = [{'name': 'monotonic', 'decreasing': True}]
75+
76+
Custom Constraints
77+
^^^^^^^^^^^^^^^^^^
78+
Define arbitrary linear constraints of the form :math:`A\beta + b \ge 0`.
79+
80+
* **Names**: ``'custom'``
81+
* **Parameters**:
82+
* ``A`` (*ndarray*): Coefficient matrix of shape (K, d).
83+
* ``b`` (*ndarray*): Intercept vector of shape (K,).
84+
85+
.. code-block:: python
86+
87+
import numpy as np
88+
89+
# Example: beta_0 + beta_1 >= 1
90+
A = np.zeros((1, d))
91+
A[0, 0] = 1
92+
A[0, 1] = 1
93+
b = np.array([-1.0])
94+
95+
constraint = [{'name': 'custom', 'A': A, 'b': b}]
96+
97+
98+
References
99+
----------
100+
101+
.. [1] `Lee, D. D., & Seung, H. S. (1999). Learning the parts of objects by non-negative matrix factorization. Nature, 401(6755), 788-791. <https://www.nature.com/articles/44565>`_
102+
.. [2] `Zafar, M. B., Valera, I., Gomez Rodriguez, M., & Gummadi, K. P. (2019). Fairness Constraints: A Flexible Approach for Fair Classification. Journal of Machine Learning Research, 20(75), 1-42. <https://www.jmlr.org/papers/v20/18-262.html>`_
103+
.. [3] `Nature Research Intelligence. Monotonicity Constraints in Machine Learning and Classification. <https://www.nature.com/research-intelligence/nri-topic-summaries/monotonicity-constraints-in-machine-learning-and-classification-micro-23773>`_

0 commit comments

Comments
 (0)