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

代码报错AttributeError: 'function'无iterrows属性,如何获取模型准确率?

垃圾文本分类代码错误排查与准确率实现

问题概述

编写了基于pandas、nltk的垃圾文本分类代码,运行时触发错误AttributeError: 'function' object has no attribute 'iterrows',同时希望正确获取模型准确率,查阅accuracy_score文档后仍无法解决。

错误原因分析

  1. 主函数参数传递错误:在if __name__ == '__main__'中,最后一行print((text_classifier(accuracy_score)))将accuracy_score函数作为参数传给text_classifier,但text_classifier的第一个参数要求是pandas DataFrame,导致get_data函数中调用df.iterrows()时,df变成了accuracy_score函数,从而触发AttributeError。
  2. 特征提取逻辑混乱:
    • 混淆了数据集的标签列和文本列:spam.csv中v1是分类标签(ham/spam),v2是邮件文本,但原代码中错误地将row['v1']当作文本、row['v2']当作标签。
    • get_feature和get_feature_text函数逻辑不合理,比如text[-3]会在文本长度不足3时触发索引错误,且特征提取逻辑完全无法反映垃圾文本的特征;get_feature_text中错误使用DataFrame.rename处理字符串,属于API误用。
  3. 准确率获取方式未正确落地:原代码中text_classifier已经返回了准确率,但主函数调用错误,导致无法正确输出。

代码修正与优化

1. 修正核心错误点

  • 调整数据集列的使用逻辑,正确区分标签和文本。
  • 重写合理的特征提取函数(以文本长度和是否包含垃圾邮件常见关键词为例)。
  • 修正主函数的调用方式,正确输出准确率。
  • 同时支持用nltk自带的准确率方法和sklearn的accuracy_score计算准确率。

2. 完整修正代码

import pandas as pd
import nltk
from sklearn.metrics import accuracy_score

# 读取数据集,保留核心列并重命名
df = pd.read_csv('spam.csv', encoding='ISO-8859-1')
df = df[['v1', 'v2']].rename(columns={'v1': 'label', 'v2': 'text'})

# 特征提取函数:提取对垃圾邮件有区分度的特征
def get_features(text):
    text = text.lower()
    return {
        'text_length': len(text),
        'has_free': 'free' in text,
        'has_win': 'win' in text or 'winner' in text,
        'has_money': '$' in text or 'dollar' in text,
        'has_urgent': 'urgent' in text
    }

# 生成nltk分类器所需的(特征字典, 标签)格式数据
def process_dataset(df, feature_func=get_features):
    dataset = []
    for _, row in df.iterrows():
        label = row['label']
        text = row['text']
        if isinstance(text, str):
            dataset.append((feature_func(text), label))
    return dataset

# 划分训练集与测试集
def split_train_test(dataset, train_ratio=0.9):
    total = len(dataset)
    train_size = int(total * train_ratio)
    return dataset[:train_size], dataset[train_size:]

# 训练分类器并计算两种方式的准确率
def train_spam_classifier(df, feature_func=get_features):
    dataset = process_dataset(df, feature_func)
    train_data, test_data = split_train_test(dataset)
    
    # 训练朴素贝叶斯分类器
    classifier = nltk.NaiveBayesClassifier.train(train_data)
    
    # 用nltk自带方法计算准确率
    nltk_accuracy = nltk.classify.accuracy(classifier, test_data)
    
    # 用sklearn的accuracy_score计算准确率(验证结果)
    true_labels = [label for _, label in test_data]
    pred_labels = [classifier.classify(feat) for feat, _ in test_data]
    sklearn_accuracy = accuracy_score(true_labels, pred_labels)
    
    return classifier, nltk_accuracy, sklearn_accuracy

# 预测单条文本并可选输出准确率
def predict_single_text(text, show_accuracy=False):
    classifier, nltk_acc, sklearn_acc = train_spam_classifier(df)
    if show_accuracy:
        print(f"NLTK计算准确率: {nltk_acc:.4f}")
        print(f"Sklearn计算准确率: {sklearn_acc:.4f}")
    pred_result = classifier.classify(get_features(text))
    print(f"\n文本内容: {text}")
    print(f"预测分类: {pred_result}")
    classifier.show_most_informative_features(10)

if __name__ == '__main__':
    print("模型训练中...")
    # 预测单条文本并显示准确率
    predict_single_text("Win a free iPhone now! Click the link below!", show_accuracy=True)
    
    # 单独输出模型准确率
    _, nltk_acc, sklearn_acc = train_spam_classifier(df)
    print("\n模型最终准确率:")
    print(f"NLTK方法: {nltk_acc:.4f}")
    print(f"Sklearn方法: {sklearn_acc:.4f}")

关键说明

  1. 错误修复:主函数不再传递错误参数,正确传入数据集df,彻底解决iterrows的属性错误。
  2. 特征优化:替换原不合理的特征逻辑,改为提取垃圾邮件高频出现的关键词、文本长度等有效特征,提升模型分类能力。
  3. 准确率获取:
    • 使用nltk.classify.accuracy直接传入分类器和测试集,快速得到准确率。
    • 同时用sklearn的accuracy_score,通过提取测试集真实标签与预测标签计算结果,两种方法可互相验证。
  4. 数据处理:对原始spam.csv做了列精简与重命名,让数据结构更清晰,避免冗余列干扰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 20:02:23