字节二面,稳了。。。


哈喽,我是kk~
今儿接到一位同学的面试字节的经验。
工作两年,想要跳槽,最终拿到了字节的offer。

针对这个问题,可能项目组还是比较看重对于基础的理解。
趁这个机会,咱们这里也手动推一下,帮助大家差缺补漏~
支持向量机(Support Vector Machine,SVM)是一种用于分类和回归的监督学习模型。它是通过寻找一个最佳的决策边界(即超平面)来区分不同类别的数据点。SVM 的理论基础包括以下几个重要的部分:
1. 基本概念
a. 超平面
在二维空间中,超平面是一条线,在三维空间中,超平面是一个平面。在更高维度的空间中,超平面是一个 n-1 维的子空间。
b. 支持向量
支持向量是那些离决策边界最近的数据点,这些点对决策边界的位置有重要影响。
c. 决策边界
决策边界是用来分隔不同类别的数据点的超平面。
2. 线性可分支持向量机
对于线性可分的数据集,SVM 通过以下步骤来找到最优决策边界:
a. 最大化边界
SVM 的目标是找到一个能够最大化边界(margin)的超平面。边界是指到最近的训练数据点(支持向量)的距离。
b. 优化问题
最大化边界可以被转化为一个优化问题:
在满足约束条件:
其中,
 是超平面的法向量,
 是偏置项,
 是数据点的类别标签,
 是数据点。
c. 拉格朗日对偶问题
使用拉格朗日乘子法将优化问题转化为对偶形式:
其中,
 是拉格朗日乘子。
对偶形式的目标是:
在满足约束条件:
3. 非线性支持向量机
对于非线性可分的数据集,SVM 使用核技巧(Kernel Trick)将数据映射到一个高维空间,在这个高维空间中数据是线性可分的。
a. 核函数
核函数 
 是用来计算两个数据点在高维空间中内积的函数,常见的核函数包括:
线性核:
多项式核:
高斯核(RBF核):
b. 优化问题(非线性)
在使用核函数后,优化问题的形式与线性 SVM 类似,只是将内积替换为核函数:
4. 软间隔支持向量机
对于线性不可分的数据集,SVM 通过引入松弛变量 
 来允许一定程度的误分类,从而找到一个最佳的平衡:
a. 优化问题(软间隔)
引入松弛变量后的优化问题为:
在满足约束条件:
其中,
 是一个超参数,用来控制误分类的惩罚程度。
5. SVM 的优缺点
优点:
能有效处理高维数据。
在样本数量少但特征数量多的情况下表现良好。
可以使用不同的核函数处理非线性分类问题。
缺点:
对于大规模数据集,训练时间较长。
对参数(如 
 和核函数的选择)比较敏感,需要进行调参。
对于不平衡的数据集,分类效果可能不理想。
以上是支持向量机的理论细节,涉及了基本概念、线性和非线性 SVM 的优化问题、软间隔 SVM 以及 SVM 的优缺点。
案例:数据集的分类
数据集生成
我们生成一个复杂的二维数据集,数据点分布在两个螺旋曲线上,这种数据集在二维空间中是非线性可分的。
生成数据集。
使用不同的核函数训练SVM模型。
绘制二维图,展示不同核函数下的分类结果。
将数据映射到三维空间,展示高维空间中的分类效果。
import numpy as npimport matplotlib.pyplot as pltfrom sklearn.datasets import make_moons, make_circlesfrom sklearn.svm import SVCfrom mpl_toolkits.mplot3d import Axes3Dfrom matplotlib import cm# 生成数据集def generate_spiral_data(n_points, noise):    n = np.sqrt(np.random.rand(n_points, 1)) * 780 * (2 * np.pi) / 360    d1x = -np.cos(n) * n + np.random.rand(n_points, 1) * noise    d1y = np.sin(n) * n + np.random.rand(n_points, 1) * noise    return np.hstack((d1x, d1y))n_points = 200noise = 0.5X = generate_spiral_data(n_points, noise)y = np.array([0] * (n_points//2) + [1] * (n_points//2))# 创建不同核函数的SVM模型models = [    ("Linear Kernel", SVC(kernel="linear")),    ("Polynomial Kernel (degree 3)", SVC(kernel="poly", degree=3)),    ("RBF Kernel", SVC(kernel="rbf", gamma=0.5))]# 绘制二维图fig, axes = plt.subplots(1, 3, figsize=(18, 6))for ax, (title, model) in zip(axes, models):    model.fit(X, y)    ax.scatter(X[:, 0], X[:, 1], c=y, cmap=plt.cm.coolwarm, edgecolors='k')    ax.set_title(title)        # 绘制决策边界    xx, yy = np.meshgrid(np.linspace(X[:, 0].min() - 1, X[:, 0].max() + 1, 500),                         np.linspace(X[:, 1].min() - 1, X[:, 1].max() + 1, 500))    Z = model.decision_function(np.c_[xx.ravel(), yy.ravel()])    Z = Z.reshape(xx.shape)    ax.contourf(xx, yy, Z, levels=np.linspace(Z.min(), 0, 7), cmap=plt.cm.PuBu)    ax.contour(xx, yy, Z, levels=[0], linewidths=2, colors='darkred')plt.show()

将数据映射到三维空间并进行可视化:
# 使用RBF核的模型model_rbf = SVC(kernel="rbf", gamma=0.5)model_rbf.fit(X, y)# 构建三维数据XX, YY = np.meshgrid(np.linspace(X[:, 0].min() - 1, X[:, 0].max() + 1, 50),                     np.linspace(X[:, 1].min() - 1, X[:, 1].max() + 1, 50))ZZ = model_rbf.decision_function(np.c_[XX.ravel(), YY.ravel()])ZZ = ZZ.reshape(XX.shape)fig = plt.figure(figsize=(12, 8))ax = fig.add_subplot(111, projection='3d')ax.scatter(X[:, 0], X[:, 1], y, c=y, cmap=plt.cm.coolwarm, edgecolors='k')ax.plot_surface(XX, YY, ZZ, cmap=cm.coolwarm, alpha=0.6)ax.set_title("3D Visualization with RBF Kernel")plt.show()

生成数据集:生成螺旋形数据集,这种数据集在二维平面中是非线性可分的。
训练模型:使用线性核、多项式核和RBF核训练SVM模型。
绘制二维图:展示不同核函数下的分类结果,并绘制决策边界。
绘制三维图:使用RBF核,将数据映射到三维空间,展示高维空间中的决策边界。
通过这些步骤,大家可以直观地比较不同核函数对复杂数据集分类的效果,并理解SVM在高维空间中的分类原理。
 
到顶部