罗兰关于MATLAB的艺术

将想法转化为MATLAB

数学与字-字嵌入与MATLAB和文本分析工具箱

文本数据已成为重要的组成部分数据分析,这要归功于自然语言处理的进步,自然语言处理将非结构化文本转换为有意义的数据文本分析工具箱在MATLAB中提供处理和分析文本数据的工具。

今天的嘉宾博客古原竹内介绍新工具箱中提供的一些很酷的功能,从单词嵌入.看看他是怎么使用的情绪分析发现入住波士顿的AirBnB酒店位置不错

内容

什么是单词嵌入?

你听说过word2vec手套?这些是非常强大的自然语言处理技术的一部分,叫做词嵌入,现在你可以通过文本分析工具箱在MATLAB中利用它。

为什么我对它感到兴奋?它把单词“嵌入”到向量空间模型根据一个单词与其他单词的相似度。在互联网规模下,您可以尝试捕捉向量中单词的语义,这样类似的单词就有类似的向量。

关于单词嵌入如何表示这种关系的一个非常著名的例子是,你可以像这样做一个矢量计算:

$$国王-男人+女人大约皇后$$

是的,“皇后”和“国王”很像,除了它是一个女人,而不是一个男人!多酷啊?多亏了互联网上大量的原始文本数据,这种魔力才得以实现,更大的计算能力,可以处理它,以及人工神经网络的进展,例如深度学习

更令人兴奋的是,如果您使用预先训练过的模型,您不必成为自然语言处理专家来利用单词嵌入的力量!让我向您展示如何将它用于您自己的文本分析目的,例如文档分类信息检索情绪分析

成分

在这个例子中,我将使用一个预先训练过的词嵌入手套.请跟着我走

请将存档文件中的内容解压缩到当前文件夹中。

从手套中加载预先训练好的词嵌入

你可以使用这个函数readWordEmbedding在文本分析工具箱中读取预先训练过的单词嵌入。要查看单词向量,请使用word2vec为了得到一个给定单词的向量表示,因为这个嵌入的维数是300,所以我们为每个单词得到一个300个元素的向量。

文件名=“glove.6B.300d”如果存在(文件名+“.mat”“文件”) ~= 2 emb = readwordem寝具(文件名+' . txt ');保存(文件名+“.mat”“循证”“-v7.3”);其他的负载(文件名+“.mat”结束v_k = word2vec (emb,“国王”)”“谁沃金
名称大小字节类属性v_king 300x1 1200单

向量数学示例

让我们试试向量数学吧!下面是另一个著名的例子:

$$巴黎-法国+波兰\大约华沙$$

显然,向量减法“巴黎-法国”编码了“首都”的概念,如果加上“波兰”,就得到了“华沙”。

我们用MATLAB试试。word2vec返回单词嵌入中给定单词的向量向量2字找出在单词嵌入中与向量最接近的单词。

v_paris = word2vec (emb,“巴黎”);v_france = word2vec (emb,“法国”);v_poland = word2vec (emb,“波兰”);Vec2word (emb, v_paris - v_france + v_波兰)
ans=“华沙”

可视化单词嵌入

我们希望使用textscatter绘图,但如果包含单词嵌入中的所有400000个单词,则很难将其可视化。我找到了4000个英语名词的列表。让我们仅使用这些单词,并使用tsne(t分布随机邻居嵌入)降维。为了更容易看到单词,我放大到情节中包含与食物相关的单词的特定区域。你可以看到相关的词被放在一起。

如果存在(“nouns.mat”“文件”) ~= 2 url =“http://www.desiquintans.com/downloads/nounlist/nounlist.txt”;名词= webread (url);名词=分裂(名词);保存(“nouns.mat”“名词”);其他的负载(“nouns.mat”结束名词(~ ismember(名词、emb.Vocabulary)) = [];vec = word2vec (emb、名词);rng (“默认”);%的再现性xy = tsne (vec);图textscatter (xy,名词)标题(手套词嵌入(6B.300d) -食品相关领域)轴([-35 -10 -36 -14]);集(gca),“剪裁”“关”)轴心

使用词语嵌入进行情感分析

对于一个词嵌入的实际应用,让我们考虑情感分析。我们通常会利用已经存在的情感词汇,比如这个来自芝加哥的伊利诺伊大学.它包含2006个肯定词和4783个否定词。让我们使用自定义函数加载词典load_lexicon

如果我们仅仅依靠词典里可用的单词,我们只能给6789个单词打分。一个想法是用“嵌入”这个词来找到与这些情感词相近的词。

pos = load_lexicon (“positive-words.txt”);neg = load_lexicon (“negative-words.txt”)[长度(正)长度(负)]
Ans = 2006 4783

单词嵌入符合机器学习

如果我们使用单词向量作为训练数据来开发一个分类器,可以对40万单词嵌入中的所有单词进行评分,会怎么样?我们可以利用相关单词在单词嵌入中紧密相连的这一事实来做到这一点。让我们制作一个情感分类器,利用词嵌入的向量。

第一步,我们将从词向量中得到词在词典中的嵌入向量,创建一个300列的预测器矩阵,然后使用积极或消极的情绪标签作为响应变量。这是单词的预览,反应变量和300个预测变量中的前7个。

%删除不在嵌入的单词pos=pos(ismember(pos,emb.词汇));neg=neg(ismember(neg,emb.词汇));%得到相应的单词向量v_pos = word2vec (emb、pos);neg v_neg = word2vec (emb);%初始化表并添加数据数据=表;数据。词= (pos;底片);pred = [v_pos; v_neg];Data = [Data array2table(pred)];数据。resp = 0(高度(数据),1);data.resp(1:长度(pos)) = 1;%预览表格头(数据(:,(1、结束2:8)))
ans = 8×9表词resp pred1 pred2 pred3 pred4 pred5 pred6 pred7  _____________ ____ _________ _________ _________ ________ __________ _________ __________ " 富于“1 0.081981 -0.27295 0.32238 0.19932 0.099266 0.60253 0.18819”丰富“1 -0.037126 0.085212 0.26952 0.20927 -0.014547 0.52336 0.11287“丰富”1 -0.038408 0.076613 -0.094277“丰富的”1 -0.29317 -0.068101 -0.44659 -0.31563 -0.13791 - 0.4888 - 1894“可访问的”1 -0.45096 -0.46794 - 0.11761 - 0.7075 - 0.26262“称赞的”1 - 0.69129 -0.11164 - 0.3615 -0.4499 - 0.44146 -0.0067972“称赞的”1 - 0.69129 - 0.04812 - 0.29267 - 0.1242 -0.13791 - 0.44888 - 1894“称赞的”1-0.026593 -0.60759 -0.15785 0.36048 -0.45289 0.0092178 0.074671

为机器学习准备数据

让我们将数据划分为培训集和保留集,以进行性能评估。保留集包含30%的可用数据。

rng (“默认”%的再现性c = cvpartition (data.resp“坚持”, 0.3);火车=数据(训练(c), 2:结束);Xtest =数据(测试(c), 2: end-1);欧美= data.resp(测试(c));lte =数据(测试(c), 1);lte。标签=欧美;

情感分类器的训练和评价

我们想要构建一个分类器,它可以在词嵌入定义的向量空间中分离正词和负数词。为了快速评估性能,我在可能的机器学习算法中选择了快速而简单的线性判别法。

这是你的电话号码混淆矩阵这个模型。分类准确率为91.1%。不坏。

%的火车模型mdl = fitcdiscr(火车,“resp”);%基于试验数据的预测Xtest Ypred =预测(mdl);cf = confusionmat(欧美,Ypred);%显示结果Figure vals = {“负面”“积极”};热图(val, vals, cf);包含(“预测标签”) ylabel (“真正的标签”)标题({线性判别的混淆矩阵...斯普林特(的分类精度% .1f % %...sum(cf(逻辑(眼睛(2)))/sum(sum(cf))*100})

让我们把预测的情绪得分和实际标签进行对比。自定义类情绪采用线性判别模型对情感进行评分。

scoreWords本班记分方法。积极的分数代表积极的情绪,消极的分数代表消极的情绪。现在我们可以用40万个词来衡量情感。

dbtypesentiment.m18:26
18功能得分=得分单词(obj,单词)19%得分单词情感得分20向量=单词2VEC(obj.emb,单词);%字向量21如果大小(vec,2)~=obj.emb.Dimension%检查num cols 22 vec=vec';%根据需要换位23结束24[~,分数,~]=预测(obj.mdl,vec);%获取类概率25分=分数(:,2)-分数(:,1);%正面得分-负面得分26结束

让我们测试这个自定义类。如果标签为0且得分为负,或者标签为1且得分为正,则模型正确地对单词进行了分类。否则,这个词就被错分类了。

下面的表格显示了测试集中的10个例子:

  • 这个词
  • 其情绪标签(0 =消极,1 =积极)
  • 其情绪得分(负=负,正=正)
  • 评估(true =正确,false =不正确)
发送=情绪(emb、mdl);lte。分数= sent.scoreWords (Ltest.word);lte。eval = lte。score > 0 == Ltest.label;disp (lte (randsample(高度(lte), 10),:))
文字标签得分eval _____________ _____________ _____“逃亡”0 -0.90731真“不幸”0 -0.98667真“杰出”1 0.99999真“不情愿”0 -0.99694真“笨”0 -0.99957真“无忧无虑”1 0.97568真“催眠”1 0.4801真“slug”0 -0.88944真“天使”1 0.43419真“甜言蜜语”0 -0.98412真

现在我们需要一种方法来记录人类语言文本的情感,而不是一个单词scoreText情感课的方法是平均文本中每个单词的情感分数。这可能不是最好的方法,但这是一个简单的起点。

dbtypesentiment.m28:33
28 function score = scoreText(obj,text) 29% scoreText得分情感文本30 token = split(lower(text));% split text into token 31 scores = obj.scoreWords(token);32 score = mean(scores,'omitnan');%平均分数33结束

这是由scoreText方法——非常积极,有些积极,和消极。

[sent.scoreText](“这太棒了”...sent.scoreText (“这是好的”...sent.scoreText (“这很糟糕”)]
Ans = 0.91458 0.80663 -0.073585

波士顿Airbnb开放数据

让我们用来自Kaggle上的波士顿Airbnb开放数据页面的评论数据试试这个方法。首先,我们想看看人们在评论中是怎么说的词云.文本分析工具箱提供简化文本预处理工作流程的功能,例如tokenizedDocument哪个将文档解析为一个令牌数组,和bagOfWords生成术语频率计数模型(这可以用来构建机器学习模型)。

被注释掉的代码将生成如本文顶部所示的单词云。然而,你也可以使用双字短语生成单词云。可以用docfun,它对令牌数组进行操作。您还可以看到,它可以生成三角图和其他n克通过修改函数句柄。

似乎很多评论都是关于地点的!

选择= detectImportOptions (“listings.csv”);l = readtable (“listings.csv”,选项);评论=可读(“reviews.csv”);评论= tokenizedDocument (reviews.comments);评论=低(评论);评论= removeWords(评论,stopWords);评论= removeShortWords(注释2);评论= erasePunctuation(评论);% == uncomment生成单词云==% bag = bagOfWords(comments);%身材% wordcloud(袋);%标题(“AirBnB评论词云”)%生成二元字云f=@(s)s(1:end-1)+”“+ s(2:结束);三元= docfun (f,评论);bag2 = bagOfWords(三元);图wordcloud (bag2);标题(“AirBnB Review Bigram云”

Airbnb审查评级

评论评分也是可用的,但评分确实偏向于100,这意味着绝大多数列表都是完美的(真的吗?)作为这XCKD漫画所示,我们有在线评分的问题关于评论评级。这不是很有用。

图直方图(l.review_scores_rating)标题(“AirBnB评价评级的分布”)包含(“评估评级”) ylabel (“#清单”

计算情绪得分

现在让我们对Airbnb的房舍评论进行评分。因为一个列表可以有许多评论,我将使用每个列表的情绪得分中位数。波士顿的情绪得分中值总体上处于正区间,但它遵循正态分布。这个看起来更真实。

给评论打分f = @(str) send . scoretext (str);评论。情绪= cellfun (f, reviews.comments);%通过列表计算审查分数中位数(G,上市)= findgroups(评论(:,“listing_id”)); listings.touction=splitapply(@median,...reviews.sentiment G);%可视化结果图直方图(listings.sentiment)标题(“波士顿AirBnB Listing的人气”)包含(“情绪得分中值”) ylabel (上市公司的数量

按地点划分的情绪

二元组云显示,评论者经常对位置和距离进行评论。您可以使用列表的纬度和经度来查看情绪得分很高或很低的列表位于哪里。如果你看到一组高分,也许它们表明了你住的好地方。

%加入情绪分数和上市信息加入= innerjoin (...上市,l (:, {“id”“纬度”“经度”...“社区清洁”}),...“LeftKeys”“listing_id”“RightKeys”“id”);joined.Properties。VariableNames{结束}=“已”%丢弃带有NaN情感分数的列表加入(isnan (joined.sentiment ),:) = [];%将情绪分数离散化为桶加入。猫=离散化(joined.sentiment 0:0.25:1,...“绝对的”, {“< 0.25”“< 0.50”“< 0.75”“< = 1.00”});%删除未定义的类别猫=类别(joined.cat);加入(isundefined (joined.cat ),:) = [];颜色变量colorlist =冬天(长度(猫));%生成图Latlim = [42.300 42.386];Lonlim = [-71.1270 -71.0174];负载boston_map.mat图imagesc(lonlim,latlim, map)保持gscatter(连接.经度,连接.纬度,连接.cat,颜色列表,“o”)举行Dar = [1, cosd(mean(latlim)), 1];daspect (dar)组(gca,“ydir”“正常”);轴([lonlim latlim])标题(“波士顿Airbnb房源的情绪评分”) [g,ngh] = findgroups(join (:,“已”));ngh.Properties。VariableNames{结束}=“名字”;已。lat = splitapply (@mean, joined.latitude, g);已。朗= splitapply (@mean, joined.longitude, g);%的注释文本(ngh.lon (2), ngh.lat (2), ngh.name (2),“颜色”' w ')文本(ngh.lon (4), ngh.lat (4), ngh.name (4),“颜色”' w ')文本(ngh.lon(6)、ngh.lat(6)、ngh.name(6),“颜色”' w ')文本(ngh.lon (11), ngh.lat (11), ngh.name (11),“颜色”' w ')文本(ngh.lon(13)、ngh.lat(13)、ngh.name(13),“颜色”' w ')文本(ngh.lon (17), ngh.lat (17), ngh.name (17),“颜色”' w ')文本(ngh.lon (18), ngh.lat (18), ngh.name (18),“颜色”' w ')文本(ngh.lon (22), ngh.lat (22), ngh.name (22),“颜色”' w '

总结

在这篇文章中,我重点介绍了单词嵌入和情感分析,作为文本分析工具箱中新功能的一个示例。希望您看到工具箱使高级文本处理技术变得非常容易访问。除了情绪分析,您还可以使用单词嵌入做更多的工作,工具箱还提供了单词嵌入以外的更多功能,例如潜在语义分析潜在狄利克雷分配

希望在未来我有更多的机会讨论文本分析工具箱中其他有趣的功能。

获得一个免费试用版本,让我们知道你的想法在这里




发布与MATLAB®R2017b

|

评论

要留下评论,请点击在这里登录到您的MathWorks帐户或创建一个新帐户。