Bird
Raised Fist0

Implement Confusion Matrix from Predictions

CODINGbeginnerInterview freq: very_high
Choose your preparation mode6 modes available
🤖
Implement Confusion Matrix from Predictions
Build a confusion matrix from scratch using predictions and true labels.
codingbeginnerFreq: very_highEvaluation Coding
Prerequisites:Classification Metrics - Precision, Recall, F1
📝
Problem Statement

Given two lists, one of true labels and one of predicted labels, implement a function to compute the confusion matrix. The confusion matrix should be a 2D NumPy array where the rows represent the true classes and the columns represent the predicted classes.

Input:  true_labels: List[int], predicted_labels: List[int]
Output: confusion_matrix: np.ndarray
{
  "input": "true_labels = [0, 1, 0, 1], predicted_labels = [0, 0, 1, 1]",
  "expected_output": "array([[1, 1], [1, 1]])"
}
🎯
Interview Angles
  • Testing understanding of classification metrics and how they are derived from confusion matrices.
  • Evaluating ability to implement basic matrix operations using NumPy.
  • Assessing knowledge of handling edge cases in classification problems.
  • Checking for efficient use of Python's data structures and libraries.
🔵
Naive Approach

Iterate over each pair of true and predicted labels, incrementing the appropriate cell in the confusion matrix.

Time complexity: O(n), where n is the number of labels. Space complexity: O(k^2), where k is the number of classes.
Why Insufficient
Iterating over each label pair is O(n), which is acceptable, but the approach does not leverage NumPy's vectorized operations for potential speedup.
🐍
Naive Code
Python
import numpy as np

def confusion_matrix_naive(true_labels, predicted_labels):
    num_classes = max(max(true_labels), max(predicted_labels)) + 1
    matrix = np.zeros((num_classes, num_classes), dtype=int)
    for true, pred in zip(true_labels, predicted_labels):
        matrix[true, pred] += 1
    return matrix

# Driver example
true_labels = [0, 1, 0, 1]
predicted_labels = [0, 0, 1, 1]
print(confusion_matrix_naive(true_labels, predicted_labels))
💡
Key Insight
Use NumPy's advanced indexing to efficiently count occurrences of each (true, predicted) pair.
🐍
Optimized Code
Python
import numpy as np

def confusion_matrix_optimized(true_labels, predicted_labels):
    if not true_labels or not predicted_labels:
        return np.array([])
    num_classes = max(max(true_labels), max(predicted_labels)) + 1
    matrix = np.zeros((num_classes, num_classes), dtype=int)
    for true, pred in zip(true_labels, predicted_labels):
        matrix[true, pred] += 1
    return matrix

# Driver example
true_labels = [0, 1, 0, 1]
predicted_labels = [0, 0, 1, 1]
print(confusion_matrix_optimized(true_labels, predicted_labels))
🔍
Line-by-Line
num_classes = max(max(true_labels), max(predicted_labels)) + 1
Determine the number of classes by finding the maximum label in both true and predicted lists.
matrix = np.zeros((num_classes, num_classes), dtype=int)
Initialize a square matrix of zeros with dimensions equal to the number of classes.
for true, pred in zip(true_labels, predicted_labels):
Iterate over each pair of true and predicted labels.
matrix[true, pred] += 1
Increment the cell corresponding to the true and predicted label pair.
return matrix
Return the populated confusion matrix.
⚡
Complexity
Time complexity: O(n), where n is the number of labels. Space complexity: O(k^2), where k is the number of classes.
array([[1, 1], [1, 1]])
🔲
Edge Cases
Empty input lists
Returns an empty confusion matrix.
if not true_labels or not predicted_labels: return np.array([])
Single class
Returns a 1x1 matrix with the count of predictions.
num_classes = max(max(true_labels), max(predicted_labels)) + 1
⚠️
Common Mistakes
Symptom: IndexError or incorrect matrix dimensions.
Symptom: Matrix dimensions do not match the number of classes.
Symptom: Slower performance and potential type errors.
Symptom: Incorrect counts in the confusion matrix.

Practice

(1/5)
1.
import numpy as np

def cosine_similarity(a, b):
    dot_product = np.dot(a, b)
    norm_a = np.linalg.norm(a)
    norm_b = np.linalg.norm(b)
    return dot_product / (norm_a * norm_b)

vector1 = np.array([1, 2, 3])
vector2 = np.array([4, 5, 6])

result = cosine_similarity(vector1, vector2)
print(result)
easy
A. 0.9746318461970762
B. 0.9999999999999998
C. 1.0
D. 0.0

Solution

  1. Step 1: Calculate dot product and norms

    Dot product = 32, norm_a = 3.7416573867739413, norm_b = 8.774964387392123.
  2. Step 2: Compute cosine similarity

    Cosine similarity = 32 / (3.7416573867739413 * 8.774964387392123) = 0.9746318461970762.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Dot product over product of norms. [OK]
Hint: Dot product over product of norms. [OK]
Common Mistakes:
2. What does the following Python code output when applied to an image array img?
import numpy as np

def flip_image(img):
    return np.flip(img, axis=1)

img = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
flipped_img = flip_image(img)
print(flipped_img)
easy
A. [[3, 2, 1], [6, 5, 4], [9, 8, 7]]
B. [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
C. [[7, 8, 9], [4, 5, 6], [1, 2, 3]]
D. [[9, 8, 7], [6, 5, 4], [3, 2, 1]]

Solution

  1. Step 1: Understand the flip operation

    The np.flip function flips the array along the specified axis. Here, axis=1 means flipping horizontally.
  2. Step 2: Apply the flip to the array

    Flipping horizontally changes the order of elements in each row.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Horizontal flip reverses row elements. [OK]
Hint: Horizontal flip reverses row elements. [OK]
Common Mistakes:
3. What is the time complexity of updating the embeddings for a single word pair in the Skip-Gram model with negative sampling?
easy
A. O(k)
B. O(vocab_size)
C. O(n)
D. O(1)

Solution

  1. Step 1: Identify the operations involved

    Updating embeddings involves computing gradients and updating weights for the target word and k negative samples.
  2. Step 2: Determine the complexity

    Each update involves a constant number of operations per sample, leading to O(k) complexity where k is the number of negative samples.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Complexity is O(k) due to k negative samples [OK]
Hint: Complexity is O(k) due to k negative samples [OK]
Common Mistakes:
4. How would you modify the scaled dot-product attention mechanism to handle variable-length sequences efficiently?
medium
A. Use padding and mask the padded values.
B. Use a fixed-size window for all sequences.
C. Truncate all sequences to the same length.
D. Ignore sequences longer than a threshold.

Solution

  1. Step 1: Identify the challenge

    Variable-length sequences require handling of different sequence lengths.
  2. Step 2: Choose the correct approach

    Padding with masking is efficient and maintains sequence integrity.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Pad and mask for variable lengths [OK]
Hint: Pad and mask for variable lengths [OK]
Common Mistakes:
5. How can you optimize the following logistic regression implementation for faster computation?
import numpy as np

# Initialize weights
weights = np.zeros((m, 1))

# Training loop
for epoch in range(epochs):
    # Compute predictions
    predictions = 1 / (1 + np.exp(-np.dot(X, weights)))
    
    # Compute gradient
    gradient = np.dot(X.T, (predictions - y)) / n
    
    # Update weights
    weights -= learning_rate * gradient
hard
A. Use a sparse matrix representation for X.
B. Use a smaller learning rate to ensure stability.
C. Vectorize the gradient computation to avoid loops.
D. Precompute the sigmoid function for all possible inputs.

Solution

  1. Step 1: Identify bottlenecks

    Matrix operations can be slow if X is dense and large.
  2. Step 2: Optimize matrix operations

    Using a sparse matrix representation for X reduces memory usage and speeds up computations.
  3. Final Answer:

    Option A -> Option A
  4. Quick Check:

    Sparse matrices optimize large, sparse datasets [OK]
Hint: Sparse matrices optimize large, sparse datasets [OK]
Common Mistakes:
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard