Loren谈MATLAB的艺术

将想法转化为MATLAB

请注意

Loren谈MATLAB的艺术已退役,将不再更新。

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

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

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

内容

什么是词嵌入?

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

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

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

$$king -男人+女人\约皇后$$

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

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

成分

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

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

从GloVe加载预训练的单词嵌入

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

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

向量的数学例子

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

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

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

让我们用MATLAB来试试。word2vec返回单词嵌入和中的给定单词的向量vec2word查找单词嵌入中与向量最接近的单词。

v_paris = word2vec (emb,“巴黎”);v_france = word2vec (emb,“法国”);v_poland = 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 =底片(ismember (neg emb.Vocabulary));获取相应的词向量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 _____________ _____________ _________ _________ ________ __________ _________ __________ "abundance" 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.0766277 -0.10652 -0.43257 0.74405 0.41298 "abundance" 1 -0.29317 -0.068101 -0.44659 -0.31563 -0.13791 0.44888 0.31894 "accessible" 1 -0.45096 -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);火车=数据(训练(c), 2:结束);Xtest =数据(测试(c), 2: end-1);欧美= data.resp(测试(c));lte =数据(测试(c), 1);lte。标签=欧美;

情感分类器的训练与评价

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

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

%的火车模型mdl = fitcdiscr(火车,“职责”);%对测试数据进行预测Xtest Ypred =预测(mdl);cf = confusionmat(欧美,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);% get类概率25 scores = scores(:,2) - scores(:,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真“碎片”0 -0.88944真“天使”1 0.0.43419真“欺骗”0 -0.98412真

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

dbtypesentiment.m28:33
28函数得分= scoreText(obj,text) 29 % scoreText得分情绪的文本30个token = split(lower(text));31 scores = obj.scoreWords(token);得分=均值(scores,'omitnan');%平均分数33结束

以下是评分机构给出的句子情感评分scoreText方法——非常积极,有点积极,和消极。

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

波士顿Airbnb开放数据

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

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

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

选择= detectImportOptions (“listings.csv”);l = readtable (“listings.csv”、选择);评论= readtable (“reviews.csv”);评论= tokenizedDocument (reviews.comments);评论=低(评论);评论= removeWords(评论,stopWords);评论= removeShortWords(注释2);评论= erasePunctuation(评论);% ==取消注释以生成字云==% bag = bagOfWords(comments);%图% wordcloud(袋);% title(“AirBnB评论字云”)生成一个Bigram字云F = @(s)s(1:end-1) +”“+ s(2:结束);三元= docfun (f,评论);bag2 = bagOfWords(三元);图wordcloud (bag2);标题(“AirBnB评论Bigram云”

Airbnb评估评级

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

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

计算情绪得分

现在让我们来为Airbnb的上市评论打分。因为一个清单可能有很多评论,我将使用每个清单的情绪评分中位数。波士顿的情绪得分中值总体处于正态分布范围内。这看起来更真实。

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

情绪的位置

bigram云显示,评论者经常评论地点和距离。您可以使用清单的纬度和经度来查看情绪评分非常高或非常低的清单位于哪里。如果你看到成群的高分,也许它们表明了适合居住的好地方。

%加入情绪评分和列表信息加入= innerjoin (...上市,l (:, {“id”“纬度”“经”...“neighbourhood_cleansed”}),...“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 (joined.longitude joined.latitude、joined.cat colorlist,“o”)举行Dar = [1, cosd(mean(latlim)), 1];daspect (dar)组(gca,“ydir”“正常”);轴([lonlim latlim])标题(“波士顿爱彼迎的情感评分”) [g,ngh] = findgroups(joined(:,“已”));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

|
Baidu
map