





# 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__:				Union[str, Any]     ):
		return 1 / (1 + np.exp(-z     ))






def 					SCREAMING_SNAKE_CASE__				(							UpperCamelCase__:				int       , UpperCamelCase__:				Tuple     ):
		return (-y * np.log(UpperCamelCase__     ) - (1 - y) * np.log(1 - h     )).mean()






def 					SCREAMING_SNAKE_CASE__				(							UpperCamelCase__:				List[str]       , UpperCamelCase__:				Optional[Any]       , UpperCamelCase__:				Tuple     ):
		SCREAMING_SNAKE_CASE__								=   np.dot(UpperCamelCase__       , UpperCamelCase__     )
		return np.sum(y * scores - np.log(1 + np.exp(UpperCamelCase__     )     )     )






def 					SCREAMING_SNAKE_CASE__				(							UpperCamelCase__:				Union[str, Any]       , UpperCamelCase__:				List[str]       , UpperCamelCase__:				Any       , UpperCamelCase__:				Optional[Any]=70_000     ):
		SCREAMING_SNAKE_CASE__								=   np.zeros(x.shape[1]     )

		for iterations in range(UpperCamelCase__     ):
				SCREAMING_SNAKE_CASE__								=   np.dot(UpperCamelCase__       , UpperCamelCase__     )
				SCREAMING_SNAKE_CASE__								=   sigmoid_function(UpperCamelCase__     )
				SCREAMING_SNAKE_CASE__								=   np.dot(x.T       , h - y     ) / y.size
				SCREAMING_SNAKE_CASE__								=   theta - alpha * gradient  # updating the weights
				SCREAMING_SNAKE_CASE__								=   np.dot(UpperCamelCase__       , UpperCamelCase__     )
				SCREAMING_SNAKE_CASE__								=   sigmoid_function(UpperCamelCase__     )
				SCREAMING_SNAKE_CASE__								=   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=70000)
	print('theta: ', theta)  # printing the theta i.e our weights vector






	def 					SCREAMING_SNAKE_CASE__				(							UpperCamelCase__:				List[str]     ):
			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()






def 					SCREAMING_SNAKE_CASE__				(							UpperCamelCase__:				int = 600_851_475_143     ):

		try:
				SCREAMING_SNAKE_CASE__								=   int(UpperCamelCase__     )
		except (TypeError, ValueError):
				raise TypeError("""Parameter n must be int or castable to int."""     )
		if n <= 0:
				raise ValueError("""Parameter n must be greater than or equal to one."""     )
		SCREAMING_SNAKE_CASE__								=   1
		SCREAMING_SNAKE_CASE__								=   2
		while i * i <= n:
				while n % i == 0:
						SCREAMING_SNAKE_CASE__								=   i
						n //= i
				i += 1
		if n > 1:
				SCREAMING_SNAKE_CASE__								=   n
		return int(UpperCamelCase__     )


if __name__ == "__main__":
	print(F'''{solution() = }''')