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

从零实现GaussianNaiveBayes运行报无predict属性错误求助

代码问题排查与修复

核心错误:类方法缩进错误

Python 以缩进作为代码块的划分依据,你写的_calculate_likelihood、predict两个方法没有缩进进入GaussianNaiveBayes类的作用域,属于全局独立函数,不在类的成员属性范围内,所以实例化后调用predict会抛出属性不存在的报错。同时_classify_sample方法的缩进层级错误,需要和类内其他方法对齐。

修复后的完整分类器代码

import numpy as np
class GaussianNaiveBayes:
    def fit(self, X, y):
        n_samples, n_features = X.shape
        self._classes = np.unique(y)
        n_classes = len(self._classes)
        self._mean = np.zeros((n_classes, n_features), dtype=np.float64)
        self._var = np.zeros((n_classes, n_features), dtype=np.float64)
        self._priors =  np.zeros(n_classes, dtype=np.float64)
        # 计算每个类别的均值、方差和先验概率P(H)
        for i, c in enumerate(self._classes):
            X_for_class_c = X[y==c]
            self._mean[i, :] = X_for_class_c.mean(axis=0)
            self._var[i, :] = X_for_class_c.var(axis=0) + 1e-9 # 加极小值避免方差为0除以零
            self._priors[i] = X_for_class_c.shape[0] / float(n_samples)

    # 计算给定均值和方差时,数据X的似然度P(E|H)的函数
    def _calculate_likelihood(self, class_idx, x):
        mean = self._mean[class_idx]
        var = self._var[class_idx]
        num = np.exp(- (x-mean)**2 / (2 * var))
        denom = np.sqrt(2 * np.pi * var)
        return num / denom 

    # 通过计算类别后验概率P(H|E)完成分类
    def predict(self, X):
        y_pred = [self._classify_sample(x) for x in X]
        return np.array(y_pred)

    def _classify_sample(self, x):
        posteriors = []
        # 计算每个类别的后验概率
        for i, c in enumerate(self._classes):
            prior = np.log(self._priors[i])
            posterior = np.sum(np.log(self._calculate_likelihood(i, x)))
            posterior = prior + posterior
            posteriors.append(posterior)
        # 返回后验概率最高的类别
        return self._classes[np.argmax(posteriors)] 

测试代码适配修改

你传入fit的y是二维DataFrame格式,会导致类内索引X时报维度错误,需要将y转为一维数组:

from sklearn import datasets
from sklearn.model_selection import train_test_split
import pandas as pd

iris = datasets.load_iris()
X = pd.DataFrame(iris.data, columns = iris.feature_names)
y = pd.DataFrame(iris.target, columns = ['Target'])
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size = 0.2,random_state = 42)

nb = GaussianNaiveBayes()
# 把y转为一维数组传入
nb.fit(X_train.values, y_train.values.ravel())
predictions = nb.predict(X_test.values)

额外优化点

  • 在方差计算时加了1e-9的极小偏移量,避免某类特征取值完全一致时方差为0,导致似然计算出现除以零的报错
  • 预测时传入X的values属性,避免pandas DataFrame索引和numpy数组运算的兼容问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 04:54:03