



'''simple docstring'''





import logging

import numpy as np
import pytest
from scipy.linalg import eigh

logging.basicConfig(level=logging.INFO, format='''%(message)s''')
def        _SCREAMING_SNAKE_CASE  (	UpperCamelCase      ):



    """simple docstring"""





    return input_array.reshape((input_array.size, 1)      )
def        _SCREAMING_SNAKE_CASE  (	UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase      ):



    """simple docstring"""





    lowerCAmelCase__			:  List[Any]											= np.nan
    for i in range(UpperCamelCase      ):
        lowerCAmelCase__			:  List[Any]											= features[:, labels == i]
        lowerCAmelCase__			:  List[Any]											= data.mean(1      )
        # Centralize the data of class i
        lowerCAmelCase__			:  Union[str, Any]											= data - column_reshape(UpperCamelCase      )
        if i > 0:
            # If covariance_sum is not None
            covariance_sum += np.dot(UpperCamelCase							,   centered_data.T      )
        else:
            # If covariance_sum is np.nan (i.e. first loop)
            lowerCAmelCase__			:  Union[str, Any]											= np.dot(UpperCamelCase							,   centered_data.T      )

    return covariance_sum / features.shape[1]
def        _SCREAMING_SNAKE_CASE  (	UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase      ):



    """simple docstring"""





    lowerCAmelCase__			:  str											= features.mean(1      )
    lowerCAmelCase__			:  Dict											= np.nan
    for i in range(UpperCamelCase      ):
        lowerCAmelCase__			:  str											= features[:, labels == i]
        lowerCAmelCase__			:  List[str]											= data.shape[1]
        lowerCAmelCase__			:  Tuple											= data.mean(1      )
        if i > 0:
            # If covariance_sum is not None
            covariance_sum += device_data * np.dot(
                column_reshape(UpperCamelCase      ) - column_reshape(UpperCamelCase      )							,   (column_reshape(UpperCamelCase      ) - column_reshape(UpperCamelCase      )).T							,   )
        else:
            # If covariance_sum is np.nan (i.e. first loop)
            lowerCAmelCase__			:  Dict											= device_data * np.dot(
                column_reshape(UpperCamelCase      ) - column_reshape(UpperCamelCase      )							,   (column_reshape(UpperCamelCase      ) - column_reshape(UpperCamelCase      )).T							,   )

    return covariance_sum / features.shape[1]
def        _SCREAMING_SNAKE_CASE  (	UpperCamelCase							,   UpperCamelCase      ):



    """simple docstring"""





    if features.any():
        lowerCAmelCase__			:  Union[str, Any]											= features.mean(1      )
        # Center the dataset
        lowerCAmelCase__			:  Union[str, Any]											= features - np.reshape(UpperCamelCase							,   (data_mean.size, 1)      )
        lowerCAmelCase__			:  str											= np.dot(UpperCamelCase							,   centered_data.T      ) / features.shape[1]
        lowerCAmelCase__				,       lowerCAmelCase__			:  int											= np.linalg.eigh(UpperCamelCase      )
        # Take all the columns in the reverse order (-1), and then takes only the first
        lowerCAmelCase__			:  Union[str, Any]											= eigenvectors[:, ::-1][:, 0:dimensions]
        # Project the database on the new space
        lowerCAmelCase__			:  Any											= np.dot(filtered_eigenvectors.T							,   UpperCamelCase      )
        logging.info("""Principal Component Analysis computed"""      )

        return projected_data
    else:
        logging.basicConfig(level=logging.ERROR							,   format="""%(message)s"""							,   force=UpperCamelCase      )
        logging.error("""Dataset empty"""      )
        raise AssertionError
def        _SCREAMING_SNAKE_CASE  (	UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase      ):



    """simple docstring"""





    assert classes > dimensions

    # Check if features have been already loaded
    if features.any:
        lowerCAmelCase__				,       lowerCAmelCase__			:  Optional[Any]											= eigh(
            covariance_between_classes(UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase      )							,   covariance_within_classes(UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase      )							,   )
        lowerCAmelCase__			:  Optional[Any]											= eigenvectors[:, ::-1][:, :dimensions]
        lowerCAmelCase__				,       lowerCAmelCase__				,       lowerCAmelCase__			:  Union[str, Any]											= np.linalg.svd(UpperCamelCase      )
        lowerCAmelCase__			:  Optional[Any]											= svd_matrix[:, 0:dimensions]
        lowerCAmelCase__			:  Any											= np.dot(filtered_svd_matrix.T							,   UpperCamelCase      )
        logging.info("""Linear Discriminant Analysis computed"""      )

        return projected_data
    else:
        logging.basicConfig(level=logging.ERROR							,   format="""%(message)s"""							,   force=UpperCamelCase      )
        logging.error("""Dataset empty"""      )
        raise AssertionError
def        _SCREAMING_SNAKE_CASE  (	):



    """simple docstring"""





    lowerCAmelCase__			:  Union[str, Any]											= np.array([[1, 2, 3, 4, 5], [2, 3, 4, 5, 6], [3, 4, 5, 6, 7]]      )
    lowerCAmelCase__			:  int											= np.array([0, 0, 0, 1, 1]      )
    lowerCAmelCase__			:  str											= 2
    lowerCAmelCase__			:  Tuple											= 2

    # Assert that the function raises an AssertionError if dimensions > classes
    with pytest.raises(UpperCamelCase      ) as error_info:
        lowerCAmelCase__			:  Optional[Any]											= linear_discriminant_analysis(
            UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase      )
        if isinstance(UpperCamelCase							,   np.ndarray      ):
            raise AssertionError(
                """Did not raise AssertionError for dimensions > classes"""      )
        assert error_info.type is AssertionError
def        _SCREAMING_SNAKE_CASE  (	):



    """simple docstring"""





    lowerCAmelCase__			:  int											= np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]      )
    lowerCAmelCase__			:  str											= 2
    lowerCAmelCase__			:  Any											= np.array([[6.9282_0323, 8.6602_5404, 10.3923_0485], [3.0, 3.0, 3.0]]      )

    with pytest.raises(UpperCamelCase      ) as error_info:
        lowerCAmelCase__			:  Any											= principal_component_analysis(UpperCamelCase							,   UpperCamelCase      )
        if not np.allclose(UpperCamelCase							,   UpperCamelCase      ):
            raise AssertionError
        assert error_info.type is AssertionError


if __name__ == "__main__":
 import doctest

 doctest.testmod()







'''simple docstring'''





# Logistic Regression from scratch

# In[62]:

# In[63]:

# importing all the required libraries

import numpy as np
from matplotlib import pyplot as plt
from sklearn import datasets
def        _SCREAMING_SNAKE_CASE  (	UpperCamelCase      ):



    """simple docstring"""





    return 1 / (1 + np.exp(-z      ))
def        _SCREAMING_SNAKE_CASE  (	UpperCamelCase							,   UpperCamelCase      ):



    """simple docstring"""





    return (-y * np.log(UpperCamelCase      ) - (1 - y) * np.log(1 - h      )).mean()
def        _SCREAMING_SNAKE_CASE  (	UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase      ):



    """simple docstring"""





    lowerCAmelCase__			:  Union[str, Any]											= np.dot(UpperCamelCase							,   UpperCamelCase      )
    return np.sum(y * scores - np.log(1 + np.exp(UpperCamelCase      )      )      )
def        _SCREAMING_SNAKE_CASE  (	UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase							,   UpperCamelCase=70000      ):



    """simple docstring"""





    lowerCAmelCase__			:  Union[str, Any]											= np.zeros(x.shape[1]      )

    for iterations in range(UpperCamelCase      ):
        lowerCAmelCase__			:  str											= np.dot(UpperCamelCase							,   UpperCamelCase      )
        lowerCAmelCase__			:  Tuple											= sigmoid_function(UpperCamelCase      )
        lowerCAmelCase__			:  List[str]											= np.dot(x.T							,   h - y      ) / y.size
        lowerCAmelCase__			:  List[Any]											= theta - alpha * gradient  # updating the weights
        lowerCAmelCase__			:  List[Any]											= np.dot(UpperCamelCase							,   UpperCamelCase      )
        lowerCAmelCase__			:  List[Any]											= sigmoid_function(UpperCamelCase      )
        lowerCAmelCase__			:  List[Any]											= cost_function(UpperCamelCase							,   UpperCamelCase      )
        if iterations % 100 == 0:
            print(f"""loss: {j} \t"""      )  # printing the loss after every 100 iterations
    return theta


# In[68]:

if __name__ == "__main__":
 _lowerCAmelCase										=     datasets.load_iris()
 _lowerCAmelCase										=     iris.data[:, :2]
 _lowerCAmelCase										=     (iris.target != 0) * 1

 _lowerCAmelCase										=     0.1
 _lowerCAmelCase										=     logistic_reg(alpha, x, y, max_iterations=7_0000)
 print('''theta: ''', theta)  # printing the theta i.e our weights vector
 def        _SCREAMING_SNAKE_CASE  (	UpperCamelCase      ):



     """simple docstring"""





     return sigmoid_function(
         np.dot(UpperCamelCase							,   UpperCamelCase      )      )  # predicting the value of probability from the logistic regression algorithm

 plt.figure(figsize=(10, 6))
 plt.scatter(x[y == 0][:, 0], x[y == 0][:, 1], color='''b''', label='''0''')
 plt.scatter(x[y == 1][:, 0], x[y == 1][:, 1], color='''r''', label='''1''')
 ((_lowerCAmelCase)						,      (_lowerCAmelCase))										=     (x[:, 0].min(), x[:, 0].max())
 ((_lowerCAmelCase)						,      (_lowerCAmelCase))										=     (x[:, 1].min(), x[:, 1].max())
 ((_lowerCAmelCase)						,      (_lowerCAmelCase))										=     np.meshgrid(np.linspace(xa_min, xa_max), np.linspace(xa_min, xa_max))
 _lowerCAmelCase										=     np.c_[xxa.ravel(), xxa.ravel()]
 _lowerCAmelCase										=     predict_prob(grid).reshape(xxa.shape)
 plt.contour(xxa, xxa, probs, [0.5], linewidths=1, colors='''black''')

 plt.legend()




 plt.show()


