基于Bert和TextCNN的大学生学习资源推荐系统设计

一个基于用户课程评论数据,应用Bert和TextCNN进行大学生学习资源推荐系统的详细方案、实验过程和示例代码。

详细方案

1. 系统整体架构
  • 数据收集:收集大学生对课程的评论数据,这些数据可以来自学校的在线学习平台、课程评价网站等。
  • 数据预处理:对收集到的评论数据进行清洗、分词、标注等操作,将文本数据转换为适合模型输入的格式。
  • 特征提取:使用Bert模型对课程评论进行特征提取,将文本转换为向量表示。
  • 分类模型:使用TextCNN模型对课程评论进行分类,根据评论的情感倾向和主题,将课程分为不同的类别。
  • 推荐算法:根据用户的历史评论数据和课程分类结果,为用户推荐相关的学习资源。
2. 数据预处理
  • 清洗数据:去除评论中的特殊字符、HTML标签、停用词等。
  • 分词:使用中文分词工具(如jieba)对评论进行分词。
  • 标注数据:根据评论的情感倾向和主题,为每条评论标注相应的标签。
3. 特征提取
  • Bert模型:使用预训练的Bert模型对课程评论进行特征提取,将文本转换为固定长度的向量表示。
4. 分类模型
  • TextCNN模型:使用TextCNN模型对课程评论进行分类,根据评论的情感倾向和主题,将课程分为不同的类别。
5. 推荐算法
  • 基于内容的推荐:根据用户的历史评论数据和课程分类结果,为用户推荐相关的学习资源。

实验过程

1. 数据收集

从学校的在线学习平台、课程评价网站等收集大学生对课程的评论数据。

2. 数据预处理
  • 使用Python的正则表达式库和jieba分词工具对评论数据进行清洗和分词。
  • 根据评论的情感倾向和主题,为每条评论标注相应的标签。
3. 特征提取
  • 使用Hugging Face的transformers库加载预训练的Bert模型,对课程评论进行特征提取。
4. 分类模型训练
  • 使用PyTorch构建TextCNN模型,将Bert提取的特征作为输入,对课程评论进行分类。
  • 使用训练集对TextCNN模型进行训练,使用验证集对模型进行评估和调优。
5. 推荐算法实现
  • 根据用户的历史评论数据和课程分类结果,为用户推荐相关的学习资源。
6. 实验评估
  • 使用测试集对推荐系统进行评估,计算准确率、召回率、F1值等指标。

实验代码

import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import Dataset, DataLoader
from transformers import BertTokenizer, BertModel
import jieba
import re

# 数据预处理
def clean_text(text):
    text = re.sub(r'[^\u4e00-\u9fa5a-zA-Z0-9]', ' ', text)
    text = re.sub(r'\s+', ' ', text).strip()
    return text

def tokenize_text(text):
    return jieba.lcut(text)

# 自定义数据集类
class CourseReviewDataset(Dataset):
    def __init__(self, reviews, labels, tokenizer, max_length):
        self.reviews = reviews
        self.labels = labels
        self.tokenizer = tokenizer
        self.max_length = max_length

    def __len__(self):
        return len(self.reviews)

    def __getitem__(self, idx):
        review = self.reviews[idx]
        label = self.labels[idx]
        encoding = self.tokenizer.encode_plus(
            review,
            add_special_tokens=True,
            max_length=self.max_length,
            padding='max_length',
            truncation=True,
            return_tensors='pt'
        )
        input_ids = encoding['input_ids'].flatten()
        attention_mask = encoding['attention_mask'].flatten()
        return {
            'input_ids': input_ids,
            'attention_mask': attention_mask,
            'labels': torch.tensor(label, dtype=torch.long)
        }

# TextCNN模型
class TextCNN(nn.Module):
    def __init__(self, input_dim, num_filters, filter_sizes, num_classes):
        super(TextCNN, self).__init__()
        self.convs = nn.ModuleList([
            nn.Conv2d(in_channels=1,
                      out_channels=num_filters,
                      kernel_size=(fs, input_dim))
            for fs in filter_sizes
        ])
        self.fc = nn.Linear(len(filter_sizes) * num_filters, num_classes)

    def forward(self, x):
        x = x.unsqueeze(1)
        conved = [nn.functional.relu(conv(x)).squeeze(3) for conv in self.convs]
        pooled = [nn.functional.max_pool1d(conv, conv.shape[2]).squeeze(2) for conv in conved]
        cat = torch.cat(pooled, dim=1)
        return self.fc(cat)

# 训练模型
def train_model(model, dataloader, optimizer, criterion, device):
    model.train()
    total_loss = 0
    for batch in dataloader:
        input_ids = batch['input_ids'].to(device)
        attention_mask = batch['attention_mask'].to(device)
        labels = batch['labels'].to(device)

        optimizer.zero_grad()
        outputs = model(input_ids, attention_mask)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()
        total_loss += loss.item()
    return total_loss / len(dataloader)

# 评估模型
def evaluate_model(model, dataloader, criterion, device):
    model.eval()
    total_loss = 0
    correct = 0
    total = 0
    with torch.no_grad():
        for batch in dataloader:
            input_ids = batch['input_ids'].to(device)
            attention_mask = batch['attention_mask'].to(device)
            labels = batch['labels'].to(device)

            outputs = model(input_ids, attention_mask)
            loss = criterion(outputs, labels)
            total_loss += loss.item()

            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()
    accuracy = correct / total
    return total_loss / len(dataloader), accuracy

# 主函数
def main():
    # 超参数设置
    max_length = 128
    num_filters = 100
    filter_sizes = [3, 4, 5]
    num_classes = 5
    batch_size = 32
    num_epochs = 10
    learning_rate = 1e-4

    # 加载数据
    reviews = ["这门课程非常有趣", "老师讲得很清楚", "课程内容很实用"]
    labels = [1, 1, 1]

    # 数据预处理
    reviews = [clean_text(review) for review in reviews]
    reviews = [' '.join(tokenize_text(review)) for review in reviews]

    # 加载Bert分词器和模型
    tokenizer = BertTokenizer.from_pretrained('bert-base-chinese')
    bert_model = BertModel.from_pretrained('bert-base-chinese')

    # 划分数据集
    train_size = int(0.8 * len(reviews))
    train_reviews = reviews[:train_size]
    train_labels = labels[:train_size]
    test_reviews = reviews[train_size:]
    test_labels = labels[train_size:]

    # 创建数据集和数据加载器
    train_dataset = CourseReviewDataset(train_reviews, train_labels, tokenizer, max_length)
    train_dataloader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)
    test_dataset = CourseReviewDataset(test_reviews, test_labels, tokenizer, max_length)
    test_dataloader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)

    # 初始化TextCNN模型
    textcnn_model = TextCNN(bert_model.config.hidden_size, num_filters, filter_sizes, num_classes)

    # 定义损失函数和优化器
    criterion = nn.CrossEntropyLoss()
    optimizer = optim.Adam(textcnn_model.parameters(), lr=learning_rate)

    # 设备设置
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    textcnn_model.to(device)

    # 训练模型
    for epoch in range(num_epochs):
        train_loss = train_model(textcnn_model, train_dataloader, optimizer, criterion, device)
        test_loss, test_accuracy = evaluate_model(textcnn_model, test_dataloader, criterion, device)
        print(f'Epoch {epoch+1}/{num_epochs}, Train Loss: {train_loss:.4f}, Test Loss: {test_loss:.4f}, Test Accuracy: {test_accuracy:.4f}')

if __name__ == '__main__':
    main()

代码说明

  • 数据预处理:使用clean_text函数清洗评论数据,使用tokenize_text函数对评论进行分词。
  • 自定义数据集类CourseReviewDataset类用于将评论数据转换为适合模型输入的格式。
  • TextCNN模型TextCNN类定义了TextCNN模型的结构。
  • 训练和评估函数train_model函数用于训练模型,evaluate_model函数用于评估模型。
  • 主函数main函数实现了整个实验过程,包括数据加载、预处理、模型初始化、训练和评估。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值