idx = randperm(size(dataKaggle,1),10);disp (dataKaggle (idx[“名称”“风格”)))
的名字 |
风格 |
_______________________________________ |
_______________________________________ |
“隆(2014)” |
“Saison /农舍麦芽酒” |
“耀西的花蜜” |
“加州普通/蒸汽啤酒” |
“1327 Pod的ESB” |
“特别/强苦(ESB)” |
“Parade Ground Coffee Porter” |
“美国波特” |
“永恒的黑暗” |
“比利时浓啤酒” |
La Frontera高级IPA |
“美国音标” |
“峡谷奶油啤酒” |
“奶油啤酒” |
“引领比利时风格的智慧” |
“Witbier” |
“Squatters Hop Rising双IPA” |
“美国双IPA /皇家IPA” |
“Good Vibes IPA” |
“美国音标” |
加载剑桥啤酒节的数据,除了名称和风格,还包含品酒笔记。从文本分析工具箱中使用HTML解析工具提取数据。
Url = "https://www.cambridgebeerfestival.com/下载188bet金宝搏products/cbf44-beer";代码= webread(url);tree = htmlTree(code);
提取啤酒名称。
subtrees = findElement(树,"span[class=""productname""]");name = extractHTMLText(subtrees);
提取品尝笔记。
subtrees = findElement(tree,"span[class=""tasting""]");notes = extractHTMLText(subtrees);dataCambridge = table(name,notes);
把品尝笔记想象成文字云。的
wordcloud
“文本分析工具箱”中的函数直接从字符串数据创建词云。
图wordcloud(笔记);标题(“口味”)
分类啤酒类型
首先,使用Kaggle数据,创建一个长短期记忆(LSTM)深度学习模型,对给定名称的啤酒风格进行分类。使用词汇云可视化啤酒样式的分布。
textData = dataKaggle.name;labels = categorical(dataKaggle.style);图wordcloud(标签);标题(“啤酒风格”)
正如您在字云中看到的,样式非常不平衡,有些样式只包含几个实例。为了改进模型,去掉实例数小于5的样式,然后将数据分成90%的训练分区和10%的测试分区。
(数据准备的细节可以在完整的示例文件中找到)
将每个啤酒名转换为一个整数序列,其中每个整数代表一个字符。
答案是啤酒的风格。
YTrain = labelsTrain;YTest = labelsTest;YTrain (1:6)
Ans = 6x1字符串数组 |
美国淡啤酒 |
美国音标 |
美国Double / Imperial IPA |
美国音标 |
燕麦片的 |
接下来创建深度学习网络架构。使用单词嵌入层学习字符嵌入并将整数映射到向量。使用双向LSTM (BiLSTM)层来学习啤酒名称中字符之间的双向长期依赖关系。
为了学习BiLSTM层的隐藏单元之间更强的相互作用,包括一个额外的大小为50的全连接层。使用dropout层来帮助防止网络过拟合。
numFeatures = 1;embeddingDimension = 100;numCharacters = max([XTrain{:}]);numClasses = nummel(类别(YTrain));layers = [sequenceInputLayer(numFeatures) wordEmbeddingLayer(embeddingDimension,numCharacters) bilstmLayer(200,'OutputMode','last') dropoutLayer(0.5) fullyConnectedLayer(50) dropoutLayer(0.5) fullyConnectedLayer(numClasses) softmaxLayer classificationLayer];
指定培训选项。
选项= trainingOptions('adam',…“MaxEpochs”,100年,…“InitialLearnRate”,0.01,…“GradientThreshold”,2,…“洗牌”、“every-epoch’,……ValidationData, {XTest,欧美},…“ValidationFrequency”,80年,…“阴谋”、“训练进步”,…“详细”,假);
培训网络。
beerStyleNet = trainNetwork(XTrain,YTrain,layers,options);
在这里,我们可以看到模型过拟合。该模型能有效地记忆训练数据,但对测试数据的泛化效果不佳。
这也许是意料之中的:很多啤酒的名字在风格方面并没有透露太多,所以网络没有什么可做的。有些很容易分类,因为名字中包含了啤酒的风格。
例如,你认为下面这些是什么类型的啤酒?你能打败分类器吗?
Idx = [1 4 5 8 9 10 12 14 15 17];textDataTest (idx)
Ans = 10x1字符串数组 |
“一知半解的季节” |
“分裂的天空” |
“亲爱的Kolsch” |
“阿拉斯加琥珀” |
“加州啤酒” |
”兄弟姐妹“蒸汽 |
《愤怒的果园苹果姜》 |
“长叶” |
《本季金发女郎》 |
“拉” |
比较你的猜测和网络的预测以及正确的标签
YPred =分类(beerStyleNet,XTest);disp(table(textDataTest(idx),YPred(idx),YTest(idx),'VariableNames',["Name" "预测" "True"]))
的名字 |
预测 |
真正的 |
______________________________ |
______________________________ |
______________________________ |
“一知半解的季节” |
Saison /农家乐啤酒 |
Saison /农家乐啤酒 |
“分裂的天空” |
美国琥珀/红啤酒 |
美国音标 |
“亲爱的Kolsch” |
Kolsch |
Kolsch |
“阿拉斯加琥珀” |
美国琥珀/红啤酒 |
酿造 |
“加州啤酒” |
美国琥珀/红窖藏啤酒 |
美国琥珀/红窖藏啤酒 |
”兄弟姐妹“蒸汽 |
美国淡麦酒 |
加州普通/蒸汽啤酒 |
《愤怒的果园苹果姜》 |
苹果酒 |
苹果酒 |
“长叶” |
慕尼黑Helles拉格啤酒 |
美国音标 |
《本季金发女郎》 |
奶油啤酒 |
美国金发啤酒 |
“拉” |
果蔬啤酒 |
美国Double / Imperial IPA |
那么,我可以用这个网络为我选择啤酒吗?假设测试集包含酒吧中所有可用的啤酒。我喜欢喝印度淡啤酒。让我们来看看这些啤酒中哪些是国际淡啤酒。这可以是包含“IPA”的任何类标签。
classNames = string(beerStyleNet.Layers(end).Classes);idx = contains(classNames,"IPA");classNamesIPA = classNames(idx)
Ans = 5x1字符串数组 |
“美国音标” |
“美国音标” |
“美国白IPA” |
“比利时音标” |
英国印度淡啤酒 |
[YPred,scores] = category (beerStyleNet,XTest);Idx = contains(字符串(YPred),“音标”);select = textDataTest(idx)
让我们来看看这些酒中有多少是IPA。
(包含(string(YTest(idx)),"IPA")))
accuracyIPA = 0.7241
查看按评分排序的前10个预测。更令人兴奋的是,让我们排除所有名字中含有“IPA”的名字
topScores = max(scores(idx,:),[],2);[~,idxSorted] = sort(topScores,' descent ');selectionSorted = select (idxSorted);%除去名称中含有IPAidx = contains(selectionSorted,["IPA" "印度淡啤酒"]);selectionSorted(idx) = [];selectionSorted (1:10)
Ans = 10x1字符串数组 |
《美国白痴啤酒》(2012) |
“Citra面临“ |
《公海上的跳跃》(卡利普索) |
“孟加拉虎” |
剑铁天鹅啤酒 |
“26” |
“伊西斯” |
“En Parfaite harmony” |
“分别为圣” |
“红鲑Maibock” |
看起来是一些很好的建议!
生成新的啤酒名称
我们建立了一个深厚的网络,为我找啤酒做了合理的工作。我的下一个愿望是用MATLAB为我设计一种啤酒。首先它需要一个名字。为此,我将使用LSTM网络进行序列预测,它预测序列的下一个字符。为了改进模型,我还将包括来自英国剑桥啤酒节的啤酒名称。验证数据在这里没有帮助,所以我们将在所有数据上进行训练。
textData = [dataKaggle.name;dataCambridge.name];
为了帮助生成,将所有空格字符替换为“·”(中间的点)字符,在开头插入文本字符的开始,在结尾插入文本字符的结束。
startOfTextCharacter = compose("\x0002");whitespaceCharacter = compose("\x00B7");endOfTextCharacter = compose("\x2403");
对于预测器,在啤酒名称之前插入文本字符的开头。对于响应,将文本字符的结尾附加在啤酒名称之后。在这里,响应与预测因子相同,平移了一个时间步长。
textdatappredictors = startOfTextCharacter + replace(textData," ",whitespaceCharacter);textDataResponses = replace(textData," ",whitespaceCharacter) + endOfTextCharacter;
XTrain = cellfun(@double, textdatappredictors,'UniformOutput',false);YTrain = cellfun(@(Y) categorical(cellstr(Y')'),textDataResponses,'UniformOutput',false);
查看预测器和响应的第一个序列。
XTrain {1}
Ans = 1x9 |
2 80 117 98 183 66 101 101 114 |
YTrain {1}
构建网络架构。
numFeatures = 1;numClasses = number (categories([YTrain{:}]));numCharacters = max([XTrain{:}]);layers = [sequenceInputLayer(numFeatures) wordEmbeddingLayer(200,numCharacters) lstmLayer(400) dropoutLayer(0.5) fullyConnectedLayer(numClasses) softmaxLayer classificationLayer];
指定培训选项。
选项= trainingOptions('adam',…“InitialLearnRate”,0.01,…“GradientThreshold”,2,…“洗牌”、“every-epoch’,……“阴谋”、“训练进步”,…“详细”,假);
培训网络。
beerNameNet = trainNetwork(XTrain,YTrain,layers,options);
在这里,网络可能看起来不是特别好。同样,这也是意料之中的。为了获得较高的准确率,网络必须准确地生成训练数据。我们不希望网络过度拟合因为网络只会生成训练数据。
类生成一些啤酒名称
generateText
函数,该函数包含在文章末尾的完整示例文件中。
numBeers = 30;generatedBeers = strings(numBeers,1);for i = 1:numBeers generatedBeers(i) = generateText(beerNameNet,startOfTextCharacter,whitespaceCharacter,endOfTextCharacter);结束
有时,网络可能只是从训练数据中预测啤酒名称。移除它们。
idx = ismember(generatedBeers,textData);generatedBeers(idx) = [];
查看生成的啤酒。
generatedBeers
generatedBeers = |
“Firis琥珀” |
“Sprecian Claisper” |
“沃瑟淡啤酒” |
“Ma’s Canido冬季啤酒” |
“跳激动” |
"蜂蜜牛奶啤酒" |
“Slowneck啤酒” |
"CuDas Colora Lager" |
“没有赖尔比尔森啤酒” |
“Dark Light IPA” |
生成品尝笔记
我们有了啤酒名,现在需要一些品酒笔记。与名称生成器类似,根据剑桥啤酒节笔记创建一个品尝笔记生成器。
textData = dataCambridge.notes;
与前面一样,为了帮助生成名称,将所有空格字符替换为“·”(中间的点)字符,在开头插入文本字符的开始,在结尾插入文本字符的结束。
同样,定义网络架构,指定训练选项,并训练网络。
(详细信息可在本文最后的主示例文件链接中找到)
使用示例末尾列出的generateText函数生成一些品尝笔记。
numBeers = 5;for i = 1:numBeers generatedNotes = generateText(beerNotesNet,startOfTextCharacter,whitespaceCharacter,endOfTextCharacter)结束
“这款淡色啤酒有一种很好的坚定的淡色和浓郁的酒体,回味悠长。” |
“这是一款酒体醇厚的皇家黑啤,带有轻微而饱满的烘焙麦芽味,回味中还能感受到丝质黑啤的精致。Unfined。” |
“淡铜味的传统苦啤酒,有很好的麦芽风味。酿造出最好的英国水獭马里斯酒的味道,有龙舌兰果味和苦甜的回味。” |
"用多种香料酿造的黑啤。Unfined。” |
“混合麦芽和水果开始煮沸。” |
完美!我现在可以开始酿造我自己的完美啤酒了。您可以多次运行代码以生成更多的名称和品尝注释。迄今为止,我最喜欢的设计是:
Hopky Wolf印度啤酒
“这款双IPA有浓郁的麦芽味,柚子、橙子和柠檬的味道,并有潜在的花香和帐篷的味道。均衡的香气反映了它的口感。它是用Fuggle和Golding啤酒花混合制成的。”
现在我只需要MATLAB来自动化酿造过程…
版权所有2018 The MathWorks, Inc.
获取MATLAB代码
评论
如欲留言,请点击在这里登录您的MathWorks帐户或创建一个新帐户。