如何为scikit-learn的KNeighborsClassifier提供自定义样本权重
如何在scikit-learn的KNeighborsClassifier中使用自定义样本权重
嘿,我来帮你搞定这个自定义权重的需求!你当前用weights='distance'让模型基于距离倒数给邻居加权,但想要替换成自己定义的权重规则对吧?分两种常见场景给你具体的实现方案:
场景1:给每个训练样本分配固定的全局权重
如果你希望某些训练样本在分类时拥有更高的优先级(比如标记为更可靠的样本),可以在模型拟合时结合sample_weight参数。这个参数允许你给每个训练样本设置一个固定权重,模型在计算邻居投票时会把这个权重和距离权重(如果有的话)结合起来。
举个例子:
import sklearn.neighbors as neighbors import numpy as np # 假设你的训练数据和标签 X_train = np.array([[1,2], [3,4], [5,6], [7,8], [9,10]]) y_train = np.array([0,1,2,3,0]) # 自定义每个训练样本的权重:比如第0个样本权重设为2,其他为1(让它的投票更有分量) sample_weights = np.array([2, 1, 1, 1, 1]) # 初始化KNN模型,这里可以选择weights='uniform'或者保留'distance' knn = neighbors.KNeighborsClassifier( n_neighbors=7, weights='uniform', # 先设为均匀权重,后续结合sample_weights algorithm='auto', leaf_size=30, p=1, metric='minkowski' ) # 拟合时传入自定义的样本权重 knn.fit(X_train, y_train, sample_weight=sample_weights)
这里的逻辑是:每个邻居的最终投票权重 = 样本本身的sample_weight × 距离相关权重(如果weights设为'distance'的话),相当于给重要样本的投票加了buff。
场景2:自定义邻居权重的计算逻辑(替代weights='distance')
如果你想完全自定义权重的计算规则(比如不用距离倒数,而是用距离的平方、或者其他和距离/样本相关的逻辑),可以直接给weights参数传入一个自定义函数。这个函数只需要接收一个参数——测试样本到邻居的距离数组,然后返回对应的权重数组就行。
比如我们自定义一个“距离倒数平方”的权重规则:
def custom_weight_func(distances): # 加个epsilon避免除以0的情况 epsilon = 1e-6 # 自定义权重:距离越小,权重越大,这里用距离的倒数平方 weights = 1 / (distances ** 2 + epsilon) # 也可以在这里加入其他逻辑,比如给特定距离范围的邻居加权重 # 比如:weights[distances < 2] *= 2 return weights # 初始化模型时传入自定义函数 knn = neighbors.KNeighborsClassifier( n_neighbors=7, weights=custom_weight_func, # 替换成你的自定义权重函数 algorithm='auto', leaf_size=30, p=1, metric='minkowski' ) # 正常拟合和预测就行 knn.fit(X_train, y_train) y_pred = knn.predict(X_test)
如果你的自定义权重需要依赖训练样本的其他属性(而不只是距离),那原生的KNeighborsClassifier可能没法直接支持。这时候你可以考虑继承KNeighborsClassifier重写相关方法,或者手动实现KNN的核心逻辑来融入你的自定义规则。
小提醒
- 自定义权重函数返回的权重最好是非负的,并且可以考虑归一化(比如除以权重总和),这样投票的权重分配会更合理。
- 当同时使用
sample_weight和自定义weights函数时,最终的权重是两者的乘积,这点要注意哦。
内容的提问来源于stack exchange,提问作者Jefferson Abraham
相关产品推荐
相关产品推荐

