Contents
Conteúdo
Começa com a explicação foldLeft
, fold
e aggregate
. Muito boas explicações. Seria ótimo tê-los para a 1ª tarefa. Mesmo uma estrutura semelhante à primeira atribuição é mencionada juntamente com pares de valores-chave distribuídos (par RDDs), que suportam reduceByKey
.
As sessões posteriores apresentam diferentes junções disponíveis nos RDDs dos pares, mostrando novamente exemplos, para que os conceitos sejam fáceis de entender. As explicações são muito claras e detalhadas.
Tarefa
Desta vez, o objetivo é examinar as perguntas e respostas dos StackOverflow e aplicar o k-means para agrupar o conteúdo por idiomas. Essa foi uma tarefa muito interessante e divertida.
Ao implementá-lo, permita-me avaliar como o R é incrível para o trabalho de ciência de dados exploratório e interativo. Comparado com o R, a depuração do código Scala foi desafiadora, e escrever código de organização de dados para colocar os dados no formato correto levou horas.
Para uma comparação, aqui está o código Scala que escrevi para obter os dados nos formatos solicitados:
val langs = List(
"JavaScript", "Java", "PHP", "Python", "C#", "C++", "Ruby", "CSS",
"Objective-C", "Perl", "Scala", "Haskell", "MATLAB", "Clojure", "Groovy"
)
def langSpread = 50000
val lines = sc.textFile("src/main/resources/stackoverflow/stackoverflow.csv")
val raw = rawPostings(lines)
/** Parse lines into proper structure */
def rawPostings(lines: RDD[String]): RDD[Posting] =
lines.map(line => {
val arr = line.split(",")
Posting(
postingType = arr(0).toInt,
id = arr(1).toInt,
acceptedAnswer = if (arr(2) == "") None else Some(arr(2).toInt),
parentId = if (arr(3) == "") None else Some(arr(3).toInt),
score = arr(4).toInt,
tags = if (arr.length >= 6) Some(arr(5).intern()) else None
)
})
/** Group the questions and answers together */
def groupedPostings(
postings: RDD[Posting]
): RDD[(QID, Iterable[(Question, Answer)])] = {
val questions = postings.
filter(thisPosting => thisPosting.postingType == 1).
map(thisQuestion => (thisQuestion.id, thisQuestion))
val answers = postings.
filter(thisPosting => thisPosting.postingType == 2).
map(thisAnswer => (thisAnswer.parentId.get, thisAnswer))
questions.join(answers).groupByKey()
}
/** Compute the maximum score for each posting */
def scoredPostings(
grouped: RDD[(QID, Iterable[(Question, Answer)])]
): RDD[(Question, HighScore)] = {
def answerHighScore(as: Array[Answer]): HighScore = {
var highScore = 0
var i = 0
while (i highScore) highScore = score
i += 1
}
highScore
}
grouped.map{
case (_, qaList) => (
qaList.head._1,
answerHighScore(qaList.map(x => x._2).toArray)
)
}
}
E aqui está o código data.table que pode alcançar resultados muito semelhantes:
library(data.table)
# Read Data -----
so
Também foram necessários alguns ajustes para deixar a motoniveladora feliz e, como a produção da motoniveladora não é tão detalhada e não foram fornecidos testes de unidade local, levei alguns envios para que isso acontecesse. No geral, foi uma tarefa divertida e destacou o quanto o R é mais simples para esse tipo de uso.