罗兰谈MATLAB的艺术

将想法转化为MATLAB

请注意

罗兰谈MATLAB的艺术已存档,不会更新。

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

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

今天的嘉宾博主,古原竹内介绍新工具箱中可用的一些很酷的特性,从字嵌入.看看他是怎么用的情绪分析找到爱彼迎在波士顿的好住宿地点

内容

什么是词嵌入?

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

我为什么这么兴奋?它将单词“嵌入”到向量空间模型基于一个单词出现在其他单词附近的频率。在互联网规模上,您可以尝试捕获向量中单词的语义,以便相似的单词具有相似的向量。

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

$$king -男人+女人大约是皇后$$

是的,“王后”和“国王”很像,只不过她是女人,而不是男人!多酷啊!多亏了互联网上大量的原始文本数据,这种魔法才成为可能,更强大的计算能力可以处理它,以及人工神经网络的进展,如深度学习

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

成分

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

请将存档文件中的内容提取到当前文件夹中。

从GloVe加载预训练的词嵌入

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

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

向量数学实例

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

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

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

我们用MATLAB试试。word2vec返回单词嵌入中给定单词的向量,和vec2word找到单词embedding中最接近向量的单词。

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

可视化单词嵌入

我们想要可视化这个词嵌入使用textscatter但是,如果包括单词嵌入的全部40万个单词,就很难将其可视化。我找到了一个有4000个英语名词的列表。让我们只使用这些词,并使用将维数从300减少到2tsne(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”);(长度(pos)(否定)
Ans = 2006 4783

词嵌入满足机器学习

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

作为第一步,我们将从词汇库中的单词嵌入中获取向量,创建一个300列的预测因子矩阵,然后使用积极或消极的情绪标签作为响应变量。这里是单词的预览,响应变量和前7个预测变量的300。

删除不在嵌入中的单词pos = pos(ismember(pos,emb.Vocabulary));neg = neg(ismember(neg,emb.Vocabulary));获取相应的字向量V_pos = word2vec(emb,pos);V_neg = word2vec(emb,neg);初始化表并添加数据数据=表;数据。单词= [pos;neg];Pred = [v_pos;v_neg];Data = [Data array2table(pred)];数据。Resp = 0 (height(data),1);Data.resp (1:length(pos)) = 1;%预览表格头(数据(:,(1、结束2:8)))
Ans = 8×9 table word resp pred1 pred2 pred3 pred4 pred5 pred6 pred7 _____________ _____________ _________ _________ ________ __________ _________ __________ "abundant" 1 0.081981 -0.27295 0.32238 0.19932 0.099266 0.60253 0.18819 "abounds" 1 -0.037126 0.085212 0.26952 0.20927 -0.014547 0.52336 0.11287 "abundance" 1 -0.038408 0.076613 -0.094277 -0.10652 -0.43257 0.74405 0.41298 "abundant" 1 -0.29317 -0.068101 -0.44659 -0.31563 -0.13791 0.44888 0.31894 "accessible" 1 -0.45096 - 0.0.46794 0.11761-0.70256 0.19879 0.44775 0.26262“喝彩”1 0.07426 -0.11164 0.3615 -0.4499 -0.0061991 0.44146 -0.0067972“喝彩”1 0.69129 0.04812 0.29267 0.1242 0.083869 0.25791 -0.5444“喝彩”1 -0.026593 -0.60759 -0.15785 0.36048 -0.45289 0.0092178 0.074671

为机器学习准备数据

我们将数据划分为训练集和坚持集,用于性能评估。保留集包含30%的可用数据。

rng (“默认”再现率%C = cvpartition(data.resp,“坚持”, 0.3);Train = data(training(c),2:end);Xtest = data(test(c),2:end-1);Ytest = data.resp(test(c));Ltest = data(test(c),1);lte。标签= Ytest;

情感分类器的训练与评估

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

这是混淆矩阵这个模型。结果分类准确率为91.1%。不坏。

%列车模型MDL =火车,“职责”);对测试数据进行预测Ypred = predict(mdl,Xtest);cf = confismat (Ytest,Ypred);%显示结果图vals = {“负面”“积极”};热图(val, vals, cf);包含(“预测标签”) ylabel (“真正的标签”)标题({“线性判别式的混淆矩阵”...sprintf ('分类精度%.1f%%'...sum (cf(逻辑(眼(2))))/笔(sum (cf)) * 100)})

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

scoreWords班级的计分方法。积极的分数代表积极的情绪,消极的分数代表消极。现在我们可以用40万字来给情绪打分。

dbtypesentiment.m18:26
18功能评分= scoreWords(obj,words) 19% scoreWords评分单词情绪20 vec = word2vec(obj.emb,words);if size(vec,2) ~= obj.emb.Dimension % check num cols 22 vec = vec';%转置所需23 end 24 [~,scores,~] = predict(obj.mdl,vec);%获得类概率25 scores = scores(:,2) - scores(:,1);%正面得分-负面得分26结束

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

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

  • 这个词
  • 情绪标签(0 =消极,1 =积极)
  • 情绪评分(负=负,正=正)
  • 评估(真=正确,假=不正确)
Sent =情绪(emb,mdl);lte。score = send . scorewords (Ltest.word);lte。eval = Ltest。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真“懒汉”0 -0.88944真“天使”1 0.43419真“骗子”0 -0.98412真

现在我们需要一种方法来对人类语言文本的情感进行评分,而不是单个单词。的scoreText情感类的方法对文本中每个词的情感得分进行平均。这可能不是最好的方法,但这是一个简单的开始。

dbtypesentiment.m28:33
28函数得分= scoreText(obj,text) 29 % scoreText得分对文本的情绪30 token = split(lower(text));%分割文本为符号31 scores = obj.scoreWords(符号);% get分数为每个标记32分=平均数(分数,'omitnan');%平均分33分结束

下面是调查人员给出的句子情感评分scoreText方法——非常积极,有点积极,和消极。

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

波士顿Airbnb开放数据

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

注释后的代码将生成本文顶部所示的单词云。但是,您也可以使用被称为bigrams的两个单词短语来生成单词云。你可以用docfun,它操作令牌数组。您还可以看到可以生成三元表和其他字格通过修改函数句柄。

看起来很多评论都是关于地点的!

opts = detectImportOptions(“listings.csv”);L =可读的(“listings.csv”、选择);评论=可读(“reviews.csv”);comments = tokenizedDocument(reviews.comments);Comments = lower(Comments);comments = removeWords(comments,stopWords);comments = removeShortWords(comments,2);comments = eraspunctuation(注释);% == uncomment生成一个字云==% bag = bagOfWords(评论);%图% wordcloud(袋);% title(“AirBnB评论Word Cloud”)生成一个Bigram Word CloudF = @(s)s(1:end-1) +”“+ s(2:结束);Bigrams = docfun(f,comments);bag2 = bagOfWords(bigrams);图wordcloud (bag2);标题(“AirBnB审查Bigram云”

爱彼迎评论评分

评论评分也有,但评分倾向于100,这意味着绝大多数的列表都非常棒(真的吗?)作为这张XCKD漫画节目,我们有在线评分的问题关于评论评级。这不是很有用。

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

计算情绪分数

现在让我们来评估一下Airbnb房源评论的情绪。因为一个房源可能会有很多评论,所以我会使用每个房源的情绪评分中位数。波士顿的情绪得分中值一般处于积极范围,但它遵循正态分布。这个看起来更真实。

%评价评分f = @(str) sent.scoreText(str);评论。情绪= cellfun(f,reviews.comments);通过列出列表计算中位数评分。[G,listings] = findgroups(评论(:,“listing_id”));上市。情绪= splitapply(@中位数,...reviews.sentiment G);%可视化结果图直方图(listings. emotion)“波士顿AirBnB房源的情绪”)包含(“情绪评分中值”) ylabel (“房源数量”

按位置划分的情绪

bigram云显示,评论者经常评论位置和距离。您可以使用列表的纬度和经度来查看情绪分数很高或很低的列表所在的位置。如果你看到一堆高分,也许它们表明了适合居住的好地方。

%加入情绪分数和列表信息已加入= innerjoin(...上市,l (:, {“id”“纬度”“经”...“neighbourhood_cleansed”}),...“LeftKeys”“listing_id”“RightKeys”“id”);joined.Properties。VariableNames{结束}=“已”丢弃具有NaN情绪评分的列表Joined (isnan(Joined .sentiment),:) = [];将情绪分数离散到桶中加入。* * * * * * * * * * * * * * * * *...“分类”,{“< 0.25”“< 0.50”“< 0.75”“< = 1.00”});删除未定义的类别Cats =类别(joined.cat);Joined (isundefined(Joined .cat),:) = [];%颜色变量Colorlist =冬季(长度(猫));%生成图Latlim = [42.300 42.386];Lonlim = [-71.1270 -71.0174];负载boston_map.mat图imagesc(lonlim,latlim, map)保持gscatter (joined.longitude joined.latitude、joined.cat colorlist,“o”)举行Dar = [1, cosd(mean(latlim)), 1];daspect (dar)组(gca,“ydir”“正常”);轴([lonlim latlim])标题(“波士顿爱彼迎房源的情绪评分”) [g,ngh] = findgroups(已加入(:,“已”));ngh.Properties。VariableNames{结束}=“名字”;已。Lat = splitapply(@mean,joined.latitude,g);已。Lon = 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帐户或创建一个新帐户。