Bonus. Composing Kernels
In lecture and tutorial, we have introduced you to a few (commonly used) kernels:
Linear kernel: .
Polynomial kernel (with degree ): .
Gaussian Kernel:
These kernels work well but... isn't it cool to invent your own kernel?
Recall that kernels are essentially applying feature transformations (yet implicitly). Any function that satisfies would be a valid kernel, where is the function mapping the original features to the transformed features. In this exercise, let's try to compose the existing kernels to create new kernels.
Your task: There are 3 tasks (+ a demo task) which walks you through on how you could create new kernels. Go through them one by one.
Submission: After working on Tasks 1 - 3, send me a screenshot of your implementation and diagram (for Task 3) before/during the tutorial (for bonus EXP)!
P.S. If no one solves all three tasks, I will still give out bonus EXP to those who solved at least 2. I believe Task 2 would be the hardest one.
Task 0: Finding Transformed Features (Demo)
Given that the kernel trick is equivalent to performing feature transformations, we can actually train an equivalent SVM by making explicit feature transformations.
In lecture, we have shown that the kernel is equivalent to applying the transformed features , since we have
Let's try to verify this with code!
There are two code snippets below. The first one trains a SVM by generating the transformed features , and for each input sample . The second one trains a SVM by applying the kernel function directly. Run them and verify if you obtained the same decision boundaries. It's also useful to study the implementation for Tasks 1 - 3.
Task 1: Adding Kernel Functions
One attempt is to add two kernel functions together, e.g. given that and are both valid kernel functions, we can create a new function .
We can prove that the resulting function always a valid kernel function.
Try to prove this by working out the list of transformed features created by this composition. To demonstrate your understanding, implement your idea at transform_add that generates the list of transformed features.
If you implemented the function correctly, the resulting decision boundaries should be same as applying the kernel function.
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
Cell In[8], line 36
33 plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, linewidth=1, edgecolor='black')
34 plt.title("Actual: Transformed Features")
---> 36 assert np.all(Z_correct == Z_test), "Your SVM gives a different classification"
38 plt.show()
AssertionError: Your SVM gives a different classification
Task 2: Multiplying Kernel Functions
Another attempt is to multiply two kernel functions together, e.g. given that and are both valid kernel functions, we can create a new function .
We can also prove that the resulting function always a valid kernel function.
Try to prove this by working out the list of transformed features created by this composition. To demonstrate your understanding, implement your idea at transform_multiply that generates the list of transformed features.
If you implemented the function correctly, the resulting decision boundaries should be same as applying the kernel function.
---------------------------------------------------------------------------
AssertionError Traceback (most recent call last)
Cell In[10], line 39
36 plt.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.Paired, linewidth=1, edgecolor='black')
37 plt.title("Actual: Transformed Features")
---> 39 assert np.all(Z_correct == Z_test), "Your SVM gives a different classification"
41 plt.show()
AssertionError: Your SVM gives a different classification
Task 3: Create your own kernel!
Based on these two transformations, create your own kernel function my_creative_kernel. Be as creative as possible!
Note: You are not required to work out the set of equivalent transformed features. Infinite-dimensional kernel functions would make this impossible.