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

不使用SKlearn,用Python实现基于TF-IDF的应用类别多分类逻辑回归

不用Sklearn实现多分类逻辑回归(TF-IDF多标签分类)

嘿,咱们一步步来搞定不用Sklearn的多分类逻辑回归实现!我会把核心逻辑、代码落地,还有你可能碰到的坑都讲清楚。

1. 先搞定标签编码

多分类问题首先得把「健康」「社交」这类文本标签转成模型能识别的数值格式,one-hot编码是最常用的方式——每个标签对应一个独热向量,比如「健康」对应[1,0,0],「社交」对应[0,1,0]。

import numpy as np
import pandas as pd

# 假设你的DataFrame名为df,包含'data'(TF-IDF数组)和'labels'(类别标签)列
unique_labels = df['labels'].unique()
label_to_idx = {label: idx for idx, label in enumerate(unique_labels)}
num_classes = len(unique_labels)

# 定义标签转独热向量的函数
def label_to_onehot(label):
    onehot = np.zeros(num_classes)
    onehot[label_to_idx[label]] = 1
    return onehot

# 转换标签为one-hot矩阵,同时把TF-IDF数组转成二维特征矩阵
y = np.array([label_to_onehot(label) for label in df['labels']])
X = np.array(df['data'].tolist())  # 确保X形状是(样本数, 特征数)

2. 实现多分类逻辑回归的核心函数

多分类逻辑回归依赖Softmax函数输出每个类别的概率(保证所有类别概率和为1),用交叉熵损失衡量预测值和真实值的差异,再通过梯度下降更新模型参数。

def softmax(z):
    # 减去每行最大值防止指数爆炸(数值稳定技巧)
    exp_z = np.exp(z - np.max(z, axis=1, keepdims=True))
    return exp_z / np.sum(exp_z, axis=1, keepdims=True)

def cross_entropy_loss(y_pred, y_true):
    # 加极小值避免log(0)报错
    epsilon = 1e-10
    return -np.sum(y_true * np.log(y_pred + epsilon)) / y_true.shape[0]

def compute_gradients(X, y_true, y_pred):
    m = X.shape[0]
    # 权重梯度:(特征矩阵转置 @ 预测与真实值的差) / 样本数
    dw = np.dot(X.T, (y_pred - y_true)) / m
    # 偏置梯度:预测与真实值的差的均值
    db = np.sum(y_pred - y_true, axis=0) / m
    return dw, db

3. 模型训练流程

初始化权重和偏置,然后用梯度迭代更新参数:

def train_multinomial_logreg(X, y, learning_rate=0.01, epochs=1000):
    n_samples, n_features = X.shape
    n_classes = y.shape[1]
    
    # 小随机值初始化权重(避免梯度消失/爆炸),偏置初始化为0
    np.random.seed(42)  # 固定随机种子,方便结果复现
    w = np.random.randn(n_features, n_classes) * 0.01
    b = np.zeros(n_classes)
    
    loss_history = []
    
    for epoch in range(epochs):
        # 前向传播:计算预测概率
        z = np.dot(X, w) + b
        y_pred = softmax(z)
        
        # 计算并记录损失
        loss = cross_entropy_loss(y_pred, y)
        loss_history.append(loss)
        
        # 反向传播:计算梯度
        dw, db = compute_gradients(X, y, y_pred)
        
        # 更新参数
        w -= learning_rate * dw
        b -= learning_rate * db
        
        # 每100轮打印一次损失,监控训练进度
        if epoch % 100 == 0:
            print(f"Epoch {epoch:4d} | Loss: {loss:.4f}")
    
    return w, b, loss_history

4. 预测函数

训练完成后,用模型对新的TF-IDF数据做预测:

def predict(X, w, b):
    z = np.dot(X, w) + b
    y_pred = softmax(z)
    # 取概率最大的类别索引,再转回原标签
    pred_idx = np.argmax(y_pred, axis=1)
    idx_to_label = {v: k for k, v in label_to_idx.items()}
    return [idx_to_label[idx] for idx in pred_idx]

你可能碰到的坑&解决办法

  • TF-IDF数组形状错误:如果X不是二维矩阵,检查df['data']里的每个元素是否是一维特征数组,用np.array(df['data'].tolist())强制转换
  • 标签编码混乱:确保每个标签对应唯一索引,可打印label_to_idx验证
  • 损失不下降/震荡:调整学习率(比如从0.01改成0.1或0.001),或者增加训练轮数;也可以试试学习率衰减(比如每轮乘以0.99)
  • 数值不稳定:Softmax里一定要加「减去每行最大值」的操作,否则大的指数值会导致溢出

快速测试

假设你有测试集的TF-IDF数组X_test,可以这样用:

# 训练模型(根据你的数据调整学习率和轮数)
w, b, loss_history = train_multinomial_logreg(X, y, learning_rate=0.1, epochs=1500)

# 预测测试数据
test_predictions = predict(X_test, w, b)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:24:04