





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







def    _lowerCamelCase  (__lowerCamelCase  :     Union[str, Any]					,  __lowerCamelCase  :     Union[str, Any]     )   ->    str:
			return (-y * np.log(__lowerCamelCase     ) - (1 - y) * np.log(1 - h     )).mean()







def    _lowerCamelCase  (__lowerCamelCase  :     Any					,  __lowerCamelCase  :     int					,  __lowerCamelCase  :     List[str]     )   ->    Optional[int]:
			a__     = np.dot(__lowerCamelCase					,  __lowerCamelCase     )
			return np.sum(y * scores - np.log(1 + np.exp(__lowerCamelCase     )     )     )







def    _lowerCamelCase  (__lowerCamelCase  :     int					,  __lowerCamelCase  :     List[str]					,  __lowerCamelCase  :     List[Any]					,  __lowerCamelCase  :     Tuple=7_0000     )   ->    List[str]:
			a__     = np.zeros(x.shape[1]     )

			for iterations in range(__lowerCamelCase     ):
						a__     = np.dot(__lowerCamelCase					,  __lowerCamelCase     )
						a__     = sigmoid_function(__lowerCamelCase     )
						a__     = np.dot(x.T					,  h - y     ) / y.size
						a__     = theta - alpha * gradient  # updating the weights
						a__     = np.dot(__lowerCamelCase					,  __lowerCamelCase     )
						a__     = sigmoid_function(__lowerCamelCase     )
						a__     = cost_function(__lowerCamelCase					,  __lowerCamelCase     )
						if iterations % 100 == 0:
									print(f'''loss: {j} \t'''     )  # printing the loss after every 100 iterations
			return theta


# In[68]:

if __name__ == "__main__":
		lowerCAmelCase_   :   int       =					datasets.load_iris()
		lowerCAmelCase_   :   Optional[int]       =					iris.data[:, :2]
		lowerCAmelCase_   :   Union[str, Any]       =					(iris.target != 0) * 1

		lowerCAmelCase_   :   Tuple       =					0.1
		lowerCAmelCase_   :   int       =					logistic_reg(alpha, x, y, max_iterations=70000)
		print("theta: ", theta)  # printing the theta i.e our weights vector







		def    _lowerCamelCase  (__lowerCamelCase  :     List[Any]     )   ->    Tuple:
					return sigmoid_function(
					    np.dot(__lowerCamelCase					,  __lowerCamelCase     )     )  # 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_))   :   List[Any]       =					(x[:, 0].min(), x[:, 0].max())
		((lowerCAmelCase_)     ,      (lowerCAmelCase_))   :   Union[str, Any]       =					(x[:, 1].min(), x[:, 1].max())
		((lowerCAmelCase_)     ,      (lowerCAmelCase_))   :   Tuple       =					np.meshgrid(np.linspace(xa_min, xa_max), np.linspace(xa_min, xa_max))
		lowerCAmelCase_   :   List[Any]       =					np.c_[xxa.ravel(), xxa.ravel()]
		lowerCAmelCase_   :   str       =					predict_prob(grid).reshape(xxa.shape)
		plt.contour(xxa, xxa, probs, [0.5], linewidths=1, colors="black")

		plt.legend()




		plt.show()










'''simple docstring'''


class       UpperCamelCase__  :







	def __init__(				self			:   str , lowerCamelCase			:   int , lowerCamelCase			:   List[str]=None , lowerCamelCase			:   int=None		):




				'''simple docstring'''
				a__     = data
				a__     = previous
				a__     = next_node







	def __str__(				self			:   List[Any]		):




				'''simple docstring'''
				return F'''{self.data}'''







	def 						__a   (				self			:   List[Any]		):




				'''simple docstring'''
				return self.data







	def 						__a   (				self			:   Tuple		):




				'''simple docstring'''
				return self.next







	def 						__a   (				self			:   Union[str, Any]		):




				'''simple docstring'''
				return self.previous






class       UpperCamelCase__  :







	def __init__(				self			:   int , lowerCamelCase			:   Tuple		):




				'''simple docstring'''
				a__     = head







	def __iter__(				self			:   Any		):




				'''simple docstring'''
				return self







	def 						__a   (				self			:   List[Any]		):




				'''simple docstring'''
				if not self.current:
							raise StopIteration
				else:
							a__     = self.current.get_data()
							a__     = self.current.get_next()
							return value






class       UpperCamelCase__  :







	def __init__(				self			:   Tuple		):




				'''simple docstring'''
				a__     = None  # First node in list
				a__     = None  # Last node in list







	def __str__(				self			:   Any		):




				'''simple docstring'''
				a__     = self.head
				a__     = []
				while current is not None:
							nodes.append(current.get_data()		)
							a__     = current.get_next()
				return " ".join(str(lowerCamelCase		) for node in nodes		)







	def __contains__(				self			:   Optional[int] , lowerCamelCase			:   int		):




				'''simple docstring'''
				a__     = self.head
				while current:
							if current.get_data() == value:
										return True
							a__     = current.get_next()
				return False







	def __iter__(				self			:   int		):




				'''simple docstring'''
				return LinkedListIterator(self.head		)







	def 						__a   (				self			:   str		):




				'''simple docstring'''
				if self.head:
							return self.head.get_data()
				return None







	def 						__a   (				self			:   Union[str, Any]		):




				'''simple docstring'''
				if self.tail:
							return self.tail.get_data()
				return None







	def 						__a   (				self			:   List[Any] , lowerCamelCase			:   Node		):




				'''simple docstring'''
				if self.head is None:
							a__     = node
							a__     = node
				else:
							self.insert_before_node(self.head , lowerCamelCase		)







	def 						__a   (				self			:   List[str] , lowerCamelCase			:   Node		):




				'''simple docstring'''
				if self.head is None:
							self.set_head(lowerCamelCase		)
				else:
							self.insert_after_node(self.tail , lowerCamelCase		)







	def 						__a   (				self			:   List[str] , lowerCamelCase			:   int		):




				'''simple docstring'''
				a__     = Node(lowerCamelCase		)
				if self.head is None:
							self.set_head(lowerCamelCase		)
				else:
							self.set_tail(lowerCamelCase		)







	def 						__a   (				self			:   Any , lowerCamelCase			:   Node , lowerCamelCase			:   Node		):




				'''simple docstring'''
				a__     = node
				a__     = node.previous

				if node.get_previous() is None:
							a__     = node_to_insert
				else:
							a__     = node_to_insert

				a__     = node_to_insert







	def 						__a   (				self			:   Tuple , lowerCamelCase			:   Node , lowerCamelCase			:   Node		):




				'''simple docstring'''
				a__     = node
				a__     = node.next

				if node.get_next() is None:
							a__     = node_to_insert
				else:
							a__     = node_to_insert

				a__     = node_to_insert







	def 						__a   (				self			:   Union[str, Any] , lowerCamelCase			:   int , lowerCamelCase			:   int		):




				'''simple docstring'''
				a__     = 1
				a__     = Node(lowerCamelCase		)
				a__     = self.head
				while node:
							if current_position == position:
										self.insert_before_node(lowerCamelCase , lowerCamelCase		)
										return
							current_position += 1
							a__     = node.next
				self.insert_after_node(self.tail , lowerCamelCase		)







	def 						__a   (				self			:   List[Any] , lowerCamelCase			:   int		):




				'''simple docstring'''
				a__     = self.head
				while node:
							if node.get_data() == item:
										return node
							a__     = node.get_next()
				raise Exception("Node not found"		)







	def 						__a   (				self			:   List[Any] , lowerCamelCase			:   List[str]		):




				'''simple docstring'''
				if (node := self.get_node(lowerCamelCase		)) is not None:
							if node == self.head:
										a__     = self.head.get_next()

							if node == self.tail:
										a__     = self.tail.get_previous()

							self.remove_node_pointers(lowerCamelCase		)







	@staticmethod
	def 						__a   (				lowerCamelCase			:   Node		):




				'''simple docstring'''
				if node.get_next():
							a__     = node.previous

				if node.get_previous():
							a__     = node.next

				a__     = None
				a__     = None







	def 						__a   (				self			:   List[str]		):




				'''simple docstring'''
				return self.head is None







def    _lowerCamelCase  ()   ->    None:
			pass


if __name__ == "__main__":
		import doctest

		doctest.testmod()



