机器学习 - Kaggle项目实践(8)Spooky Author Identification 作者识别

Spooky Author Identification | Kaggle

Approaching (Almost) Any NLP Problem on Kaggle (参考)

Spooky Author Identification | Kaggle (My work)

根据三位的一些作品训练集,三分类测试集是哪个作家写的概率。

目录

1. 数据导入&格式display

2. 损失函数的定义

3. 数据准备

4. 两种向量化编码 TF-IDF和词频统计Count

5. 机器学习分类模型

5.1 逻辑回归

5.2 朴素贝叶斯模型

5.3 对TF-IDF SVD降维+标准化后 SVM

6. Grid_Search 参数调优

6.1 Grid_Search_SVM

6.2 Grid_Search_贝叶斯

7. GloVe词向量 + XGboost

8. GloVe词向量 + 深度学习

8.1 构建embedding_matrix 作为词嵌入层

8.2 LSTM / 双头LSTM / GRU

8.3 预测+提交


1. 数据导入&格式display

import pandas as pd
import numpy as np
train = pd.read_csv('/kaggle/input/spooky-author-identification/train.zip')
test = pd.read_csv('/kaggle/input/spooky-author-identification/test.zip')
sample = pd.read_csv('/kaggle/input/spooky-author-identification/sample_submission.zip')display(train.head())
display(test.head())
display(sample.head())

test 数据包含id 和 text内容;train中还多一个标签 哪个作者写的。

submission_sample中为 id 以及text为每个作者的概率(每行均为训练集中每个作者的比例)

2. 损失函数的定义

多类别对数损失函数;仅i属于类别j时 y=1;即 pij 越大越好

def multiclass_logloss(actual, predicted, eps=1e-15):# 步骤1: 将整数标签转换为one-hot编码if len(actual.shape) == 1:actual2 = np.zeros((actual.shape[0], predicted.shape[1]))for i, val in enumerate(actual):actual2[i, val] = 1  # 对应 y_ij = 1 (当j=真实类别时)actual = actual2# 步骤2: 防止log(0)的情况,将概率裁剪到[eps, 1-eps]范围clip = np.clip(predicted, eps, 1 - eps)  # 对应 p_ij# 步骤3: 计算损失rows = actual.shape[0]  # 对应 N (样本数量)vsota = np.sum(actual * np.log(clip))  # 对应 ΣΣ [y_ij * log(p_ij)]# 步骤4: 最终计算return -1.0 / rows * vsota  # 对应 - (1/N) * ΣΣ [y_ij * log(p_ij)]

3. 数据准备

target为作者名称 使用LabelEncoder() 转换为0 1 2 编码; 并划分训练集测试集

from sklearn import preprocessing
from sklearn.model_selection import train_test_split
lbl_enc = preprocessing.LabelEncoder()
y = lbl_enc.fit_transform(train.author.values)
xtrain, xvalid, ytrain, yvalid = train_test_split(train.text.values, y, stratify=y, random_state=42, test_size=0.1, shuffle=True)

4. 两种向量化编码 TF-IDF和词频统计Count

from sklearn.feature_extraction.text import TfidfVectorizer, CountVectorizer# TF-IDF特征提取
tfv = TfidfVectorizer(min_df=3, max_features=None, strip_accents='unicode', analyzer='word', token_pattern=r'\w{1,}',ngram_range=(1, 3), use_idf=1, smooth_idf=1, sublinear_tf=1,stop_words='english')# 拟合并转换数据
tfv.fit(list(xtrain) + list(xvalid))  # 在训练集+验证集上学习词汇表
xtrain_tfv = tfv.transform(xtrain)    # 转换训练集为TF-IDF矩阵
xvalid_tfv = tfv.transform(xvalid)    # 转换验证集为TF-IDF矩阵# Count向量化特征提取
ctv = CountVectorizer(analyzer='word',            # 按单词进行分词token_pattern=r'\w{1,}',    # 匹配至少1个字符的单词ngram_range=(1, 3),         # 使用1-gram, 2-gram, 3-gramstop_words='english'        # 移除英文停用词
)# 拟合并转换数据
ctv.fit(list(xtrain) + list(xvalid))  # 在训练集+验证集上学习词汇表
xtrain_ctv = ctv.transform(xtrain)    # 转换训练集为词频矩阵
xvalid_ctv = ctv.transform(xvalid)    # 转换验证集为词频矩阵print(f"TF-IDF特征维度: {xtrain_tfv.shape}")
print(f"Count特征维度: {xtrain_ctv.shape}")

5. 机器学习分类模型

5.1 逻辑回归

fit + 预测 predict_proba + 之前定义的损失

from sklearn.linear_model import LogisticRegression
# Fitting a simple Logistic Regression on TFIDF
clf = LogisticRegression(C=1.0)
clf.fit(xtrain_tfv, ytrain)
predictions = clf.predict_proba(xvalid_tfv)print ("logloss: %0.3f " % multiclass_logloss(yvalid, predictions))# Fitting a simple Logistic Regression on Counts
clf = LogisticRegression(C=1.0)
clf.fit(xtrain_ctv, ytrain)
predictions = clf.predict_proba(xvalid_ctv)print ("logloss: %0.3f " % multiclass_logloss(yvalid, predictions))

5.2 朴素贝叶斯模型

from sklearn.naive_bayes import MultinomialNB
# Fitting a simple Naive Bayes on TFIDF
clf = MultinomialNB()
clf.fit(xtrain_tfv, ytrain)
predictions = clf.predict_proba(xvalid_tfv)print ("logloss: %0.3f " % multiclass_logloss(yvalid, predictions))# Fitting a simple Naive Bayes on Counts
clf = MultinomialNB()
clf.fit(xtrain_ctv, ytrain)
predictions = clf.predict_proba(xvalid_ctv)print ("logloss: %0.3f " % multiclass_logloss(yvalid, predictions))

5.3 对TF-IDF SVD降维+标准化后 SVM

因为SVM对特征尺度敏感 需要降维+scale 加快收敛

from sklearn import decomposition,preprocessing
from sklearn.svm import SVC# 1. SVD降维
svd = decomposition.TruncatedSVD(n_components=120)
svd.fit(xtrain_tfv)
xtrain_svd = svd.transform(xtrain_tfv)
xvalid_svd = svd.transform(xvalid_tfv)# 2. 数据标准化
scl = preprocessing.StandardScaler()
scl.fit(xtrain_svd)
xtrain_svd_scl = scl.transform(xtrain_svd)
xvalid_svd_scl = scl.transform(xvalid_svd)# 3. SVM训练和评估
clf = SVC(C=1.0, probability=True, random_state=42)
clf.fit(xtrain_svd_scl, ytrain)
predictions = clf.predict_proba(xvalid_svd_scl)print("SVM在SVD降维特征上的logloss: %0.3f" % multiclass_logloss(yvalid, predictions))

6. Grid_Search 参数调优

需要准备  1.estimator模型管道    2.param_grid参数网络    3.scoring评分器

6.1 Grid_Search_SVM

1. 根据损失函数 创建评分器

from sklearn import metrics, pipeline
from sklearn.model_selection import GridSearchCV
# 1. 创建评分器
mll_scorer = metrics.make_scorer(multiclass_logloss, greater_is_better=False, needs_proba=True)
# 自定义的多类别对数损失函数转换为scikit-learn的评分器
# greater_is_better=False:logloss越小越好,所以设为False
# needs_proba=True:需要概率预测而不是类别标签

2. 降维+标准化+SVM 三个步骤创建管道

# 2. 创建管道 三个步骤
svd = decomposition.TruncatedSVD()
scl = preprocessing.StandardScaler()
lr_model = LogisticRegression()clf = pipeline.Pipeline([('svd', svd),      # 第一步:SVD降维('scl', scl),      # 第二步:数据标准化('lr', lr_model)   # 第三步:逻辑回归
])

3. 参数网络  降维数 / 正则化 类型与大小

# 3. 定义参数网格
param_grid = {'svd__n_components': [120, 180],  # SVD组件数'lr__C': [0.1, 1.0, 10],         # 正则化强度'lr__penalty': ['l1', 'l2']      # 正则化类型
}

4. 执行网格搜索 输出最优结果

# 4. 网格搜索
model = GridSearchCV(estimator=clf, param_grid=param_grid, scoring=mll_scorer,verbose=10, n_jobs=-1, refit=True, cv=2)# 5. 执行网格搜索
model.fit(xtrain_tfv, ytrain)# 6. 输出最佳结果
print("Best score: %0.3f" % model.best_score_)
print("Best parameters set:")
best_parameters = model.best_estimator_.get_params()
for param_name in sorted(param_grid.keys()):print("\t%s: %r" % (param_name, best_parameters[param_name]))

6.2 Grid_Search_贝叶斯

参数:拉普拉斯平滑(Laplace smoothing) 的强度

# GridSearch 三个准备
nb_model = MultinomialNB()clf = pipeline.Pipeline([('nb', nb_model)])param_grid = {'nb__alpha': [0.001, 0.01, 0.1, 1, 10, 100]}model = GridSearchCV(estimator=clf, param_grid=param_grid, scoring=mll_scorer,verbose=10, n_jobs=-1, refit=True, cv=2)
# 搜索输出最佳结果
model.fit(xtrain_tfv, ytrain)
print("Best score: %0.3f" % model.best_score_)
print("Best parameters set:")
best_parameters = model.best_estimator_.get_params()
for param_name in sorted(param_grid.keys()):print("\t%s: %r" % (param_name, best_parameters[param_name]))

7. GloVe词向量 + XGboost

加载为 word->vector 的 embeddings_index = { }

文件中每行第一个词代表word 后面300维代表向量

# 1. 加载GloVe词向量
from tqdm import tqdmembeddings_index = {}
with open('/kaggle/input/glove840b300dtxt/glove.840B.300d.txt', 'r', encoding='utf-8') as f:for line in tqdm(f):values = line.split()word = values[0]# 检查是否有足够的数值if len(values) == 301:  # 1个词 + 300个数字try:coefs = np.asarray(values[1:], dtype='float32')embeddings_index[word] = coefsexcept:continueprint('Found %s word vectors.' % len(embeddings_index))

将每个句子 tokenize分词;移除停用词 只保留字母;

所有词向量求和,并除以模长得到单位向量,作为句子的词向量

# 2. 转换文本为向量
from nltk.tokenize import word_tokenize
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
def sent2vec(s):# 1. 文本预处理words = str(s).lower()           # 转换为小写words = word_tokenize(words)     # 分词:将句子拆分成单词列表words = [w for w in words if w not in stop_words]  # 移除停用词(如'the', 'is', 'and'等)words = [w for w in words if w.isalpha()]          # 只保留纯字母单词(移除数字和标点)# 2. 获取每个词的词向量M = []for w in words:try:M.append(embeddings_index[w])  # 从GloVe词典中获取词的300维向量except:continue  # 如果词不在GloVe词典中,跳过# 3. 处理空句子情况if len(M) == 0:return np.zeros(300)  # 如果没有有效词,返回300维零向量# 4. 组合词向量为句子向量M = np.array(M)           # 转换为numpy数组,形状为 (n_words, 300)v = M.sum(axis=0)         # 对所有词的向量求和,得到300维向量# 5. 向量归一化(单位化)norm = np.sqrt((v ** 2).sum())  # 计算向量的模长if norm > 0:v = v / norm  # 将向量除以其模长,得到单位向量else:v = np.zeros(300)  # 避免除以零return vxtrain_glove = np.array([sent2vec(x) for x in tqdm(xtrain)])
xvalid_glove = np.array([sent2vec(x) for x in tqdm(xvalid)])

调用XGboost

import xgboost as xgb
clf = xgb.XGBClassifier(max_depth=7,            # 每棵树的最大深度,控制模型复杂度n_estimators=200,       # 树的数量(弱学习器的数量)colsample_bytree=0.8,   # 每棵树使用的特征比例,防止过拟合subsample=0.8,          # 每棵树使用的样本比例,防止过拟合n_jobs=10,              # 并行线程数,加速训练learning_rate=0.1,      # 学习率,控制每棵树的贡献程度random_state=42,        # 随机种子,确保结果可重现verbosity=1             # 输出训练信息(替代silent参数)
)
clf.fit(xtrain_glove, ytrain)
predictions = clf.predict_proba(xvalid_glove)print ("logloss: %0.3f " % multiclass_logloss(yvalid, predictions))

8. GloVe词向量 + 深度学习

8.1 构建embedding_matrix 作为词嵌入层

由于神经网络拟合概率 将作家0 1 2转换为独热编码

# y转换为独热编码
from keras.utils import to_categorical
ytrain_enc = to_categorical(ytrain)
yvalid_enc = to_categorical(yvalid)

分词+相同长度填充;句子 -> 每个词对应token数值

from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
token = Tokenizer(num_words=None)
max_len = 70token.fit_on_texts(list(xtrain) + list(xvalid))
xtrain_seq = token.texts_to_sequences(xtrain)
xvalid_seq = token.texts_to_sequences(xvalid)# zero pad the sequences
xtrain_pad = pad_sequences(xtrain_seq, maxlen=max_len)
xvalid_pad = pad_sequences(xvalid_seq, maxlen=max_len)

数值 -> 词向量 作为embedding

word_index = token.word_index
# create an embedding matrix for the words we have in the dataset
embedding_matrix = np.zeros((len(word_index) + 1, 300))
for word, i in tqdm(word_index.items()):embedding_vector = embeddings_index.get(word)if embedding_vector is not None:embedding_matrix[i] = embedding_vector

8.2 LSTM / 双头LSTM / GRU

循环层用 LSTM; Bi-directional LSTM ; GRU 

冻结嵌入层 -> 空间Dropout -> 循环层 -> 全连接Dense层 -> 输出层三分类

from keras.models import Sequential
from keras.layers import Embedding, SpatialDropout1D, GRU, Dense, Dropout, Activation, LSTM, Bidirectional
from keras.callbacks import EarlyStoppingmodel = Sequential()# 嵌入层:使用预训练的GloVe词向量
model.add(Embedding(len(word_index) + 1,      # 词汇表大小 + 1(为未知词预留)300,                      # 词向量维度(300维)weights=[embedding_matrix],  # 预训练的词向量矩阵input_length=max_len,     # 输入序列的最大长度trainable=False           # 冻结嵌入层,不更新词向量
))model.add(SpatialDropout1D(0.3))# model.add(LSTM(300, dropout=0.3, recurrent_dropout=0.3)) 若用LSTM
# model.add(Bidirectional(LSTM(300, dropout=0.3, recurrent_dropout=0.3))) 若用双头LSTM
# 下两行对应 GRU
model.add(GRU(300, dropout=0.3, recurrent_dropout=0.3, return_sequences=True))
model.add(GRU(300, dropout=0.3, recurrent_dropout=0.3))model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.8))model.add(Dense(1024, activation='relu'))
model.add(Dropout(0.8))# 输出层:3个神经元(对应3个类别),Softmax激活函数
model.add(Dense(3))  # 3分类问题
model.add(Activation('softmax'))# 编译模型:使用分类交叉熵损失,Adam优化器
model.compile(loss='categorical_crossentropy', optimizer='adam',metrics=['accuracy'])# Fit the model with early stopping callback
earlystop = EarlyStopping(monitor='val_loss', min_delta=0, patience=3, verbose=0, mode='auto')
model.fit(xtrain_pad, y=ytrain_enc, batch_size=512, epochs=100, verbose=1, validation_data=(xvalid_pad, yvalid_enc), callbacks=[earlystop])

8.3 预测+提交

texts_seq = token.texts_to_sequences(test.text.values)
texts_pad = pad_sequences(texts_seq, maxlen=max_len)
y_pred = model.predict(texts_pad)sample[["EAP", "HPL", "MWS"]] = y_pred
sample.to_csv('submission.csv', index=False)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/95653.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/95653.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[frontend]WebGL是啥?

对于初学者来说,通常的建议是: 不要直接从原生 WebGL 开始,而是先使用一个基于 WebGL 的高级框架或库,最著名的就是 Three.js。 webgl是啥 three.js是啥? Three.js 封装了 WebGL 的复杂细节,提供了更简单、…

[光学原理与应用-400]:设计 - 深紫外皮秒脉冲激光器 - 元件 - 声光调制器AOM

声光调制器(Acousto-Optic Modulator, AOM)是深紫外皮秒脉冲激光器中实现脉冲主动控制、频率稳定及光束管理的核心元件。其通过声波与光波的弹光相互作用,在皮秒时间尺度内实现激光强度、频率或传播方向的精准调制。以下从工作原理、关键性能…

25高教社杯数模国赛【D题顶流思路+问题分析】

注:本内容由”数模加油站“ 原创出品,虽无偿分享,但创作不易。欢迎参考teach,但请勿抄袭、盗卖或商用。后续都在”数模加油站“......

利用 openssl api 实现 TLS 双向认证

1. 环境 openssl1.1.1gwget https://github.com/openssl/openssl/releases/download/OpenSSL_1_1_1g/openssl-1.1.1g.tar.gz sha256 为: ddb04774f1e32f0c49751e21b67216ac87852ceb056b75209af2443400636d46Linux 环境 2. 静态编译 openssl tar -zxvf openssl-1.1.1…

低代码开发平台技术总结

一、 核心定义 低代码开发平台(Low-Code Development Platform, LCDP)是一种通过图形化界面、可视化建模、拖拽组件和模型驱动逻辑来构建应用程序的开发环境。其核心目标是显著减少传统手写代码的数量,从而降低开发门槛,提升应用交…

Web与Nginx网站服务

文章目录前言1、Web 概念1.1 Web 的特点1.2 B/S 架构模型1.3 Web 请求与响应过程1.4 静态资源与动态资源1.5 Web 的发展阶段1.6 小结2、HTTP 与 HTTPS 协议2.1 http与https区别2.2 HTTPS 握手流程2.3 HTTP状态码2.3.1 HTTP 状态码概览2.3.2 常用状态码详解3、Nginx 概念3.1 Ngi…

【算法--链表】25.K个一组翻转链表--通俗讲解

一、题目是啥?一句话说清 给你一个链表,每k个节点一组进行反转,如果最后剩余的节点不足k个,则保持原状。需要实际交换节点,而不仅仅是改变值。 示例: 输入:head = [1,2,3,4,5], k = 2 输出:[2,1,4,3,5](因为每2个一组反转,最后剩余5不足2个,保持原状) 二、解题核…

Git指令 | 个人学习笔记

主要包含git的日常核心操作。 1.创建新仓库 创建新文件夹&#xff0c;打开&#xff0c;然后执行。 git init2.创建一个本地仓库的克隆版本 先cd到指定的目录下&#xff0c;再 git clone /path/to/respository # 指定远程分支 git clone -b <分支名> <仓库地址> …

Apache 的安装及基本使用

1 Apache 简介Apache HTTP Server&#xff08;通常简称 “Apache”&#xff09;是世界上最流行、历史最悠久的开源 Web 服务器软件之一&#xff0c;由 Apache 软件基金会&#xff08;Apache Software Foundation&#xff09;维护。它的核心功能是接收客户端&#xff08;如浏览器…

五大主流大语言模型(LLM)对比

文章目录&#x1f916; 五大主流大型语言模型&#xff08;LLM&#xff09;对比1. ChatGPT (GPT-5) - OpenAI2. Claude 4 (Sonnet & Opus) - Anthropic3. Gemini 2.5 Pro - Google DeepMind4. Grok 4 - xAI5. DeepSeek R1 - 深度求索五款模型的综合对比表&#x1f680; 该如…

redo log详解

在 MySQL 中&#xff0c;Redo Log&#xff08;重做日志&#xff09; 是 InnoDB 存储引擎实现事务持久性&#xff08;ACID 中的 D&#xff09; 的核心机制&#xff0c;同时也通过 “预写日志&#xff08;Write-Ahead Logging, WAL&#xff09;” 策略提升了数据写入性能。它记录…

Linux awk命令完全指南:从原理到实战,搞定文本处理难题

在Linux世界里&#xff0c;文本处理是运维、开发绕不开的日常——从分析日志、提取配置信息到统计数据&#xff0c;都需要高效的工具支撑。而awk&#xff0c;作为一款强大的文本分析语言&#xff0c;凭借“按字段处理”的核心能力&#xff0c;成为了比grep&#xff08;单纯匹配…

毕业项目推荐:68-基于yolov8/yolov5/yolo11的水稻虫害检测识别系统(Python+卷积神经网络)

文章目录 项目介绍大全&#xff08;可点击查看&#xff0c;不定时更新中&#xff09;概要一、整体资源介绍技术要点功能展示&#xff1a;功能1 支持单张图片识别功能2 支持遍历文件夹识别功能3 支持识别视频文件功能4 支持摄像头识别功能5 支持结果文件导出&#xff08;xls格式…

Qt为什么要引入QML语言?

Qt发布于1991年&#xff0c;经过30多年的发展&#xff0c;Qt/C已经成为了众多学子&#xff0c;拿来学习C的首选框架。Qt/Widgets&#xff0c;相对于其他界面库&#xff08;如GNOME、KDE&#xff09;&#xff0c;其实已经很优秀&#xff0c;已经可以成为number one了。在已经是第…

设计模式在Java中的应用:从单例模式到工厂模式的全面解析!

全文目录&#xff1a;开篇语前言1. 单例模式&#xff1a;确保全局只有一个实例1.1 饿汉式单例1.2 懒汉式单例1.3 双重检查锁定&#xff08;DCL&#xff09;2. 工厂模式&#xff1a;简化对象创建2.1 简单工厂模式2.2 工厂方法模式2.3 抽象工厂模式3. 其他设计模式3.1 观察者模式…

Meta AIUCSD放大招:DeepConf 让大语言模型推理既快又准,84.7%的token节省+近乎完美的准确率!

1. 【前言】 Meta&UCSD 大语言模型&#xff08;LLMs&#xff09; 在推理任务中通过自一致性等测试时缩放方法展现出巨大潜力&#xff0c;但存在精度收益递减和计算开销高的问题。为此&#xff0c;Meta与UCSD的研究人员提出DeepConf方法&#xff0c;它利用模型内部的置信度信…

解决leetcode第3671.子序列美丽值求和问题

3671. 子序列美丽值求和难度&#xff1a;困难问题描述&#xff1a;给你一个长度为 n 的整数数组 nums。对于每个 正整数 g&#xff0c;定义 g 的 美丽值 为 g 与 nums 中符合要求的子序列数量的乘积&#xff0c;子序列需要 严格递增 且最大公约数&#xff08;GCD&#xff09;恰…

电机控制(一)-电机分类

电机分类 电机分类&#xff1a; 电机的拓扑模型并没有发生太大变化,变化较大的是控制电机的方法。 常见的电机类型有&#xff1a; 步进电机vs伺服电机 在工业自动化、机器人、精密设备等领域&#xff0c;步进电机和伺服电机是两种最常用的驱动电机&#xff0c;但两者的核心…

【Qt】QToolBar、QToolButton的常用用法

一、QToolBar 常用用法 QToolBar 是 Qt 中用于创建工具栏的控件&#xff0c;可快速放置常用功能按钮、分隔符或自定义控件&#xff0c;并支持拖动停靠、浮动等特性。 1. 基础创建与添加到主窗口 // 在 QMainWindow 中创建工具栏 QToolBar *toolBar new QToolBar(tr("主工…

DVWA靶场通关笔记-验证码绕过Insecure CAPTCHA (Impossible级别)

目录 一、reCAPTCHA 1、配置security为Impossible级别。 2、配置RECAPTCHA参数 3、再次打开靶场 二、源码分析 1、index.php 2、impossible.php 3、功能函数 三、reCAPTCHA 防范分析 1、严格的参数验证与处理 2、预处理防止SQL注入 3、CAPTCHA 验证通过 4、验证当前…