You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: compendium/modules/w07-setmap-lab.tex
+50-17Lines changed: 50 additions & 17 deletions
Original file line number
Diff line number
Diff line change
@@ -34,6 +34,29 @@ \subsection{Bakgrund}
34
34
35
35
\subsection{Obligatoriska uppgifter}
36
36
37
+
Du ska bygga ditt program med en editor, t.ex. \texttt{atom}, och kompilera din kod i terminalen med \code{scalac} eller med hjälp av byggverktyget \code{sbt}. Medan du steg för steg utvecklar ditt program, ska du parallellt göra experiment i REPL för att undersöka hur du kan använda samlingsmetoder för att lösa uppgifterna.
38
+
39
+
Kod att utgå ifrån finns på github här: \url{https://github.com/lunduniversity/introprog/tree/master/workspace/w07_words}
40
+
41
+
Dessa ofärdiga kodfiler ligger i paketet \code{nlp}:
42
+
\begin{itemize}
43
+
\item\href{https://github.com/lunduniversity/introprog/blob/master/workspace/w07_words/src/main/scala/nlp/FreqMapBuilder.scala}{\texttt{FreqMapBuilder.scala}} innehåller ett skelett till en klass för att, ord för ord, bygga en nyckel-värde-tabell som registrerar antalet förekomster av olika ord. Att implementera denna ingick i övningen du gjorde tidigare i veckan.
44
+
45
+
\item\href{https://github.com/lunduniversity/introprog/blob/master/workspace/w07_words/src/main/scala/nlp/Text.scala}{\texttt{Text.scala}} innehåller ett skelett till en klass som kan göra textbehandling genom att analysera ord i en text.
46
+
47
+
\item\href{}{\texttt{}} \href{https://github.com/lunduniversity/introprog/blob/master/workspace/w07_words/src/main/scala/nlp/Main.scala}{\texttt{Main.scala}} innehåller ett ofärdigt huvudprogramsexempel som du kan använda i laborationens senare del.
48
+
\end{itemize}
49
+
50
+
För att underlätta ditt arbetsflöde under det att du stegvis bygger upp din kod metod för metod, kan du med fördel använda byggverktyget \texttt{sbt} (se appendix \ref{appendix:build}) så här:
51
+
52
+
\begin{itemize}
53
+
\item
54
+
Med \code{sbt}-kommandot \code{console} startar du REPL innifrån \code{sbt} med dina klasser automatiskt tillgängliga på classpath och du kan anropa de metoder som du gjort färdigt hittills medan du gör experiment inför nästa steg. När du ändrat något i din editor och vill experimentera med nya versionen så trycker du Ctrl+D och startar om REPL med \code{console} (pil-upp) och din kod kompileras om automatiskt.
55
+
\item
56
+
Med \code{sbt}-kommandot \code{~run} (notera tilde-tecknet) sker kompilering och körning av \code{main}-metoden automatiskt i terminalen varje gång du gör Ctrl+S i din editor.
57
+
58
+
\end{itemize}
59
+
37
60
38
61
\Task\emph{Skapa frekvenstabeller}. Du ska använda \code{FreqMapBuilder} från veckans övning för att skapa frekvenstabeller av typen \code{Map[String, Int]}, där nyckel-värde-paren i tabellen anger antalet förekomster av en viss sträng.
\noindent I kommande uppgifter ska du steg för steg skapa och testa case-klassen \code{Text} nedan. %figur \ref{data:fig-text}.
90
+
\noindent I kommande uppgifter ska du steg för steg skapa och testa case-klassen \code{Text}. %figur \ref{data:fig-text}.
68
91
69
92
70
-
\Task\emph{Dela upp en sträng i ord}. Medlemmen \code{words} ska innehålla en vektor med alla ord i \code{source}, utan andra tecken än bokstäver.
71
-
Dela upp strängen \code{source} genom att i tur och ordnig göra följande:
93
+
\Task\emph{Dela upp en sträng i ord}. Du ska implementera medlemmen \code{words}. Den ska innehålla en vektor med alla ord i \code{source}, utan andra tecken än bokstäver.
94
+
Detta åstadkommer du genom att utgå ifrån strängen \code{source} och i tur och ordning göra följande:
72
95
\begin{enumerate}%[nolistsep, noitemsep]
73
96
\item byta ut alla tecken i \code{source} för vilka \code{isWhitespace} är sant mot \code{' '}
74
97
\item byta sedan ut alla tecken för vilka \code{isLetter} är falskt mot \code{' '}
\TaskImplementera \code{wordFreq} med hjälp av \code{FreqMapBuilder}. Testa \code{wordFreq} genom att ladda ner boken ''Skattkammarön'' skriven av Robert Louis Stevenson\footnote{Copyright för denna bok har gått ut, så du gör dig inte skyldig till piratkopiering (i juridisk mening).} och undersök frekvensen för olika vanliga ord. Vilket ord är vanligast? Näst vanligast?
133
+
\TaskDu ska nu skapa ordfrekvenstabellen \code{wordFreq} genom att registrera ordförekomster med hjälp av \code{FreqMapBuilder}. Tabellen \code{wordFreq} ska bestå av nyckelvärdepar \code{w -> f} där \code{f} är antalet gånger ordet \code{w} förekommer i \code{words}. Testa \code{wordFreq} genom att ladda ner boken ''Skattkammarön'' skriven av Robert Louis Stevenson\footnote{Copyright för denna bok har gått ut, så du gör dig inte skyldig till piratkopiering (i juridisk mening).} och undersök frekvensen för olika vanliga ord. Vilket ord är vanligast? Näst vanligast?
\Task Implementera metoden \code{ngrams}. \emph{Tips:} Undersök i REPL hur metoden \code{sliding} fungerar. Gör \code{toVector} på resultatet från \code{sliding}. Testa så att \code{ngrams} och \code{bigrams} fungerar.
158
+
\Task Implementera metoden \code{ngrams} som ger en sekvens med alla ordföljder i $n$ steg. \emph{Tips:} På veckans övning ingick att undersöka hur metoden \code{sliding} fungerar, med vilken du kan skapa $n$-gram. Gör \code{toVector} på resultatet från \code{sliding}. Testa noga så att \code{ngrams} och \code{bigrams} fungerar korrekt innan du går vidare.
\Task Implementera \code{followFreq}, som ska innehålla en nyckel-värde-tabell där värdet i sin tur är en frekvenstabell över de ord som kommer efter nyckeln. Utgå från nedan pseudokod:
169
+
\Task Implementera \code{followFreq}, som ska innehålla en nyckel-värde-tabell där värdet i sin tur är en frekvenstabell över de ord som kommer efter nyckeln.
170
+
171
+
Genom att analysera alla ordpar kan vi få fram vilket som är det vanligaste ordet som följer efter ett givet ord. Metoden \code{bigrams} ger oss alla ordpar \code{(w1, w2)} där \code{w2} följer efter \code{w1}. Vi kan spara statistiken över efterföljande ord i en nyckelvärdetabell med mappningarna \code{w -> f} där nyckeln \code{w} är ett ord och värdet \code{f} är en frekvenstabell av typen \code{Map[String, Int]}. I frekvenstabellen lagrar vi frekvensen för alla de ord som följer efter \code{w}. Du ska alltså bygga en nästlad tabell av typen \code{Map[String, Map[String, Int]]}. Rita en bild av den nästlade strukturen.\Pen
172
+
173
+
Implementera metoden followFreq genom att utgå från nedan pseudokod:
147
174
\begin{Code}
148
175
val result = scala.collection.mutable.Map.empty[String, FreqMapBuilder]
result.mapValues(_.toMap).toMap // returnerar oföränderligt objekt
156
183
\end{Code}
184
+
Skriv uttryck för att ta reda på följande:\Pen
185
+
157
186
\Subtask Vilka ord brukar följa efter \emph{han} respektive \emph{hon} i Stevensons ''Skattkammarön''?
158
187
159
188
\Subtask Vilka ord brukar följa efter \emph{han} respektive \emph{hon} i Stringbergs ''Inferno''?
@@ -198,7 +227,7 @@ \subsection{Kontrollfrågor}
198
227
199
228
\item Är mängden av alla nycklar i en nyckel-värde-tabell garanterat unika?
200
229
201
-
\item Är mängden av alla värden i en nyckel-värde-tabell garanterat unika?
230
+
\item Är alla värden i en nyckel-värde-tabell garanterat unika?
202
231
203
232
\item LTH-teknologen Oddput Clementin vill summera längden på varje sträng i en mängd och skriver:
204
233
\begin{REPL}
@@ -210,35 +239,39 @@ \subsection{Kontrollfrågor}
210
239
211
240
\subsection{Frivilliga uppgifter}
212
241
213
-
\TaskImplementera nedan metod som ska ge ett slumpmässigt ord ur \code{wordSet}. Varje ord ska förekomma med lika stor sannolikhet.
242
+
\TaskBygg vidare på klasse \code{Text} och implementera nedan metod som ska ge ett slumpmässigt ord ur \code{wordSet}. Varje ord ska förekomma med lika stor sannolikhet.
214
243
\begin{Code}
215
244
def randomWord: String = ???
216
245
\end{Code}
217
246
218
-
\Task\label{task:words:randomSeq} Implementera nedan metod som ska ge en slumpmässig sekvens av $n$ ord där varje efterföljande ord väljs ur nyckelmängden för \code{followFreq} med lika stor sannolikhet.
247
+
\Task\label{task:words:randomSeq} Med NLP kan man generera slumpmässiga meningar som statistiskt sett liknar ''riktiga'', människoskapade meningar.
248
+
249
+
Implementera metoden \code{randomSeq(firstWord, n)} nedan i klassen \code{Text}. Den ska ge en sekvens $w_{1}, w_{2}, ..., w_{n}$ där $w_{1}$ är \code{firstWord} och $w_{i+1}$ är något slumpmässigt ord som är draget bland de ord som följer efter $w_{i}$. Detta kan du åstadkomma genom att varje efterföljande ord $w_{i+1}$ väljs ur \code{keys.toVector} för den \code{followFreq}-tabell som hör till $w_{i}$. Orden ska dras med rektangelfördelad sannolikhet ur efterföljandemängden.
\emph{Tips:} Metoden \code{scala.util.Random.shuffle} tar en sekvens som argument och genererar en ny sekvens av samma typ, men med elementen ordnade i slumpmässig ordning, där varje möjlig ordning är lika sannolik.
253
+
%\emph{Tips:} Ett sätt att garanterat välja slumpmässigt element med rektangelfördelning ur en sekvens är att använda metoden \code{scala.util.Random.shuffle} som tar en sekvens som argument och genererar en ny sekvens av samma typ, men med elementen ordnade i slumpmässig ordning på ett välblandat sätt, där varje möjlig ordning är lika sannolik.
254
+
255
+
\Task\label{task:words:mostCommonSeq} För att dina datorgenererade meningar verkligen ska likna mänskilgt språk kan vi skapa de mest sannolika meningarna av olika längder ur vår analys av ordfrekvenser.
223
256
224
-
\Task\label{task:words:mostCommonSeq} Lägg till metoden \code{mostCommonSeq} i klassen \code{Text} enligt nedan:
257
+
Lägg till metoden \code{mostCommonSeq} i klassen \code{Text} enligt nedan:
\Subtask Implementera metoden så att resultatet blir en sekvens med \code{n} ord. Sekvensen ska börja med \code{firstWord} och därefter följas av det ord som är det vanligaste efterföljande ordet efter \code{firstWord}, och därpå det vanligaste efterföljande ordet efter det, etc. \emph{Tips:} Använd en lokal variabel \code{val result} som är en ArrayBuffer till vilken du i en \code{while}-loop lägger de efterföljande orden.
261
+
\Subtask Implementera metoden så att resultatet blir en sekvens med \code{n} ord. Sekvensen ska börja med \code{firstWord} och därefter följas av det ord som är det \emph{vanligaste} efterföljande ordet efter \code{firstWord}, och därpå det vanligaste efterföljande ordet efter det, etc. \emph{Tips:} Använd en lokal variabel \code{val result} som är en ArrayBuffer till vilken du i en \code{while}-loop lägger de efterföljande orden.
229
262
230
263
\Subtask Jämför de slumpmässiga sekvenserna med sekvenser genererade med \code{randomSeq} i uppgift \ref{task:words:randomSeq}. Vilka sekvenser liknar mest ''riktiga'' meningar?
231
264
232
265
233
-
\Task Använd befintliga samlingsmetoder i stället för \code{FreqMapBuilder}.
266
+
\Task Använd befintliga samlingsmetoder i stället för \code{FreqMapBuilder} för att registrera efterföljande ord.
234
267
235
268
\Subtask Undersök i REPL hur metoden \code{groupBy(x => x)} fungerar då den appliceras på en samling med strängar. Sök efter och studera dokumentationen för \code{groupBy}.
236
269
237
270
\Subtask Undersök i REPL hur metoden \code{mapValues} fungerar då den appliceras på en nyckel-värde-tabell där värdet är en samling. Sök efter och studera dokumentationen för \code{mapValues}.
238
271
239
272
\Subtask Inför värdet \code{lazy val wordFreq2}. Den ska ge samma resultat som \code{wordFreq} men men implementeras med hjälp av \code{groupBy} och \code{mapValues} i stället för \code{FreqMapBuilder}.
240
273
241
-
\Subtask Jämför prestanda mellan \code{wordFreq2} och \code{wordFreq}. Vilken är snabbast för stora texter? Är skillnaden stor?
274
+
\Subtask\Uberkurs Jämför prestanda mellan \code{wordFreq2} och \code{wordFreq}. Vilken är snabbast för stora texter? Är skillnaden stor?
242
275
243
276
\Subtask Inför värdet \code{lazy val followsFreq2}. Den ska ge samma resultat som \code{followsFreq} men implementeras med hjälp av \code{groupBy} och \code{mapValues} i stället för \code{FreqMapBuilder}.
244
277
Denna uppgift är ganska knepig. Experimentera dig fram i REPL, och bygg upp en lösning steg för steg. \emph{Tips:}
\Subtask Jämför prestanda mellan \code{followsFreq2} och \code{followsFreq}. Vilken är snabbast för stora texter? Är skillnaden stor?
284
+
\Subtask\Uberkurs Jämför prestanda mellan \code{followsFreq2} och \code{followsFreq}. Vilken är snabbast för stora texter? Är skillnaden stor?
252
285
253
286
254
-
\Task\emph{Gör \code{FreqMapBuilder} generisk.} Senare i kursen ska vi se hur man kan skapa s.k. generiska datastrukturer med hjälp av typparametrar. Denna uppgift går händelserna i förväg och tjuvkikar på hur en generisk klass kan se ut.
287
+
\Task\Uberkurs\emph{Gör \code{FreqMapBuilder} generisk.} Senare i kursen ska vi se hur man kan skapa s.k. generiska datastrukturer med hjälp av typparametrar. Denna uppgift går händelserna i förväg och tjuvkikar på hur en generisk klass kan se ut.
255
288
256
289
\Subtask Studera \code{FreqMapBuilder} och identifiera allt i den klassen som är specifikt för typen \code{String}.
0 commit comments