【Python机器学习】NLP词频背后的含义——反馈及改进

之前学习的LSA方法都没有考虑文档之间的相似度信息,创建的主题对一组通用规则来说是最优的。在这些特征(主题)提取模型的无监督学习中,没有任何关于主题向量之间应该多么接近的数据。我们也不允许任何关于主题向量在哪里结束或者它们之间相关性如何的反馈。引导或者"习得型距离指标"是在降维和特征提取方面的最新进展。通过调整向聚类和嵌入算法报告的距离分数,我们可以控制自己的向量,从而让它们使一些代价函数最小化。通过这种方式,可以"强制"向量专注于我们感兴趣的信息内容的某个方面。

线性判别分析

下面是在一个标注好的短消息数据集上训练一个线性判别分析(LDA)模型。LDA的工作原理与LSA类似,但是它需要分类标签或其他分数才能找到高维空间中维度(词袋或TF-IDF向量中的词项)的最佳线性组合。LDA没有最大化新空间中所有向量之间的分离程度(方差),而是最大化了每个类质心向量之间的距离。

但是,这意味着必须通过给出样例(标注好的向量)来告诉LDA算法想对哪些主题建模。只有这样,算法才能计算出从高维空间到低维空间的最优转换。得到的低维向量的维数不能超过所能提供的类标签或分数的数量。

因为只需要训练一个"垃圾性"主题,下面看一维主题模型在垃圾短消息分类方面能达到多高的精确率:

python 复制代码
from nlpia.data.loaders import get_data
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
from nltk.tokenize import casual_tokenize

sms=get_data('sms-spam')
index=['sms{}{}'.format(i,'!'*j) for (i,j) in zip(range(len(sms)),sms.spam)]
sms.index=index
tfidf=TfidfVectorizer(tokenizer=casual_tokenize)
tfidf_docs=tfidf.fit_transform(raw_documents=sms.text).toarray()
tfidf_docs=tfidf_docs-tfidf_docs.mean(axis=0)

lda=LDA(n_components=1)
lda=lda.fit(tfidf_docs,sms.spam)
sms['lda_spaminess']=lda.predict(tfidf_docs)
print(((sms.spam-sms.lda_spaminess)**2.0).sum()**0.5)
print((sms.spam==sms.lda_spaminess).sum())
print(len(sms))

可以看到,精确率为100%。在TF-IDF向量中有10000个词项,它可以"记住"答案。

下面做一些交叉验证:

python 复制代码
from sklearn.model_selection import cross_val_score
lds=LDA(n_components=1)
scores=cross_val_score(lda,tfidf_docs,sms.spam,cv=5)
print('精确率:',scores.mean(),scores.std()*2)

可以看到,效果并不好。为了确保76%的精确率数值是正确的,下面保留1/3的数据集用于测试:

python 复制代码
from sklearn.model_selection import train_test_split
X_train,X_text,y_train,y_test=train_test_split(tfidf_docs,sms.spam,test_size=0.33,random_state=271828)
lda=LDA(n_components=1)
lda.fit(X_train,y_train)

print(lda.score(X_text,y_test).round(3))

同样的,测试集的精确率也很低。因此,并不像是数据抽样做的不好,这是一个糟糕的过拟合模型。

下面看LSA和LDA结合起来是否有助于创建一个精确的、泛化能力强的模型,这样面对新的短消息时就不会出错:

python 复制代码
import pandas as pd
from sklearn.decomposition import PCA
pca=PCA(n_components=16)
pca=pca.fit(tfidf_docs)
pca_topicvectors=pca.transform(tfidf_docs)
columns=['topic{}'.format(i) for i in range(pca.n_components)]
pca_topicvectors=pd.DataFrame(pca_topicvectors,columns=columns,index=index)
X_train,X_text,y_train,y_test=train_test_split(pca_topicvectors.values,sms.spam,test_size=0.3,random_state=271828)
lda=LDA(n_components=1)
lda.fit(X_train,y_train)
print(lda.score(X_text,y_test).round(3))
lda=LDA(n_components=1)
scores=cross_val_score(lda,pca_topicvectors,sms.spam,cv=10)
print('精确率:',scores.mean())

因此,通过使用LSA,我们可以刻画一个只有16个维度的短消息,并且仍然有足够的信息将它们分类为垃圾信息或非垃圾信息。低维模型不太可能过拟合,它应该有很好的泛化能力,并且能够对尚未看到的短消息或聊天信息进行分类。

在尝试所有这些语义分析之前,使用简单的LDA模型可以获得更高的精确率,这个新模型的优点是:现在可以在多于一个的维度上创建表示语句语义的向量。

相关推荐
bryant_meng34 分钟前
【python】OpenCV—Image Moments
开发语言·python·opencv·moments·图片矩
车载诊断技术1 小时前
电子电气架构 --- 什么是EPS?
网络·人工智能·安全·架构·汽车·需求分析
若亦_Royi1 小时前
C++ 的大括号的用法合集
开发语言·c++
KevinRay_1 小时前
Python超能力:高级技巧让你的代码飞起来
网络·人工智能·python·lambda表达式·列表推导式·python高级技巧
跃跃欲试-迪之1 小时前
animatediff 模型网盘分享
人工智能·stable diffusion
Captain823Jack2 小时前
nlp新词发现——浅析 TF·IDF
人工智能·python·深度学习·神经网络·算法·自然语言处理
被制作时长两年半的个人练习生2 小时前
【AscendC】ReduceSum中指定workLocal大小时如何计算
人工智能·算子开发·ascendc
资源补给站2 小时前
大恒相机开发(2)—Python软触发调用采集图像
开发语言·python·数码相机
Captain823Jack2 小时前
w04_nlp大模型训练·中文分词
人工智能·python·深度学习·神经网络·算法·自然语言处理·中文分词
m0_748247552 小时前
Web 应用项目开发全流程解析与实战经验分享
开发语言·前端·php