牛客题解 | 实现AdaBoost拟合方法

题目## 题目

题目链接

AdaBoost(Adaptive Boosting)是一种常用的集成学习方法,其计算公式为:
f ( x ) = ∑ t = 1 T α t h t ( x ) f(x) = \sum_{t=1}^{T} \alpha_t h_t(x) f(x)=t=1Tαtht(x)
其中, h t ( x ) h_t(x) ht(x)是弱分类器, α t \alpha_t αt是权重, T T T是迭代次数。
该算法是深度学习中常用的集成学习方法之一。
本题使用了分类错误率作为错误率,并使用错误率来更新分类器权重。其公式为:
α t = 0.5 log ⁡ ( 1 − ϵ t ϵ t ) \alpha_t = 0.5 \log \left( \frac{1 - \epsilon_t}{\epsilon_t} \right) αt=0.5log(ϵt1ϵt)
其中, ϵ t \epsilon_t ϵt是分类错误率, ϵ t \epsilon_t ϵt=sum(w[y != prediction])/len(y)。

本题的一个小难点是,若错误率大于0.5,则需要将错误率取反后再进行对比,否则会导致分类器权重更新没有达到预期效果。

标准代码如下

def adaboost_fit(X, y, n_clf):
    n_samples, n_features = np.shape(X)
    w = np.full(n_samples, (1 / n_samples))
    clfs = []
    
    for _ in range(n_clf):
        clf = {}
        min_error = float('inf')
        
        for feature_i in range(n_features):
            feature_values = np.expand_dims(X[:, feature_i], axis=1)
            unique_values = np.unique(feature_values)
            
            for threshold in unique_values:
                p = 1
                prediction = np.ones(np.shape(y))
                prediction[X[:, feature_i] < threshold] = -1
                error = sum(w[y != prediction])
                
                if error > 0.5:
                    error = 1 - error
                    p = -1
                
                if error < min_error:
                    clf['polarity'] = p
                    clf['threshold'] = threshold
                    clf['feature_index'] = feature_i
                    min_error = error
        
        clf['alpha'] = 0.5 * math.log((1.0 - min_error) / (min_error + 1e-10))
        predictions = np.ones(np.shape(y))
        if clf['polarity'] == 1:
            predictions[X[:, clf['feature_index']] < clf['threshold']] = -1
        else:
            predictions[X[:, clf['feature_index']] > clf['threshold']] = -1
        w *= np.exp(-clf['alpha'] * y * predictions)
        w /= np.sum(w)
        clfs.append(clf)

    return clfs

题目链接

k-Means 聚类算法(k-Means Clustering)是一种常用的聚类算法,用于将数据集分为 k k k个簇。具体步骤如下:

  1. 随机选择 k k k个点作为初始聚类中心。
  2. 将每个点分配到最近的聚类中心
    本题使用欧几里得距离作为距离度量,即
    d ( x , y ) = ( x 1 − y 1 ) 2 + ( x 2 − y 2 ) 2 + ⋯ + ( x n − y n ) 2 d(x, y) = \sqrt{(x_1 - y_1)^2 + (x_2 - y_2)^2 + \cdots + (x_n - y_n)^2} d(x,y)=(x1y1)2+(x2y2)2++(xnyn)2
  3. 更新聚类中心为每个簇的平均值。
  4. 重复步骤2和步骤3,直到聚类中心不再变化或达到最大迭代次数。
通俗点说,就是把n个人分到k个组中,每次都要计算每个人到每个组的距离,然后选择距离最小的组,然后更新组中心。这样最后每个人都会分到离他最近的组中。

标准代码如下

def euclidean_distance(a, b):
    return np.sqrt(((a - b) ** 2).sum(axis=1))

def k_means_clustering(points, k, initial_centroids, max_iterations):
    points = np.array(points)
    centroids = np.array(initial_centroids)
    
    for iteration in range(max_iterations):
        # Assign points to the nearest centroid
        distances = np.array([euclidean_distance(points, centroid) for centroid in centroids])
        assignments = np.argmin(distances, axis=0)

        new_centroids = np.array([points[assignments == i].mean(axis=0) if len(points[assignments == i]) > 0 else centroids[i] for i in range(k)])
        
        # Check for convergence
        if np.all(centroids == new_centroids):
            break
        centroids = new_centroids
        centroids = np.round(centroids,4)
    return [tuple(centroid) for centroid in centroids]
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值