You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

感知器算法(PLA)处理二维线性可分数据时输出错误分隔线求助

感知器模型(PLA)实现问题排查

问题背景

我正在为模拟二维数据实现感知器模型(PLA),运行后感知器输出的分隔线错误,算法会提前停止但仍存在误分类点,更换数据参数和样本量后问题仍存在。

数据生成代码

# numpoint
n = 15
# f(x) = w0 + ax1 + bx2
# then if f(x) = 0
# x2 = (-w0 - ax1)/b 
intercept = 30
a = 4
b = 2
# generate random points from 0 - 20
x1 = np.random.uniform(-20, 20, n) # return a np array
x2 = np.random.uniform(-20, 20, n)
y = []
# plot f(x)
plt.plot(x1, (-intercept - a*x1)/b, 'k-') 
plt.ylabel("x2")
plt.xlabel("x1")

# plot colored points
for i in range(0, len(x1)):
    f = intercept + a * x1[i] + b * x2[i]
    if (f <= 0):
        plt.plot(x1[i], x2[i], 'ro')
        y.append(-1)
    if (f > 0):
        plt.plot(x1[i], x2[i], 'bo')
        y.append(1)
y = np.array(y)
# Add x0 for threshold
x0 = np.ones(n)
stacked_x = np.stack((x0,x1,x2))
stacked_x

感知器模型代码

class PLA():
    def __init__(self, numPredictors):
        self.w = np.random.rand(1,numPredictors+1) # (1, numPredictors+1)
        self.iter = 0
    def fitModel(self, xData, yData):
        while(True): 
            yhat = np.matmul(self.w, xData).squeeze() # from(1,n) to (,n)
            compare = np.sign(yhat) == yData          
            ind = [i for i in range(0,len(compare)) if compare[i] == False] # misclassified index
            print(len(ind))
            if len(ind) == 0:    
                break
            for i in ind:
                update = yData[i]* xData[:, i] # 1d array
                self.w = self.w + np.transpose(update[:,np.newaxis]) # tranpose to match weight's shape
            self.iter += 1

模型可视化代码

pla1 = PLA(2)
pla1.fitModel(stacked_x, y)
# plot colored points
for i in range(0, len(x1)):
    if (y[i] == -1):
        plt.plot(x1[i], x2[i], 'ro')
    if (y[i] == 1):
        plt.plot(x1[i], x2[i], 'bo')
plt.plot(x1, (-pla1.w[0][0] - pla1.w[0][1]*x1)/(pla1.w[0][1]), 'g-', label = "PLA")
plt.plot(x1, (-intercept - a*x1)/b, 'k-', label = "f(x)")
plt.xlabel("x1")
plt.ylabel("x2")
plt.legend()

问题分析与修复

核心问题1:权重更新逻辑错误

PLA标准流程是每次迭代仅随机选取一个误分类样本更新权重,你当前代码在单次迭代中对所有误分类样本逐一更新,会导致权重被过度调整。迭代开始时的误分类检查仅针对当前权重状态,多次更新后部分样本暂时被正确分类,但仍有未处理的误分类样本,最终导致算法提前停止但仍存在错误。

核心问题2:可视化分母错误

绘制PLA分隔线时,错误使用了x1对应的权重pla1.w[0][1]作为分母,正确分母应为x2对应的权重pla1.w[0][2],这直接导致分隔线斜率计算错误。

修复后的代码

修正后的PLA类

class PLA():
    def __init__(self, numPredictors):
        self.w = np.random.rand(1, numPredictors+1)  # (1, numPredictors+1)
        self.iter = 0
    def fitModel(self, xData, yData):
        while(True): 
            yhat = np.matmul(self.w, xData).squeeze()  # from(1,n) to (,n)
            compare = np.sign(yhat) == yData          
            ind = [i for i in range(len(compare)) if not compare[i]]  # misclassified index
            print(f"Iteration {self.iter}: Misclassified samples: {len(ind)}")
            if len(ind) == 0:    
                break
            # 随机选取单个误分类样本更新权重
            selected_idx = np.random.choice(ind)
            update = yData[selected_idx] * xData[:, selected_idx]
            self.w += update.reshape(1, -1)  # 调整形状匹配权重维度
            self.iter += 1

修正后的可视化代码

pla1 = PLA(2)
pla1.fitModel(stacked_x, y)
# plot colored points
for i in range(len(x1)):
    if y[i] == -1:
        plt.plot(x1[i], x2[i], 'ro')
    else:
        plt.plot(x1[i], x2[i], 'bo')
# 修正分母为x2对应的权重系数
plt.plot(x1, (-pla1.w[0][0] - pla1.w[0][1]*x1)/pla1.w[0][2], 'g-', label = "PLA")
plt.plot(x1, (-intercept - a*x1)/b, 'k-', label = "f(x)")
plt.xlabel("x1")
plt.ylabel("x2")
plt.legend()
plt.show()

额外优化建议

  • 初始化权重时可使用更小的随机值(如np.random.randn(1, numPredictors+1)*0.1),避免初始权重过大增加迭代次数。
  • 添加最大迭代次数限制,防止极端情况出现死循环。

内容的提问来源于stack exchange,提问作者Punpun Punyama

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 19:13:19