Talip7/scikit-learn-issues-multilabel huggingface dataset:
Add documentation about re-building extensions to "Installing the development version of scikit-learn"

### Describe the issue linked to the documentation

Quite regularly when contributing to scikit-learn I realise that I need to re-build the Cython extensions. I realise this when I run pytest and get an import error. When I started contributing, I didn't know about this and I would have been rather lost when I faced this error the first time if @adrinjalali didn't tell me how to fix this. As many people will face the same issue (especially people from underrepresented groups in tech because they're often career changers), a note about re-building the extensions should be put in the documentation. The pandas team for example now recommends to their contributors to do this after each fetch and merge from `upstream/main`: https://pandas.pydata.org/docs/dev/development/contributing_environment.html#step-3-build-and-install-pandas

### Suggest a potential alternative/fix

I think the best place to make a note about this is here in the "Note" box under point 7: https://scikit-learn.org/dev/developers/advanced_installation.html#building-from-source
Similar to the pandas documentation, it could be recommended here to run `make in` after each fetch and merge (or pull) from `upstream/main`. Additionally, it could be recommended to run `make clean` in case people run into unexpected errors after pulling from `upstream/main`.

COMMENT:
I'm closing this issue now as it's solved. Note, I also updated the documentation here: https://github.com/scikit-learn-inria-fondation/EuroSciPy22/pull/3

Labels: Documentation
Add functions for calculating log-likelihood and null log-likelihood

### Describe the workflow you want to enable

As a user of Scikit-learn, I want to be able to calculate the McFadden's pseudo R-squared for a binary logistic regression model for that we need log-likelihood and null log-likelihood.

### Describe your proposed solution

I use the following functions and I propose to add them in the library as well.  

### For Log Likelihood - 
```python
import numpy as np
from sklearn.linear_model import LogisticRegression

def log_likelihood(model, X, y):
    """Calculate the log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    model : sklearn.linear_model.LogisticRegression
        A trained binary logistic regression model.
    X : array-like, shape (n_samples, n_features)
        Feature matrix.
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    log_likelihood : float
        The log-likelihood of the model.
    """

    # Get predicted probabilities
    pred_probs = model.predict_proba(X)[:, 1]

    # Calculate log-likelihood
    log_likelihood = np.sum(y * np.log(pred_probs) + (1 - y) * np.log(1 - pred_probs))

    return log_likelihood

```
### For Null Log Likelihood - 
```python
import numpy as np
from sklearn.metrics import log_loss

def null_log_likelihood(y):
    """Calculate the null log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    null_log_likelihood : float
        The null log-likelihood of the model.
    """

    # Calculate the proportion of positive class labels
    p0 = y.mean()

    # Create an array of predicted probabilities equal to the proportion of positive class labels
    probs = p0 * np.ones_like(y)

    # Calculate the null log-likelihood using the log_loss function from scikit-learn
    null_log_likelihood = -log_loss(y, probs, normalize=False)

    return null_log_likelihood

```

### Describe alternatives you've considered, if relevant

One alternative to adding these functions to Scikit-learn would be for users to use  [statsmodels](https://www.statsmodels.org/stable/about.html#about-statsmodels). 
However, adding these functions to Scikit-learn would make it easier for users to calculate log-likelihood and null log-likelihood within the Scikit-learn ecosystem and would provide a standardized implementation. 

### Additional context

_No response_

COMMENT:
You may initiate a PR on this for review?

Labels: New Feature, module:linear_model, module:metrics, Needs Decision - Include Feature
Add functions for calculating log-likelihood and null log-likelihood

### Describe the workflow you want to enable

As a user of Scikit-learn, I want to be able to calculate the McFadden's pseudo R-squared for a binary logistic regression model for that we need log-likelihood and null log-likelihood.

### Describe your proposed solution

I use the following functions and I propose to add them in the library as well.  

### For Log Likelihood - 
```python
import numpy as np
from sklearn.linear_model import LogisticRegression

def log_likelihood(model, X, y):
    """Calculate the log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    model : sklearn.linear_model.LogisticRegression
        A trained binary logistic regression model.
    X : array-like, shape (n_samples, n_features)
        Feature matrix.
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    log_likelihood : float
        The log-likelihood of the model.
    """

    # Get predicted probabilities
    pred_probs = model.predict_proba(X)[:, 1]

    # Calculate log-likelihood
    log_likelihood = np.sum(y * np.log(pred_probs) + (1 - y) * np.log(1 - pred_probs))

    return log_likelihood

```
### For Null Log Likelihood - 
```python
import numpy as np
from sklearn.metrics import log_loss

def null_log_likelihood(y):
    """Calculate the null log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    null_log_likelihood : float
        The null log-likelihood of the model.
    """

    # Calculate the proportion of positive class labels
    p0 = y.mean()

    # Create an array of predicted probabilities equal to the proportion of positive class labels
    probs = p0 * np.ones_like(y)

    # Calculate the null log-likelihood using the log_loss function from scikit-learn
    null_log_likelihood = -log_loss(y, probs, normalize=False)

    return null_log_likelihood

```

### Describe alternatives you've considered, if relevant

One alternative to adding these functions to Scikit-learn would be for users to use  [statsmodels](https://www.statsmodels.org/stable/about.html#about-statsmodels). 
However, adding these functions to Scikit-learn would make it easier for users to calculate log-likelihood and null log-likelihood within the Scikit-learn ecosystem and would provide a standardized implementation. 

### Additional context

_No response_

COMMENT:
There already is a [`log_loss` function in the metrics module](https://scikit-learn.org/stable/modules/generated/sklearn.metrics.log_loss.html) of scikit-learn. Naively I'd assume this would also work for your case. Could you explain in a bit more detail why you can't use that function instead of adding a new one?

Labels: New Feature, module:linear_model, module:metrics, Needs Decision - Include Feature
Add functions for calculating log-likelihood and null log-likelihood

### Describe the workflow you want to enable

As a user of Scikit-learn, I want to be able to calculate the McFadden's pseudo R-squared for a binary logistic regression model for that we need log-likelihood and null log-likelihood.

### Describe your proposed solution

I use the following functions and I propose to add them in the library as well.  

### For Log Likelihood - 
```python
import numpy as np
from sklearn.linear_model import LogisticRegression

def log_likelihood(model, X, y):
    """Calculate the log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    model : sklearn.linear_model.LogisticRegression
        A trained binary logistic regression model.
    X : array-like, shape (n_samples, n_features)
        Feature matrix.
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    log_likelihood : float
        The log-likelihood of the model.
    """

    # Get predicted probabilities
    pred_probs = model.predict_proba(X)[:, 1]

    # Calculate log-likelihood
    log_likelihood = np.sum(y * np.log(pred_probs) + (1 - y) * np.log(1 - pred_probs))

    return log_likelihood

```
### For Null Log Likelihood - 
```python
import numpy as np
from sklearn.metrics import log_loss

def null_log_likelihood(y):
    """Calculate the null log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    null_log_likelihood : float
        The null log-likelihood of the model.
    """

    # Calculate the proportion of positive class labels
    p0 = y.mean()

    # Create an array of predicted probabilities equal to the proportion of positive class labels
    probs = p0 * np.ones_like(y)

    # Calculate the null log-likelihood using the log_loss function from scikit-learn
    null_log_likelihood = -log_loss(y, probs, normalize=False)

    return null_log_likelihood

```

### Describe alternatives you've considered, if relevant

One alternative to adding these functions to Scikit-learn would be for users to use  [statsmodels](https://www.statsmodels.org/stable/about.html#about-statsmodels). 
However, adding these functions to Scikit-learn would make it easier for users to calculate log-likelihood and null log-likelihood within the Scikit-learn ecosystem and would provide a standardized implementation. 

### Additional context

_No response_

COMMENT:
Thank you for your comment @betatim . I want to measure the [goodness of fit](https://support.sas.com/resources/papers/proceedings14/1485-2014.pdf) of a logistic regression model. However, I think the log_loss function measures the difference between the predicted probabilities and the actual outcomes. 

Alternatively, can we have a metric to directly calculate the Pseudo R-square?

Labels: New Feature, module:linear_model, module:metrics, Needs Decision - Include Feature
Add functions for calculating log-likelihood and null log-likelihood

### Describe the workflow you want to enable

As a user of Scikit-learn, I want to be able to calculate the McFadden's pseudo R-squared for a binary logistic regression model for that we need log-likelihood and null log-likelihood.

### Describe your proposed solution

I use the following functions and I propose to add them in the library as well.  

### For Log Likelihood - 
```python
import numpy as np
from sklearn.linear_model import LogisticRegression

def log_likelihood(model, X, y):
    """Calculate the log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    model : sklearn.linear_model.LogisticRegression
        A trained binary logistic regression model.
    X : array-like, shape (n_samples, n_features)
        Feature matrix.
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    log_likelihood : float
        The log-likelihood of the model.
    """

    # Get predicted probabilities
    pred_probs = model.predict_proba(X)[:, 1]

    # Calculate log-likelihood
    log_likelihood = np.sum(y * np.log(pred_probs) + (1 - y) * np.log(1 - pred_probs))

    return log_likelihood

```
### For Null Log Likelihood - 
```python
import numpy as np
from sklearn.metrics import log_loss

def null_log_likelihood(y):
    """Calculate the null log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    null_log_likelihood : float
        The null log-likelihood of the model.
    """

    # Calculate the proportion of positive class labels
    p0 = y.mean()

    # Create an array of predicted probabilities equal to the proportion of positive class labels
    probs = p0 * np.ones_like(y)

    # Calculate the null log-likelihood using the log_loss function from scikit-learn
    null_log_likelihood = -log_loss(y, probs, normalize=False)

    return null_log_likelihood

```

### Describe alternatives you've considered, if relevant

One alternative to adding these functions to Scikit-learn would be for users to use  [statsmodels](https://www.statsmodels.org/stable/about.html#about-statsmodels). 
However, adding these functions to Scikit-learn would make it easier for users to calculate log-likelihood and null log-likelihood within the Scikit-learn ecosystem and would provide a standardized implementation. 

### Additional context

_No response_

COMMENT:
If I look at the code of your `log_likelihood(model, X, y)` I think you can perform the same computation using the `log_loss` that already exists.

Labels: New Feature, module:linear_model, module:metrics, Needs Decision - Include Feature
Add functions for calculating log-likelihood and null log-likelihood

### Describe the workflow you want to enable

As a user of Scikit-learn, I want to be able to calculate the McFadden's pseudo R-squared for a binary logistic regression model for that we need log-likelihood and null log-likelihood.

### Describe your proposed solution

I use the following functions and I propose to add them in the library as well.  

### For Log Likelihood - 
```python
import numpy as np
from sklearn.linear_model import LogisticRegression

def log_likelihood(model, X, y):
    """Calculate the log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    model : sklearn.linear_model.LogisticRegression
        A trained binary logistic regression model.
    X : array-like, shape (n_samples, n_features)
        Feature matrix.
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    log_likelihood : float
        The log-likelihood of the model.
    """

    # Get predicted probabilities
    pred_probs = model.predict_proba(X)[:, 1]

    # Calculate log-likelihood
    log_likelihood = np.sum(y * np.log(pred_probs) + (1 - y) * np.log(1 - pred_probs))

    return log_likelihood

```
### For Null Log Likelihood - 
```python
import numpy as np
from sklearn.metrics import log_loss

def null_log_likelihood(y):
    """Calculate the null log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    null_log_likelihood : float
        The null log-likelihood of the model.
    """

    # Calculate the proportion of positive class labels
    p0 = y.mean()

    # Create an array of predicted probabilities equal to the proportion of positive class labels
    probs = p0 * np.ones_like(y)

    # Calculate the null log-likelihood using the log_loss function from scikit-learn
    null_log_likelihood = -log_loss(y, probs, normalize=False)

    return null_log_likelihood

```

### Describe alternatives you've considered, if relevant

One alternative to adding these functions to Scikit-learn would be for users to use  [statsmodels](https://www.statsmodels.org/stable/about.html#about-statsmodels). 
However, adding these functions to Scikit-learn would make it easier for users to calculate log-likelihood and null log-likelihood within the Scikit-learn ecosystem and would provide a standardized implementation. 

### Additional context

_No response_

COMMENT:
> However, I was wondering if we have an inbuilt function to compute pseudo R-squared, if not what might be the reason of not having it?

I don't know the answer to that. I think there isn't a lot of "goodness of fit" tooling in scikit-learn because there are other libraries that do that.

Labels: New Feature, module:linear_model, module:metrics, Needs Decision - Include Feature
Add functions for calculating log-likelihood and null log-likelihood

### Describe the workflow you want to enable

As a user of Scikit-learn, I want to be able to calculate the McFadden's pseudo R-squared for a binary logistic regression model for that we need log-likelihood and null log-likelihood.

### Describe your proposed solution

I use the following functions and I propose to add them in the library as well.  

### For Log Likelihood - 
```python
import numpy as np
from sklearn.linear_model import LogisticRegression

def log_likelihood(model, X, y):
    """Calculate the log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    model : sklearn.linear_model.LogisticRegression
        A trained binary logistic regression model.
    X : array-like, shape (n_samples, n_features)
        Feature matrix.
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    log_likelihood : float
        The log-likelihood of the model.
    """

    # Get predicted probabilities
    pred_probs = model.predict_proba(X)[:, 1]

    # Calculate log-likelihood
    log_likelihood = np.sum(y * np.log(pred_probs) + (1 - y) * np.log(1 - pred_probs))

    return log_likelihood

```
### For Null Log Likelihood - 
```python
import numpy as np
from sklearn.metrics import log_loss

def null_log_likelihood(y):
    """Calculate the null log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    null_log_likelihood : float
        The null log-likelihood of the model.
    """

    # Calculate the proportion of positive class labels
    p0 = y.mean()

    # Create an array of predicted probabilities equal to the proportion of positive class labels
    probs = p0 * np.ones_like(y)

    # Calculate the null log-likelihood using the log_loss function from scikit-learn
    null_log_likelihood = -log_loss(y, probs, normalize=False)

    return null_log_likelihood

```

### Describe alternatives you've considered, if relevant

One alternative to adding these functions to Scikit-learn would be for users to use  [statsmodels](https://www.statsmodels.org/stable/about.html#about-statsmodels). 
However, adding these functions to Scikit-learn would make it easier for users to calculate log-likelihood and null log-likelihood within the Scikit-learn ecosystem and would provide a standardized implementation. 

### Additional context

_No response_

COMMENT:
Metrics in the `sklearn.metrics` must be general enough to work with all models and not just linear models. In practice, I only seen pseudo R-squared applied to linear models. @AnkurSingh282000 Have you come across literature that applies pseudo R-squared to other models such as tree based models? 

@lorentzenchr What do you think of providing a pseudo R-squared to the models in `sklearn.linear_model`?

Labels: New Feature, module:linear_model, module:metrics, Needs Decision - Include Feature
Add functions for calculating log-likelihood and null log-likelihood

### Describe the workflow you want to enable

As a user of Scikit-learn, I want to be able to calculate the McFadden's pseudo R-squared for a binary logistic regression model for that we need log-likelihood and null log-likelihood.

### Describe your proposed solution

I use the following functions and I propose to add them in the library as well.  

### For Log Likelihood - 
```python
import numpy as np
from sklearn.linear_model import LogisticRegression

def log_likelihood(model, X, y):
    """Calculate the log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    model : sklearn.linear_model.LogisticRegression
        A trained binary logistic regression model.
    X : array-like, shape (n_samples, n_features)
        Feature matrix.
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    log_likelihood : float
        The log-likelihood of the model.
    """

    # Get predicted probabilities
    pred_probs = model.predict_proba(X)[:, 1]

    # Calculate log-likelihood
    log_likelihood = np.sum(y * np.log(pred_probs) + (1 - y) * np.log(1 - pred_probs))

    return log_likelihood

```
### For Null Log Likelihood - 
```python
import numpy as np
from sklearn.metrics import log_loss

def null_log_likelihood(y):
    """Calculate the null log-likelihood of a binary logistic regression model.

    Parameters
    ----------
    y : array-like, shape (n_samples,)
        Binary class labels.

    Returns
    -------
    null_log_likelihood : float
        The null log-likelihood of the model.
    """

    # Calculate the proportion of positive class labels
    p0 = y.mean()

    # Create an array of predicted probabilities equal to the proportion of positive class labels
    probs = p0 * np.ones_like(y)

    # Calculate the null log-likelihood using the log_loss function from scikit-learn
    null_log_likelihood = -log_loss(y, probs, normalize=False)

    return null_log_likelihood

```

### Describe alternatives you've considered, if relevant

One alternative to adding these functions to Scikit-learn would be for users to use  [statsmodels](https://www.statsmodels.org/stable/about.html#about-statsmodels). 
However, adding these functions to Scikit-learn would make it easier for users to calculate log-likelihood and null log-likelihood within the Scikit-learn ecosystem and would provide a standardized implementation. 

### Additional context

_No response_

COMMENT:
Such a metric `d2_log_loss` is proposed in #20943. It‘s only a matter of someone implementing it.

> I want to measure the goodness of fit of a logistic regression model. However, I think the log_loss function measures the difference between the predicted probabilities and the actual outcomes.

Note that a „good“ GOF does exactly that: it measures some kind of „distance“ between observations and predictions.

I think we can close then?

Labels: New Feature, module:linear_model, module:metrics, Needs Decision - Include Feature