一、题目
预测提供的新闻数据属于哪个类别。
二、数据
数据为新闻文本,并按照字符级别进行匿名处理。整合划分出14个候选分类类别:财经、彩票、房产、股票、家居、教育、科技、社会、时尚、时政、体育、星座、游戏、娱乐的文本数据。
数据由以下几个部分构成:训练集20w条样本,测试集A包括5w条样本,测试集B包括5w条样本。处理后的训练数据如下:
label | text |
---|---|
6 | 57 44 66 56 2 3 3 37 5 41 9 57 44 47 45 33 13 63 58 31 17 47 0 1 1 69 26 60 62 15 21 12 49 18 38 20 50 23 57 44 45 33 25 28 47 22 52 35 30 14 24 69 54 7 48 19 11 51 16 43 26 34 53 27 64 8 4 42 36 46 65 69 29 39 15 37 57 44 45 33 69 54 7 25 40 35 30 66 56 47 55 69 61 10 60 42 36 46 65 37 5 41 32 67 6 59 47 0 1 1 68 |
在数据集中标签的对应的关系如下:
{'科技': 0, '股票': 1, '体育': 2, '娱乐': 3, '时政': 4, '社会': 5, '教育': 6, '财经': 7, '家居': 8, '游戏': 9, '房产': 10, '时尚': 11, '彩票': 12, '星座': 13}
赛题数据来源为互联网上的新闻,通过收集并匿名处理得到。
三、 评测标准
评价标准为类别f1_score的均值,结果与实际测试集的类别进行对比,结果越大越好。
可以通过sklearn完成f1_score计算:
from sklearn.metrics import f1_scorey_true = [0, 1, 2, 0, 1, 2]y_pred = [0, 2, 1, 0, 0, 1]f1_score(y_true, y_pred, average='macro')
四、代码
# 读取数据print("读取数据...")train_df = pd.read_csv('data/train_set.csv', sep='\t')test_df = pd.read_csv('data/test_a.csv', sep='\t')# 查看数据基本信息print(f"训练集大小: {train_df.shape}")print(f"测试集大小: {test_df.shape}")print(f"训练集列名: {train_df.columns.tolist()}")print(f"训练集标签分布:\n{train_df['label'].value_counts()}")# 特征工程:使用TF-IDF向量化文本print("文本向量化...")vectorizer = TfidfVectorizer(max_features=10000, ngram_range=(1, 2))X_train = vectorizer.fit_transform(train_df['text'])X_test = vectorizer.transform(test_df['text'])y_train = train_df['label']# 划分训练集和验证集X_train_split, X_val_split, y_train_split, y_val_split = train_test_split( X_train, y_train, test_size=0.2, random_state=42, stratify=y_train)# 模型调参和训练print("训练模型...")# 模型1: 逻辑回归model1 = LogisticRegression(random_state=42, max_iter=1000)model1.fit(X_train_split, y_train_split)# 模型2: 随机森林model2 = RandomForestClassifier(n_estimators=100, random_state=42)model2.fit(X_train_split, y_train_split)# 模型3: 朴素贝叶斯model3 = MultinomialNB()model3.fit(X_train_split, y_train_split)# 验证模型print("验证模型...")y_val_pred1 = model1.predict(X_val_split)y_val_pred2 = model2.predict(X_val_split)y_val_pred3 = model3.predict(X_val_split)f1_1 = f1_score(y_val_split, y_val_pred1, average='macro')f1_2 = f1_score(y_val_split, y_val_pred2, average='macro')f1_3 = f1_score(y_val_split, y_val_pred3, average='macro')print(f"逻辑回归模型F1得分: {f1_1}")print(f"随机森林模型F1得分: {f1_2}")print(f"朴素贝叶斯模型F1得分: {f1_3}")# 模型融合print("模型融合...")# 使用加权平均进行模型融合y_val_pred_ensemble = []for i in range(len(y_val_pred1)): # 根据验证集表现分配权重 weights = [f1_1, f1_2, f1_3] weights = [w / sum(weights) for w in weights] # 归一化权重 # 统计每个类别的加权票数 votes = {} for model_idx, pred in enumerate([y_val_pred1[i], y_val_pred2[i], y_val_pred3[i]]): if pred not in votes: votes[pred] = 0 votes[pred] += weights[model_idx] # 选择得票最多的类别 ensemble_pred = max(votes, key=votes.get) y_val_pred_ensemble.append(ensemble_pred)f1_ensemble = f1_score(y_val_split, y_val_pred_ensemble, average='macro')print(f"融合模型F1得分: {f1_ensemble}")# 预测测试集print("预测测试集...")y_test_pred1 = model1.predict(X_test)y_test_pred2 = model2.predict(X_test)y_test_pred3 = model3.predict(X_test)# 模型融合预测y_test_pred_ensemble = []for i in range(len(y_test_pred1)): # 根据验证集表现分配权重 weights = [f1_1, f1_2, f1_3] weights = [w / sum(weights) for w in weights] # 归一化权重 # 统计每个类别的加权票数 votes = {} for model_idx, pred in enumerate([y_test_pred1[i], y_test_pred2[i], y_test_pred3[i]]): if pred not in votes: votes[pred] = 0 votes[pred] += weights[model_idx] # 选择得票最多的类别 ensemble_pred = max(votes, key=votes.get) y_test_pred_ensemble.append(ensemble_pred)# 生成提交文件print("生成提交文件...")submission = pd.DataFrame({'label': y_test_pred_ensemble})submission.to_csv('data/submission.csv', index=False)print("完成!提交文件已保存为 data/submission.csv")
代码分析
1. 数据准备与预处理
数据加载
- 使用pandas读取训练集(
train_set.csv
)和测试集(test_a.csv
),以制表符分隔打印了数据集的基本信息,包括大小、列名和标签分布,便于初步了解数据数据探索
- 检查了训练集的维度、列名和标签分布,这是数据探索的重要步骤标签分布信息有助于识别潜在的类别不平衡问题
2. 特征工程
文本向量化
使用TfidfVectorizer
将原始文本转换为TF-IDF特征向量
关键参数设置:
max_features=10000
:限制特征数量,控制维度ngram_range=(1, 2)
:考虑单个词和双词组合,捕捉更多上下文信息分别对训练集(fit_transform
)和测试集(transform
)进行转换,避免数据泄露
3. 模型训练与验证
数据集划分
使用train_test_split
划分训练集和验证集
参数设置合理:
test_size=0.2
:20%数据用于验证stratify=y_train
:保持标签分布一致性random_state=42
:确保可重复性模型选择与训练
实现了三种不同的分类模型:
逻辑回归(LogisticRegression)
- 线性模型,适合高维稀疏特征设置
max_iter=1000
确保收敛随机森林(RandomForestClassifier)
- 集成方法,能捕捉非线性关系使用100棵树(
n_estimators=100
)朴素贝叶斯(MultinomialNB)
- 适合文本数据的概率模型计算高效,适合大规模数据
模型评估
- 使用F1分数(macro平均)作为评估指标,适合多分类问题在验证集上评估各模型性能,为后续模型融合提供权重依据
4. 模型融合
加权投票融合
- 根据各模型在验证集上的F1分数分配权重权重归一化处理,确保总和为1对每个样本,计算各模型的加权投票结果选择得票最多的类别作为最终预测
融合效果验证
- 在验证集上评估融合模型的F1分数比较单模型和融合模型的性能差异