def get_training_set(context, path, sample=False): tweets = context.textFile(path).map(lambda x: x.split('\t')) tweets = tweets.sample(False, 0.1, 5) if sample else tweets return tweets.map(lambda x: (x[header.index('place_name')], x[header.index( 'tweet_text')].lower().split(' ')))
from utils import setup from constants import header conf, sc, tweets, result_path = setup(2, sample=True) ''' I think this is the correct solution, but not 100% sure. Probably a better way to format the tuples for the text file? And it is most likely a better way to do the "first by count, then by name"-sorting ''' tweets.map(lambda x: (x[header.index('country_name')], 1))\ .aggregateByKey(0, (lambda x, y: x + y), (lambda rdd1, rdd2: (rdd1+rdd2)))\ .sortByKey()\ .sortBy(lambda t: t[1], False)\ .map(lambda x: "%s\t%s" %(x[0], x[1])).coalesce(1).saveAsTextFile(result_path) #Landet bli key, har med '1' som teller. #Sorterer først på key, deretter på antall. #Det gjør at sorteringen på key bevares om noen har samme antall. #Mapper til riktig format, coalescer til 1 partisjon og lagrer.
from utils import setup from constants import header conf, sc, tweets, result_path = setup(5, sample=True) tweets.filter(lambda x: x[header.index('country_code')] == 'US' and x[header.index('place_type')] == 'city')\ .map(lambda x: (x[header.index('place_name')], 1))\ .aggregateByKey(0, (lambda x, y: x + y), (lambda rdd1, rdd2: (rdd1+rdd2)))\ .sortByKey()\ .sortBy(lambda x: x[1], False)\ .map(lambda x: f'{x[0]}\t{x[1]}').coalesce(1).saveAsTextFile(result_path) #Filtrerer ut tweets, henter kun tweets fra cities i USA #Mapper til sted og tellegreie #Aggregerer for å telle antall tweets per plass #Sorterer på samme måte som forrige gang, mapper, lagrer
result[word] += 1 else: result[word] = 1 result = dict(Counter(result).most_common(10)) return [(key, value) for key, value in result.items()] #Metode for å hente top 10 ord fra ei liste. Returnerer dict med ord og antall def get_formatting(element): result = element[0] + '\t' for e in element[1]: result += f'{e[0]}\t{e[1]}\t' return result[:-1] #Metode for å formatere topp ord fra en by til en string med byen og ordene top_5_cities = tweets.filter(lambda x: x[header.index('country_code')] == 'US' and x[header.index('place_type')] == 'city')\ .map(lambda x: (x[header.index('place_name')], 1, x[header.index('tweet_text')]))\ .keyBy(lambda x: x[0])\ .aggregateByKey((0, ''), (lambda x, y: (x[0]+y[1], x[1]+' '+y[2])), (lambda rdd1, rdd2: (rdd1[0]+rdd2[0], rdd1[1]+rdd2[1])))\ .sortBy(lambda x: x[1], False)\ .map(lambda x: (x[0], x[1][0], x[1][1]))\ .top(5, key=lambda x: x[1])\ #Filtrer på tweets fra byer i USA, henter byen, telle-greie, tweet text. Byen som keys #Aggreger for å telle antall tweets og kombinere tweets til én streng #Sorterer for å finne byene med flest tweets #Mapper til (by, antall, tweet-streng) og henter topp 5 byer sc.parallelize(top_5_cities)\ .sortBy(lambda x: x[1], False)\ .map(
from datetime import datetime as dt from utils import setup from constants import header conf, sc, tweets, result_path = setup(4, sample=True) tweets.map(lambda x: (x[header.index('country_name')], int(x[header.index('utc_time')]) + int(x[header.index('timezone_offset')])))\ .map(lambda x: ((x[0], dt.fromtimestamp(x[1]/1000).hour), 1))\ .aggregateByKey(0, (lambda x, y: x + y), (lambda rdd1, rdd2: (rdd1+rdd2)))\ .map(lambda x: (x[0][0], (x[0][1], x[1])))\ .reduceByKey(lambda x, y: y if y[1] > x[1] else x)\ .map(lambda x: f'{x[0]}\t{x[1][0]}\t{x[1][1]}')\ .coalesce(1)\ .saveAsTextFile(result_path) #Henter land, og (tid + offset) som int #Mapper til ((land, hour fra datetime-objekt), telle-greie). #Aggregerer med tuppelen som key, og teller hvor mange tweets som kommer per time, per land #Mapper til ((land), (hour, antall)) #Bruker reduce til å hente den timen med høyest antall #mapper, coalescer og lagrer
from utils import setup from constants import header from functools import reduce conf, sc, tweets, result_path = setup(1, sample=False) result_file = open(result_path, 'w') #1.a) number_of_tweets = tweets.count() print('Number of tweets:' + str(number_of_tweets)) #Number of tweets when not sampled: 2715066 result_file.write(str(number_of_tweets)+'\n') #1.b) distinct_users = tweets.map(lambda x: x[header.index('username')]).distinct() #Number of distinct users when not sampled: 583299 print('Number of distinct users: ' + str(distinct_users.count())) result_file.write(str(distinct_users.count())+'\n') #1.c) distinct_countries = tweets.map(lambda x: x[header.index('country_name')]).distinct() #Number of distinct countries when not sampled: 70 print('Number of distinct countries: ' + str(distinct_countries.count())) result_file.write(str(distinct_countries.count())+'\n') #1.d) distinct_placenames = tweets.map(lambda x: x[header.index('place_name')]).distinct() #Number of distinct place names when not sampled: 23121 print('Number of distinct place names: ' + str(distinct_placenames.count())) result_file.write(str(distinct_placenames.count())+'\n') #1.e) distinct_languages = tweets.map(lambda x: x[header.index('language')]).distinct() #Number of distinct languages when not sampled: 46 print('Number of distinct languages used in tweets: ' + str(distinct_languages.count()))
from utils import setup, get_stop_words from constants import header from operator import add conf, sc, tweets, result_path = setup(6, sample=False) stop_words = get_stop_words() result_file = open(result_path, 'w') top_10 = tweets.filter(lambda x: (x[header.index('country_code')] == 'US'))\ .flatMap(lambda x: x[header.index('tweet_text')].lower().split(" "))\ .filter(lambda word: len(word) >= 2 and not word in stop_words)\ .map(lambda x: (x, 1))\ .reduceByKey(add)\ .takeOrdered(10, key=lambda x: -x[1])\ for line in top_10: result_file.write(f'{line[0]}\t{line[1]}\n') #Henter tweets fra usa, flatmapper til en liste med alle ordene i disse tweetsene #Filtrerer ut ord med minimum lengde 2, og ut med stoppord #mapper til (ord, telle-greie), #reducer på keys for å telle antall ganger hvert ord dukker opp #henter topp 10 ord med takeOrdered, som ordner sorteringen synkende, og printer til fil
from utils import setup from constants import header conf, sc, tweets, result_path = setup(3, sample=True) def centroid(size, sum_of_lat, sum_of_long): return (sum_of_lat / size, sum_of_long / size) tweets.map(lambda x: (x[header.index('country_name')], 1, float(x[header.index('latitude')]), float(x[header.index('longitude')])))\ .keyBy(lambda x: x[0])\ .aggregateByKey( (0, 0.0, 0.0), (lambda x, y: (x[0]+y[1], x[1]+y[2], x[2]+y[3])), (lambda rdd1, rdd2: (rdd1[0]+rdd2[0], rdd1[1]+rdd2[1], rdd1[2]+rdd2[2])) )\ .filter(lambda x: x[1][0] > 10)\ .map(lambda x: (x[0],centroid(*x[1])))\ .map(lambda x: f'{x[0]}\t{x[1][0]}\t{x[1][1]}').coalesce(1).saveAsTextFile(result_path) #Henter ut land, teller, lat og long som floats #Setter land som key #Aggregerer ved å summere telleren, breddegradene og lengdegradene #Filtrerer ut de under 10 tweets #Mapper til (land, sentroide). #Beregner sentroide ved å sende inn (antall, sum av bredde, sum av lengde) #Mapper til riktig format, coalescer og lagrer