0% found this document useful (0 votes)
25 views24 pages

Aiml Lab Manual-Civil-3-26

The document describes implementing and comparing greedy and A* algorithms. It provides the algorithms for greedy best-first search and A* search. It also includes code to implement greedy shortest path finding and compares it to A* search on a sample graph.

Uploaded by

jeni.grace89
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views24 pages

Aiml Lab Manual-Civil-3-26

The document describes implementing and comparing greedy and A* algorithms. It provides the algorithms for greedy best-first search and A* search. It also includes code to implement greedy shortest path finding and compares it to A* search on a sample graph.

Uploaded by

jeni.grace89
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 24

LIST OF EXPERIMENTS

S.NO DATE NAME OF THE EXPERIMENT PAGE NO FACULTY


SIGNATURE
PROGRAMS FOR PROBLEM SOLVING WITH SEARCH
1 Implement breadth first search

2 Implement depth first search

3 Analysis of breadth first and depth first search in terms of


time and space
4 Implement and compare Greedy and A* algorithms.

SUPERVISED LEARNING
5 Implement the non-parametric locally weighted regression
algorithm in order to fit data points. Select appropriate data
set for your experiment and draw graphs
6 Write a program to demonstrate the working of the
decision tree-based algorithm.
7 Build an artificial neural network by implementing the
back propagation algorithm and test the same using
appropriate data sets.
8 Write a program to implement the naïve Bayesian
classifier.
UNSUPERVISED LEARNING
9 Implementing neural network using self-organizing maps

10 Implementing k-Means algorithm to cluster a set of data.

11 Implementing hierarchical clustering algorithm.


Ex.no:1
Date:
IMPLEMENT BREADTH FIRST SEARCH

Aim:

To Implement Breadth First Search usingpython. Breadth-first search (BFS) is an algorithm for traversing
or searching tree or graph data structures..

Algorithm:

1. Start at the Initial Node: Begin by selecting an initial node to start the search.

2. Initialize Data Structures: Initialize a queue to keep track of the nodes to visit and a set or array to keep
track of visited nodes.

3. Enqueue the Initial Node: Add the initial node to the queue and mark it as visited.

4. While the Queue is Not Empty:

 Dequeue a node from the front of the queue.

 Visit the dequeued node.

 Enqueue all unvisited neighbors of the dequeued node.

 Mark each neighbor as visited and enqueue it.

5. Repeat Until Queue is Empty: Continue this process until the queue is empty, meaning all reachable
nodes have been visited.

6. Return Traversal Result: The order in which nodes are visited represents the breadth-first traversal of
the graph or tree.

Program:

from collections import deque


def bfs(graph, start):
visited = set()
queue = deque([start])
visited.add(start)

while queue:
node = queue.popleft()
print(node, end=' ')

for neighbor in graph[node]:


if neighbor not in visited:
visited.add(neighbor)
queue.append(neighbor)
graph = {
'A': ['B', 'C'],
'B': ['A', 'D', 'E'],
'C': ['A', 'F'],
'D': ['B'],
'E': ['B', 'F'],
'F': ['C', 'E']
}

print("BFS Traversal:")
bfs(graph, 'A')

Output

BFS Traversal:
ABCDEF>

Result:
Thus the program for breadth first search is executed successfully and output is verified.
Ex.no:2
Date:
IMPLEMENT DEPTH FIRST SEARCH

Aim:
To Implement Depth First Search using python

Algorithm:

1. Start at the Initial Node: Begin by selecting an initial node to start the search.
2. Initialize Data Structures: Initialize a set or array to keep track of visited nodes.
3. Recursively Traverse: Implement a recursive function to traverse the graph or tree depth-first.
4. Visit the Current Node: Mark the current node as visited and process it. This may involve printing the
node, storing it in a list, or performing any other required operation.
5. Explore Unvisited Neighbors: For each unvisited neighbor of the current node, recursively call the
DFS function on that neighbor.
6. Base Case: Ensure there is a base case to terminate the recursion. This typically occurs when all
reachable nodes have been visited.

Program:

class Graph:
def __init__(self):
self.adj_list = {}

def add_edge(self, u, v):


if u not in self.adj_list:
self.adj_list[u] = []
self.adj_list[u].append(v)

def dfs(self, start):


visited = set()

def dfs_util(node):
visited.add(node)
print(node, end=' ')
if node in self.adj_list:
for neighbor in self.adj_list[node]:
if neighbor not in visited:
dfs_util(neighbor)

dfs_util(start)

# Example usage:
graph = Graph()
graph.add_edge('A', 'B')
graph.add_edge('A', 'C')
graph.add_edge('B', 'D')
graph.add_edge('B', 'E')
graph.add_edge('C', 'F')
print("DFS Traversal:")
graph.dfs('A')

Output:

DFS Traversal:
ABDECF>

Result:
Thus, the program for depth first search is executed successfully and output is verified.
Ex.no:3
Date:

ANALYSIS OF BREADTH FIRST AND DEPTH FIRST SEARCH IN TERMS OF


TIME AND SPACE

Both breadth-first search (BFS) and depth-first search (DFS) have different time and space
complexities, making them suitable for different types of problems and data structures. Here's an analysis of
BFS and DFS in terms of time and space complexities:

Breadth-First Search (BFS):


 Time Complexity: O(V+E), where V is the number of vertices (nodes) and E is the number of edges in
the graph or tree. This is because BFS traverses each vertex and each edge exactly once.
 Space Complexity:O(V), where V is the number of vertices. In the worst case, the entire set of vertices
will be stored in the queue at once, resulting in a space complexity proportional to the number of
vertices.

Depth-First Search (DFS):


 Time Complexity: O(V+E), where V is the number of vertices and E is the number of edges. Similar to
BFS, DFS traverses each vertex and each edge exactly once.
 Space Complexity: O(V) in the worst case, whereV is the number of vertices. However, the space
complexity of DFS can vary depending on the implementation:
 Recursive DFS: In recursive DFS, the space complexity is determined by the maximum depth of
the recursion stack, which can be O(V) in the worst case for a linear chain of vertices. However,
for graphs with branching factor greater than 1, the maximum depth of the recursion stack could
be less than V.
 Iterative DFS: In iterative DFS, a stack or similar data structure is used to simulate the recursion
stack, resulting in a space complexity of O(V) in the worst case.

Comparison:
 BFS typically requires more memory than DFS because it needs to store all vertices at the current level
in the queue, while DFS only needs to store the vertices along the current path.
 BFS is generally preferred when finding the shortest path in unweighted graphs or trees, as it guarantees
the shortest path due to its level-by-level exploration.
 DFS may be more memory-efficient and suitable for problems like topological sorting, cycle detection,
or traversing deeper into graphs or trees before backtracking.
In summary, BFS and DFS have different time and space complexities, making them suitable for different
types of problems and data structures. The choice between BFS and DFS depends on the specific requirements
of the problem and the characteristics of the graph or tree being traversed.
Ex.no:4
Date:

IMPLEMENT AND COMPARE GREEDY AND A* ALGORITHMS

Aim:

To Implement and Compare Greedy and A* Algorithms

Algorithm:

Greedy Best-First Search Algorithm:


1. Initialize an empty priority queue pq and a set visited.
2. Push the start node into pq with a priority based on a heuristic (distance estimate) to the goal.
3. While pq is not empty:
 Pop the node with the highest priority from pq.
 If the node is the goal, return success.
 Otherwise, mark the node as visited.
 Expand the node by considering all its unvisited neighbors.
 Push each unvisited neighbor into pq with a priority based on the heuristic to the goal.
4. If the priority queue is empty and the goal has not been found, return failure.

Program:

import heapq

def greedy_shortest_path(graph, start, goal):


visited = set()
pq = [(0, start)]

while pq:
cost, node = heapq.heappop(pq)

if node == goal:
return cost

if node not in visited:


visited.add(node)
for neighbor, weight in graph[node]:
if neighbor not in visited:
heapq.heappush(pq, (weight, neighbor))

return float('inf') # If there is no path from start to goal

# Example usage:
graph = {
'A': [('B', 5), ('C', 3)],
'B': [('D', 6)],
'C': [('D', 2)],
'D': [('E', 4)],
'E': []
}

start = 'A'
goal = 'E'

print("Greedy Shortest Path Cost:", greedy_shortest_path(graph, start, goal))

Output:

Greedy Shortest Path Cost: 4

A* Algorithms

Algorithm:
1. Initialize an empty priority queue pq, a dictionary cost_so_far, and a set visited.
2. Push the start node into pq with a priority of zero and a cost of zero.
3. While pq is not empty:
 Pop the node with the lowest priority from pq.
 If the node is the goal, return success.
 Otherwise, mark the node as visited.
 Expand the node by considering all its unvisited neighbors.
 For each neighbor:
 Calculate the total cost from the start node to the neighbor through the current node.
 If the neighbor is not visited or the new cost is lower than the previously recorded cost:
 Update the cost_so_far dictionary with the new cost.
 Calculate the priority of the neighbor based on the total cost and a heuristic to the
goal.
 Push the neighbor into pq with the calculated priority and update its cost.
4. If the priority queue is empty and the goal has not been found, return failure.

Program:

import heapq

def heuristic(node, goal):


# A simple heuristic, assuming straight-line distance between nodes
return abs(ord(goal) - ord(node))

def astar_shortest_path(graph, start, goal):


pq = [] # Priority queue to store nodes to be explored
heapq.heappush(pq, (0 + heuristic(start, goal), 0, start)) # Push start node with priority 0
visited = set() # Set to store visited nodes
cost_so_far = {start: 0} # Dictionary to store the cost of reaching each node

while pq:
_, cost, node = heapq.heappop(pq) # Pop the node with the lowest priority

if node == goal:
return cost # Goal reached, return the cost

if node not in visited:


visited.add(node) # Mark the node as visited

# Explore neighbors of the current node


for neighbor, weight in graph[node]:
new_cost = cost + weight
if neighbor not in cost_so_far or new_cost<cost_so_far[neighbor]:
cost_so_far[neighbor] = new_cost
priority = new_cost + heuristic(neighbor, goal) # Priority = cost + heuristic
heapq.heappush(pq, (priority, new_cost, neighbor)) # Push neighbor into priority queue

return float('inf') # If there is no path from start to goal

# Example usage:
graph = {
'A': [('B', 5), ('C', 3)],
'B': [('D', 6)],
'C': [('D', 2)],
'D': [('E', 4)],
'E': []
}

start = 'A'
goal = 'E'

print("A* Shortest Path Cost:", astar_shortest_path(graph, start, goal))

Output:

A* Shortest Path Cost: 9

Result:

Thus, the program to Implement and Compare Greedy and A* Algorithms is executed successfully
Ex.no:5
Date:

SUPERVISED LEARNING
IMPLEMENT THE NON-PARAMETRIC LOCALLY WEIGHTED REGRESSION ALGORITHM
IN ORDER TO FIT DATA POINTS. SELECT APPROPRIATE DATA SET FOR YOUR
EXPERIMENT AND DRAW GRAPHS

Aim
To Implement The Non-Parametric Locally Weighted Regression Algorithm In Order To Fit Data Points.
Select Appropriate Data Set for Your Experiment and Draw Graphs using python matplotlib.

Algorithm:
1. Define Data Structures: Define structures to represent nodes and the decision tree itself.
2. Read Data: Read the input data into your program. Each data point should have features and a label.
3. Splitting Criteria Selection: Implement functions to determine the best splitting criteria at each node.
Common criteria include Gini impurity, information gain, or entropy.
4. Build Tree: Write a recursive function to build the decision tree. At each step, you'll select the best
splitting criteria, split the data, and recursively call the function on the subsets.
5. Prediction: Implement a function to predict the label for new data points by traversing the decision tree.

Program:

import numpy as np
import matplotlib.pyplot as plt

def gaussian_kernel(x, x_i, tau):


return np.exp(-((x - x_i) ** 2) / (2 * tau ** 2))

def lowess(x_train, y_train, x_pred, tau):


y_pred = np.zeros_like(x_pred)
n = len(x_train)

for i in range(len(x_pred)):
weights = gaussian_kernel(x_pred[i], x_train, tau)
W = np.diag(weights)
X = np.vstack((np.ones(n), x_train)).T
theta = np.linalg.inv(X.T @ W @ X) @ (X.T @ W @ y_train)
y_pred[i] = np.dot(np.array([1, x_pred[i]]), theta)

return y_pred

# Generate synthetic data


np.random.seed(0)
x_train = np.linspace(0, 10, 50)
y_train = np.sin(x_train) + np.random.normal(0, 0.1, size=x_train.shape)

# Define prediction points


x_pred = np.linspace(0, 10, 100)

# Set bandwidth parameter (tau)


tau = 0.5

# Perform Locally Weighted Regression


y_pred = lowess(x_train, y_train, x_pred, tau)

# Plot the data and the fitted curve


plt.figure(figsize=(8, 6))
plt.scatter(x_train, y_train, color='blue', label='Training Data')
plt.plot(x_pred, y_pred, color='red', label='Locally Weighted Regression')
plt.title('Locally Weighted Regression')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.grid(True)
plt.show()

Output:

Result:

Thus the Implement of the Non-Parametric Locally Weighted Regression Algorithm is executed in plot
diagram.
Ex.no:6
Date:

WRITE A PROGRAM TO DEMONSTRATE THE WORKING OF THE DECISION


TREE BASED ALGORITHM.

Aim:

To write a program to demonstrate the working of the decision tree-based algorithm.

Algorithm:

1. Load Dataset:
o Load a dataset containing features and corresponding labels.
2. Preprocess Data (if necessary):
o Handle missing values.
o Encode categorical variables.
o Normalize/standardize numerical features.
3. Split Dataset:
o Divide the dataset into training and testing sets.
4. Train Decision Tree Model:
o Create an instance of a decision tree classifier/regressor.
o Train the model on the training dataset.
5. Visualize Decision Tree (Optional):
o Visualize the trained decision tree to understand its structure and decision-making process.
6. Predictions:
o Use the trained decision tree model to make predictions on the testing dataset.
7. Evaluate Model Performance:
o Calculate relevant evaluation metrics (e.g., accuracy, precision, recall, F1-score for
classification, or mean squared error for regression) on the testing dataset.
8. Interpretation:
o Interpret the results and decision rules of the decision tree to gain insights into the dataset.
9. Tuning Parameters (Optional):
o Perform hyperparameter tuning (e.g., maximum depth, minimum samples per leaf) using
techniques like cross-validation to optimize the model's performance.
10. Repeat Steps 4-9 (if necessary):
o If the model's performance is not satisfactory, repeat steps 4 to 9 with different parameters or
feature engineering techniques.
11. Conclusion:
o Conclude by summarizing the model's performance and insights gained from the decision tree-
based algorithm.
Program:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier
from sklearn.metrics import accuracy_score

# Load the Iris dataset


iris = load_iris()
X = iris.data
y = iris.target

# Split the dataset into training and testing sets


X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Create a decision tree classifier


clf = DecisionTreeClassifier()

# Train the classifier on the training data


clf.fit(X_train, y_train)

# Make predictions on the testing data


y_pred = clf.predict(X_test)

# Calculate accuracy
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

Output:

Accuracy: 1.0

Result:

Thus, the above program for decision tree-based algorithm has been executed successfully
Ex.no:7
Date:

BUILD AN ARTIFICIAL NEURAL NETWORK BY IMPLEMENTING THE BACK


PROPAGATION ALGORITHM AND TEST THE SAME USING APPROPRIATE
DATA SETS.

Aim:
To build an artificial neural network by implementing the back propagation algorithm and test the same
using appropriate data sets.

Algorithm:

1. Define the Neural Network Structure:


o Determine the number of input nodes, hidden layers, hidden nodes in each layer, and output
nodes.
o Initialize the weights and biases randomly.
2. Implement the Activation Function:
o Choose an activation function for the hidden layers (e.g., sigmoid, ReLU, tanh).
o Implement the derivative of the chosen activation function for use in backpropagation.
3. Feedforward Process:
o Compute the weighted sum of inputs for each neuron in the hidden layers.
o Apply the activation function to the weighted sum to get the output of each neuron.
o Repeat the process for each hidden layer until the output layer is reached.
4. Backpropagation Process:
o Compute the error between the predicted output and the actual output.
o Propagate the error backward through the network to update the weights.
o Update the weights using the gradient descent algorithm:
 Compute the gradient of the loss function with respect to each weight.
 Update the weights in the direction that minimizes the loss function.
5. Training the Neural Network:
o Iterate through the dataset multiple times (epochs).
o For each input-output pair in the dataset:
 Perform the feedforward process to get the predicted output.
 Calculate the loss between the predicted output and the actual output.
 Perform the backpropagation process to update the weights and biases.
6. Testing the Neural Network:
o After training, use a separate dataset (test set) to evaluate the performance of the neural network.
o For each input in the test set:
 Use the trained neural network to predict the output.
 Compare the predicted output with the actual output.
 Calculate the overall accuracy or other performance metrics.
7. Hyperparameter Tuning:
o Experiment with different hyperparameters such as learning rate, number of hidden layers,
number of hidden nodes, etc.
o Use techniques like cross-validation to find the optimal hyperparameters.
8. Iterate and Improve:
o Analyze the performance of the neural network on the test set.
o Make adjustments to the network architecture or hyperparameters based on the performance.
oRetrain the neural network if necessary with the updated settings.
9. Deployment:
o Once satisfied with the performance, deploy the trained neural network for real-world
applications.

Program:
import numpy as np

class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
self.input_size = input_size
self.hidden_size = hidden_size
self.output_size = output_size

# Initialize weights and biases


self.weights_input_hidden = np.random.randn(self.input_size, self.hidden_size)
self.bias_hidden = np.random.randn(1, self.hidden_size)
self.weights_hidden_output = np.random.randn(self.hidden_size, self.output_size)
self.bias_output = np.random.randn(1, self.output_size)

def sigmoid(self, x):


return 1 / (1 + np.exp(-x))

def sigmoid_derivative(self, x):


return x * (1 - x)

def feedforward(self, X):


# Hidden layer activation
self.hidden_output = self.sigmoid(np.dot(X, self.weights_input_hidden) + self.bias_hidden)
# Output layer activation
self.output = self.sigmoid(np.dot(self.hidden_output, self.weights_hidden_output) + self.bias_output)
return self.output

def backpropagation(self, X, y, learning_rate):


# Compute output layer error
output_error = y - self.output
output_delta = output_error * self.sigmoid_derivative(self.output)

# Compute hidden layer error


hidden_error = np.dot(output_delta, self.weights_hidden_output.T)
hidden_delta = hidden_error * self.sigmoid_derivative(self.hidden_output)

# Update weights and biases


self.weights_hidden_output += learning_rate * np.dot(self.hidden_output.T, output_delta)
self.bias_output += learning_rate * np.sum(output_delta, axis=0, keepdims=True)
self.weights_input_hidden += learning_rate * np.dot(X.T, hidden_delta)
self.bias_hidden += learning_rate * np.sum(hidden_delta, axis=0, keepdims=True)

def train(self, X, y, epochs, learning_rate):


for epoch in range(epochs):
output = self.feedforward(X)
self.backpropagation(X, y, learning_rate)
if epoch % 100 == 0:
loss = np.mean(np.square(y - output))
print(f"Epoch {epoch}: Loss {loss}")

# Example usage
X = np.array([[0,0], [0,1], [1,0], [1,1]])
y = np.array([[0], [1], [1], [0]])

input_size = 2
hidden_size = 4
output_size = 1

nn = NeuralNetwork(input_size, hidden_size, output_size)


nn.train(X, y, epochs=1000, learning_rate=0.1)

Output:

Epoch 0: Loss 0.34597039275097236


Epoch 100: Loss 0.2519048202132208
Epoch 200: Loss 0.250753396200165
Epoch 300: Loss 0.24989531390907826
Epoch 400: Loss 0.24916320987952106
Epoch 500: Loss 0.24844249651107664
Epoch 600: Loss 0.24762913907234874
Epoch 700: Loss 0.24660112318336455
Epoch 800: Loss 0.24519179143078518
Epoch 900: Loss 0.24317148760941584

Result:
Thus the program to build an artificial neural network by implementing the back propagation algorithm and
test the same using appropriate data sets.
Ex.no:8
Date:
WRITE A PROGRAM TO IMPLEMENT THE NAÏVE BAYESIAN CLASSIFIER.
Aim:
To write a program to implement the naïve Bayesian classifier.
Algorithm:

1. Load the Dataset: We load the Iris dataset from scikit-learn's built-in datasets.
2. Split the Dataset: We split the dataset into training and testing sets using the train_test_split
function. This allows us to evaluate the performance of the model on unseen data.
3. Create the Naive Bayes Classifier: We create an instance of the GaussianNB class, which implements
the Naive Bayes classifier assuming Gaussian distribution of the features.
4. Train the Classifier: We train the Naive Bayes classifier on the training data using the fit method.
5. Make Predictions: We use the trained classifier to make predictions on the testing data using the
predict method.
6. Evaluate Accuracy: We calculate the accuracy of the model by comparing the predicted labels with the
true labels using the accuracy_score function.
Program:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import accuracy_score
# Load the Iris dataset
iris = load_iris()
X = iris.data
y = iris.target
# Split the dataset into training and testing sets
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)
# Create a Naive Bayes classifier
clf = GaussianNB()
# Train the classifier on the training data
clf.fit(X_train, y_train)
# Make predictions on the testing data
y_pred = clf.predict(X_test)
# Calculate accuracy
accuracy = accuracy_score(y_test, y_pred)
print("Accuracy:", accuracy)

Output:
Accuracy: 0.9777777777777777

Result:
To write a program to implement the naïve Bayesian classifier.
Ex.no:9
Date:
UNSUPERVISED LEARNING

IMPLEMENTING NEURAL NETWORK USING SELF-ORGANIZING MAPS

Aim:
To Implementing neural network using self-organizing maps.
Algorithm:

1. Initialize the SOM:


o Define the input size, output size (grid size), learning rate, and sigma (neighborhood radius).
o Initialize the SOM grid with random weights.
2. Find the Best Matching Unit (BMU):
o For each input vector, calculate the Euclidean distance between the input vector and all neurons'
weights.
o Determine the neuron with the smallest distance to the input vector. This neuron is the BMU.
3. Update Neuron Weights:
o Update the weights of the BMU and its neighboring neurons based on the input vector and a
neighborhood function.
o The update rule should favor adjusting the weights of neighboring neurons closer to the BMU
more than those farther away.
4. Decay Learning Rate and Sigma:
o After each epoch, decay the learning rate and sigma to gradually reduce the amount of
adjustment to neuron weights.
5. Repeat Steps 2-4:
o Iterate through the training dataset for a specified number of epochs, performing BMU finding
and weight updates.
6. Prediction:
o Once the SOM is trained, given a new input vector, find the BMU for that vector using the
current state of the SOM grid.
7. Visualization (Optional):
o Optionally, visualize the SOM grid to understand how input vectors are organized in the output
space.
8. Interpretation:
o Analyze the trained SOM to understand the relationships between input vectors and the topology
of the SOM grid.
9. Tuning Parameters (Optional):
o Experiment with different parameters such as learning rate, sigma, and grid size to optimize the
performance of the SOM for the specific task.
10. Evaluation (Optional):
o If applicable, evaluate the performance of the trained SOM for tasks such as clustering,
dimensionality reduction, or visualization on a separate validation or test dataset.
11. Conclusion:
o Conclude by summarizing the performance of the SOM and any insights gained from its use.
Program:
import numpy as np

class SOM:
def __init__(self, input_size, output_size, learning_rate=0.1, sigma=1.0):
self.input_size = input_size
self.output_size = output_size
self.learning_rate = learning_rate
self.sigma = sigma

# Initialize weights randomly


self.weights = np.random.rand(output_size[0], output_size[1], input_size)

def find_bmu(self, input_vector):


# Calculate distance between input vector and all neurons
distances = np.linalg.norm(self.weights - input_vector, axis=2)
# Find the index of the neuron with the minimum distance (Best Matching Unit)
bmu_index = np.unravel_index(np.argmin(distances), distances.shape)
return bmu_index

def update_weights(self, input_vector, bmu_index):


# Update weights of the BMU and its neighbors
for i in range(self.output_size[0]):
for j in range(self.output_size[1]):
distance_to_bmu = np.linalg.norm(np.array([i, j]) - np.array(bmu_index))
influence = np.exp(-(distance_to_bmu**2) / (2 * self.sigma**2))
self.weights[i, j] += self.learning_rate * influence * (input_vector - self.weights[i, j])

def train(self, input_data, epochs):


for epoch in range(epochs):
for input_vector in input_data:
bmu_index = self.find_bmu(input_vector)
self.update_weights(input_vector, bmu_index)
# Decay learning rate and sigma
self.learning_rate *= 0.9
self.sigma *= 0.9

def predict(self, input_data):


predictions = []
for input_vector in input_data:
bmu_index = self.find_bmu(input_vector)
predictions.append(bmu_index)
return predictions

# Example usage
input_data = np.random.rand(100, 2) # Generate random input data
input_size = 2 # Dimensionality of input vectors
output_size = (10, 10) # Size of the SOM grid
epochs = 100 # Number of training epochs

som = SOM(input_size, output_size)


som.train(input_data, epochs)

# Predict the BMU for each input vector


predictions = som.predict(input_data)
print(predictions)

Output:
[(5, 3), (0, 0), (6, 0), (4, 0), (2, 0), (7, 1), (3, 5), (9, 5), (3, 3), (7, 0), (5, 7), (2, 9), (2, 9), (2, 1), (5, 0), (9, 9),
(8, 3), (2, 9), (4, 3), (8, 7), (6, 3), (3, 1), (7, 1), (1, 0), (9, 6), (0, 3), (4, 0), (9, 5), (9, 6), (6, 7), (0, 9), (6, 1),
(2, 2), (6, 7), (3, 5), (0, 1), (9, 5), (4, 0), (1, 7), (6, 0), (6, 0), (1, 0), (5, 7), (7, 3), (9, 6), (2, 2), (2, 9), (2, 0),
(5, 5), (1, 0), (0, 4), (0, 1), (2, 9), (8, 3), (2, 7), (2, 1), (4, 5), (5, 1), (0, 0), (1, 8), (0, 1), (1, 6), (4, 9), (0, 8),
(6, 7), (0, 5), (2, 9), (0, 3), (6, 0), (2, 2), (7, 5), (1, 2), (0, 5), (0, 5), (3, 1), (5, 0), (5, 6), (0, 5), (3, 9), (9, 5),
(7, 5), (6, 7), (9, 6), (4, 5), (4, 5), (0, 4), (4, 5), (8, 3), (4, 5), (5, 5), (0, 0), (6, 8), (3, 8), (1, 9), (8, 8), (5, 3),
(9, 0), (9, 0), (6, 7), (1, 0)]

Result:
Thus the above program forImplementingneural networkusing self-organizing maps has been
executed successfully.
Ex.no:10
Date:
IMPLEMENTING K-MEANS ALGORITHM TO CLUSTER A SET OF DATA.

Aim:
To Implementing k-Means algorithm to cluster a set of data.

Algorithm:

1. Initialize Centroids:
o Randomly select k data points from the dataset to serve as initial centroids.
2. Assign Data Points to Clusters:
o For each data point in the dataset, calculate the Euclidean distance to each centroid.
o Assign each data point to the cluster corresponding to the nearest centroid.
3. Update Centroids:
o Calculate the mean of all data points assigned to each cluster.
o Update the centroids to be the mean values.
4. Repeat Steps 2-3:
o Iterate the process of assigning data points to clusters and updating centroids until convergence
or a maximum number of iterations is reached.
o Convergence can be determined by checking if the centroids no longer change significantly
between iterations.
5. Output:
o After convergence, the final centroids represent the centers of the clusters.
o Each data point is assigned to the cluster corresponding to the nearest centroid.
6. Optional: Choosing the Number of Clusters:
o In some cases, the number of clusters k may not be known beforehand.
o Various methods, such as the elbow method or silhouette score, can be used to select an optimal
value for k.

Program:
import numpy as np

class KMeans:
def __init__(self, n_clusters, max_iter=300):
self.n_clusters = n_clusters
self.max_iter = max_iter

def initialize_centroids(self, X):


# Randomly initialize centroids by selecting k data points from X
np.random.seed(42)
centroids_indices = np.random.choice(X.shape[0], size=self.n_clusters, replace=False)
centroids = X[centroids_indices]
return centroids

def find_closest_centroid(self, x, centroids):


# Find the index of the closest centroid to the given data point x
distances = np.linalg.norm(centroids - x, axis=1)
return np.argmin(distances)
def update_centroids(self, clusters, X):
# Update centroids based on the mean of the data points in each cluster
centroids = np.zeros((self.n_clusters, X.shape[1]))
for i in range(self.n_clusters):
cluster_points = X[clusters == i]
centroids[i] = np.mean(cluster_points, axis=0)
return centroids

def fit(self, X):


# Initialize centroids
centroids = self.initialize_centroids(X)

for _ in range(self.max_iter):
# Assign each data point to the closest centroid
clusters = np.array([self.find_closest_centroid(x, centroids) for x in X])

# Update centroids
new_centroids = self.update_centroids(clusters, X)

# Check for convergence


if np.allclose(centroids, new_centroids):
break

centroids = new_centroids

self.centroids = centroids
self.clusters = clusters

def predict(self, X):


# Predict the cluster for each data point in X
return np.array([self.find_closest_centroid(x, self.centroids) for x in X])

# Example usage
X = np.array([[1, 2], [1, 3], [2, 2], [10, 8], [10, 10], [12, 8]])
kmeans = KMeans(n_clusters=2)
kmeans.fit(X)
print("Centroids:", kmeans.centroids)
print("Cluster assignments:", kmeans.clusters)

Output:
Centroids: [ 1.33333333 2.33333333]
[10.66666667 8.66666667]]
Cluster assignments: [0 0 0 1 1 1]

Result:
Thus, the above program to Implementing k-Means algorithm to cluster a set of data has been executed
successfully.
Ex.no:11
Date:
11. IMPLEMENTING HIERARCHICAL CLUSTERING ALGORITHM.
Aim:
To Implementing hierarchical clustering algorithm.

Algorithm:

1. Initialization:
o Start with each data point as a separate cluster.
2. Compute Pairwise Distances:
o Compute the distance matrix containing the pairwise distances between all data points.
3. Merge Clusters:
o Find the pair of clusters with the smallest distance between them.
o Merge these two clusters into a single cluster.
4. Update Distance Matrix:
o Update the distance matrix to reflect the distances between the new merged cluster and all other
clusters.
5. Repeat:
o Repeat steps 3-4 until only a single cluster remains, or until a specified number of clusters is
reached.
6. Output:
o The output of hierarchical clustering is typically represented as a dendrogram, a tree-like
structure that shows the order and distances at which clusters were merged.

PROGRAM:

import numpy as np

class HierarchicalClustering:
def __init__(self, n_clusters=None):
self.n_clusters = n_clusters

def fit(self, X):


n = X.shape[0]
distance_matrix = np.zeros((n, n))
np.fill_diagonal(distance_matrix, np.inf)

clusters = [{i} for i in range(n)]

while len(clusters) >self.n_clusters if self.n_clusters else 1:


min_distance = np.inf
min_i, min_j = None, None

for i in range(len(clusters)):
for j in range(i+1, len(clusters)):
distance = self.complete_linkage_distance(X, clusters[i], clusters[j])
if distance <min_distance:
min_distance = distance
min_i, min_j = i, j

new_cluster = clusters[min_i].union(clusters[min_j])
del clusters[min_j]
clusters[min_i] = new_cluster

self.labels_ = np.zeros(n, dtype=int)


for i, cluster in enumerate(clusters):
self.labels_[list(cluster)] = i

def complete_linkage_distance(self, X, cluster1, cluster2):


max_distance = -np.inf
for i in cluster1:
for j in cluster2:
distance = np.linalg.norm(X[i] - X[j])
if distance >max_distance:
max_distance = distance
return max_distance

# Example usage
X = np.array([[1, 2], [1, 3], [2, 2], [10, 8], [10, 10], [12, 8]])
clustering = HierarchicalClustering(n_clusters=2)
clustering.fit(X)
print("Cluster assignments:", clustering.labels_)

OUTPUT:
Cluster assignments: [0 0 0 1 1 1]

RESULT:
Thus, the above program for Implementing hierarchical clustering algorithmhas been executed
successfully.

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy