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

使用scikit-learn LabelEncoder编码数据时遇TypeError问题求助

解决LabelEncoder编码时的TypeError: unhashable type: 'list'问题

首先看你给出的报错核心信息:

TypeError: unhashable type: 'list'
...
TypeError: argument must be a string or number

这个错误的根源是你的标签数据被存成了列表类型,而sklearn.preprocessing.LabelEncoder只能处理可哈希的单个值(比如字符串、数字),无法处理列表作为输入。

问题出在哪里?

看你读取数据的这段代码:

for i ,line in enumerate(data.split("\n")):
    content = line.split('",')
    texts.append(content[0])
    labels.append(content[1:])  # 这里是关键错误!

content[1:]会返回一个列表(哪怕该位置只有一个元素),比如一行数据的标签是"spam",split后content[1:]会变成['spam'],而不是单个字符串'spam'。当LabelEncoder尝试处理这些列表时,就会抛出"不可哈希类型"的错误。

一步步修复方案

1. 修正标签读取逻辑

如果你每个样本只有一个标签,应该直接取content[1]而不是content[1:],同时清理掉残留的引号和换行符:

data = open('dataset.csv').read()
labels = []
texts = []
for i ,line in enumerate(data.split("\n")):
    # 跳过空行避免索引错误
    if not line.strip():
        continue
    content = line.split('",')
    # 清理文本开头的引号(比如第一个元素可能是"hello world)
    texts.append(content[0].strip('"'))
    # 提取单个标签,清理引号和换行
    raw_label = content[1].strip('"\n')
    labels.append(raw_label)

2. 不要重复训练LabelEncoder

你现在对训练集和验证集分别调用了fit_transform,这会导致编码规则不一致(比如训练集的"positive"可能被编码为0,验证集的"positive"可能因为fit时的顺序变成1)。正确的做法是只在训练集上拟合编码器,再用它转换验证集:

encoder = preprocessing.LabelEncoder()
train_y = encoder.fit_transform(train_y)
valid_y = encoder.transform(valid_y)  # 这里用transform,不要fit_transform

3. 修正特征提取器的列名错误

你的代码里写了count_vect.fit(trainDF['texts']),但DataFrame的列名是text(你定义的trainDF['text'] = texts),这里会抛出KeyError,要改成:

count_vect = CountVectorizer(analyzer='word', token_pattern=r'\w{1,}')
count_vect.fit(trainDF['text'])  # 是text不是texts
xtrain_count = count_vect.transform(train_x)
xvalid_count = count_vect.transform(valid_x)

tfidf_vect = TfidfVectorizer(analyzer='word', token_pattern=r'\w{1,}', max_features=5000)
tfidf_vect.fit(trainDF['text'])  # 同样修正列名
xtrain_tfidf = tfidf_vect.transform(train_x)
xvalid_tfidf = tfidf_vect.transform(valid_x)

4. 更可靠的CSV读取方式(可选推荐)

手动split读取CSV很容易出错(比如文本里包含逗号的情况),推荐直接用pandas的read_csv方法,它会自动处理引号和分隔符:

# 假设你的CSV第一行是表头:text,label
trainDF = pandas.read_csv('dataset.csv', quotechar='"', escapechar='\\')
# 直接获取text和label列,不需要手动循环处理
train_x, valid_x, train_y, valid_y = model_selection.train_test_split(
    trainDF['text'], trainDF['label'], test_size=0.2, random_state=0
)

修正后的完整代码示例

from sklearn import model_selection, preprocessing, linear_model, naive_bayes, metrics, svm
from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer
from sklearn import decomposition, ensemble
import pandas, xgboost, numpy, string

# 推荐用pandas读取CSV
trainDF = pandas.read_csv('dataset.csv', quotechar='"', escapechar='\\')

# 划分训练集和验证集
train_x, valid_x, train_y, valid_y = model_selection.train_test_split(
    trainDF['text'], trainDF['label'], test_size=0.2, random_state=0
)

# 编码标签
encoder = preprocessing.LabelEncoder()
train_y = encoder.fit_transform(train_y)
valid_y = encoder.transform(valid_y)

# CountVectorizer特征提取
count_vect = CountVectorizer(analyzer='word', token_pattern=r'\w{1,}')
count_vect.fit(trainDF['text'])
xtrain_count = count_vect.transform(train_x)
xvalid_count = count_vect.transform(valid_x)

# TF-IDF特征提取
tfidf_vect = TfidfVectorizer(analyzer='word', token_pattern=r'\w{1,}', max_features=5000)
tfidf_vect.fit(trainDF['text'])
xtrain_tfidf = tfidf_vect.transform(train_x)
xvalid_tfidf = tfidf_vect.transform(valid_x)

# 训练模型(假设你有train_model函数,注意补充valid_y参数)
accuracy = train_model(svm.SVC(), xtrain_tfidf, train_y, xvalid_tfidf, valid_y)
print(accuracy)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 14:57:29