Analizowanie sieci Twittera

Czas zacząć budować sieci na Twitterze. Poprzez wprowadzenie alternatywnego podejścia do budowania i uruchamiania skryptów R, w tym przypadku zbudujemy kod jako skrypt powłoki do uruchomienia w wierszu poleceń. Do tego momentu pisaliśmy kod, który ma być uruchamiany w konsoli R, co prawdopodobnie będzie dominującym sposobem używania języka. Czasami jednak możesz mieć zadanie lub program, który chcesz wykonać wiele razy przy różnych danych wejściowych. W takim przypadku łatwiej jest napisać program, który działa w wierszu poleceń i pobiera dane ze standardowego wejścia. W tym celu użyjemy programu wiersza polecenia Rscript dołączonego do instalacji R. Zamiast uruchomić teraz kod, najpierw go przejrzyjmy, abyśmy zrozumieli, co robi, zanim uruchomimy program. Przypomnijmy, że z powodu zmiany interfejsu API Google SocialGraph, , nie możemy już generować nowych danych w sieci Twitter. W związku z tym do końca będziemy wykorzystywać dane sieciowe Twittera dla Johna (@johnmyleswhite) w stanie, w jakim były w momencie, gdy je po raz pierwszy zgromadziliśmy. Ponieważ możemy chcieć zbudować sieci Twittera dla wielu różnych użytkowników, nasz program powinien mieć możliwość przyjmowania różnych nazw użytkowników oraz wprowadzania i generowania danych w razie potrzeby. Po zbudowaniu obiektu sieciowego w pamięci przeprowadzimy na nim podstawową analizę sieci w celu ustalenia podstawowej struktury społeczności, dodamy te informacje do obiektu wykresu, a następnie wyeksportujemy sieci jako pliki na dysk. Zaczynamy od załadowania biblioteki igraph oraz funkcji wbudowanych w poprzedniej sekcji, którą umieściliśmy w pliku google_sg.R.

library(igraph)

source(‘google_sg.R’)

user <- ‘johnmyleswhite’

user.net <- read.graph(paste(“data/”,user, “/”, user, “_net.graphml”, sep =

“”), format = “graphml”)

Ponownie będziemy używać biblioteki igraph do budowania obiektów wykresu na Twitterze i manipulowania nimi. Używamy funkcji źródłowej, aby załadować funkcje zapisane w poprzedniej sekcji. Ponieważ nie będziemy generować nowych danych na potrzeby tego studium przypadku, ładujemy dane wcześniej zeskrobane dla sieci Johna na Twitterze, ładując dane do folderu johnmyleswhite. Uwaga dla użytkowników systemu Windows: uruchomienie tego skryptu z powłoki DOS może być niemożliwe. W takim przypadku powinieneś po prostu ustawić zmienną użytkownika na dowolnego użytkownika Twittera, dla którego chcesz zbudować sieć i uruchomić ten skrypt, tak jak wcześniej. Zauważono to ponownie również w pliku twitter_net.R. Po zbudowaniu wszystkich niezbędnych funkcji wsparcia w poprzedniej sekcji, musimy tylko przekazać naszemu użytkownikowi funkcję twitter.snowball. Ponadto, ponieważ w tym przykładzie jesteśmy zainteresowani budowaniem sieci ego użytkownika nasion, użyliśmy tylko dwóch rund dla próbki śnieżki. W dalszej części tego rozdziału załadujemy pliki sieciowe do oprogramowania do wizualizacji wykresów Gephi, które pozwoli nam zbudować piękne wizualizacje naszych danych. Gephi ma pewne zastrzeżone nazwy zmiennych, których używa do wizualizacji. Jedną z nich jest zmienna Label, która służy do oznaczania węzłów na wykresie. Domyślnie igraph przechowuje informacje o etykiecie jako atrybut nazwy wierzchołka, dlatego musimy utworzyć nowy atrybut wierzchołka o nazwie Etykieta, który powiela te informacje. W tym celu używamy funkcji set.vertex.attribute, która pobiera obiekt wykresu user.net utworzony w poprzednim kroku, nowy atrybut i wektor danych do przypisania do tego atrybutu.

user.net <- set.vertex.attribute (user.net, „Label”,

value = get.vertex.attribute (user.net, „name”))

Gephi to wieloplatformowa platforma do wizualizacji i manipulacji grafami typu open source. Wbudowane narzędzia do wizualizacji sieci w językach R i igraph są przydatne, ale niewystarczające dla naszych potrzeb. Gephi jest specjalnie zaprojektowany do wizualizacji sieci i zawiera wiele przydatnych funkcji do tworzenia wysokiej jakości grafiki sieciowej. Jeśli nie masz zainstalowanego Gephi lub masz starą wersję, zalecamy zainstalowanie najnowszej wersji, dostępnej na stronie http://gephi.org/. Po zbudowaniu obiektu wykresu przeprowadzimy na nim podstawową analizę sieci, aby zarówno zmniejszyć jego złożoność, jak i odkryć część lokalnej struktury społeczności.

(II): Tryby obiektów

Obiekty R istnieją w systemie obiektowym. R ma dwa systemy obiektowe: S3 i S4. S4 to najnowsza wersja R i zawiera nowy sposób podejścia do programowania R. S3 to poprzednia wersja. Obie wersje działają jednocześnie. S4 oferuje nowe potężne metody, ale do korzystania z tych metod konieczna jest solidna znajomość S3. Ta książka koncentruje się głównie na metodach S3, w tym, w stosownych przypadkach, na składni S4.

Przegląd trybów

Tryby opisują rodzaj informacji zawartych w obiekcie i są klasyfikacją na poziomie S3. Tryb obiektu można znaleźć za pomocą funkcji mode(). Klasyfikacja poziomu S4 jest według typu i można ją znaleźć za pomocą funkcji typeof(). Obecnie obiekty R dzielą się na jeden z następujących trybów: NULL, logiczny, numeryczny, złożony, surowy, znak, lista, wyrażenie, nazwa, funkcja, pairlist, język, char, …, środowisko, externalptr, poorref, zamknięcie, kod bajtowy, obietnica i S4. Ponieważ R stale się zmienia, lista trybów może ulec zmianie. Z kilkoma wyjątkami typy i tryby są takie same i większość z nich  można znaleźć pod listą typów. Listę typów można znaleźć na stronie pomocy dla typeof () i na http://svn.r-project.org/R/trunk/src/main/util.c, w TypeTable. Do instancji, dla których mode() i typeof() dają różne wyniki, należą: funkcja typeof() zwraca liczbę całkowitą lub podwójną, gdzie mode() zwraca wartość liczbową, typeof() zwraca specjalne lub wbudowane, gdzie mode() zwraca funkcję, a typeof() zwraca symbol, gdzie mode() zwraca nazwę. Strona pomocy dla mode() podaje odniesienie między trybami i typami.

Często używane tryby

Większość użytkowników nigdy nie użyje połowy trybów. Najczęściej używane tryby to NULL, logiczne, numeryczne, złożone, surowe, znakowe, lista, funkcja, wywołanie, nazwa, wyrażenie i S4. Tryb NULL jest trybem innego, niemodalnego, pustego obiektu. Obiekty trybu logicznego zawierają elementy, które mogą przyjmować wartości PRAWDA, FAŁSZ lub NA, gdzie NA oznacza brakującą wartość. Obiekty trybu numerycznego mogą przyjmować liczby całkowite lub rzeczywiste wartości liczbowe lub NA. Obiekty trybu złożonego mogą przyjmować złożone wartości liczbowe lub NA. Obiekty trybu raw składają się z bajtów. NA są ustawione na 00 dla surowych danych. Obiekty postaci trybu składają się z ciągów znaków lub NA. Elementy obiektów znakowych są cytowane, z wyjątkiem NA. Obiekty listy trybów to listy innych obiektów, które mogą znajdować się w dowolnym trybie. Obiektami funkcji trybu są funkcje. Obiekty nazwy trybu to uproszczona nazwa obiektu oparta na pierwszym elemencie obiektu, zakładając, że nie brakuje pierwszego elementu. Obiektami wywołania trybu są funkcje i argumenty. Obiekty wyrażenia trybu to zbiory obiektów, takie jak wywołania i nazwy. Obiekty trybu S4 to obiekty S4, które są złożone (odnoszą się do struktury obiektu, a nie do liczb zespolonych). Źródłami powyższych informacji są strony pomocy dla mode() i typeof().

Tryby atomowy, rekurencyjny i językowy

Tryby występują w trzech rodzajach: atomowym, rekurencyjnym i językowym. Tryby atomowe to NULL, logiczne, numeryczne, złożone, surowe i znakowe. Atom odnosi się do elementów obiektów podobnych do atomów. W przypadku trybów atomowych wszystkie elementy w obiekcie mają ten sam tryb atomowy. Tryby rekurencyjne to zbiory obiektów i mogą zawierać obiekty różnych trybów. Dwa typy trybów rekurencyjnych to lista i funkcja. Większość obiektów, które nie są atomowe, ma charakter rekurencyjny. Tryby językowe to nazwa, połączenie i wyrażenie. Więcej informacji o rodzajach trybów można znaleźć na stronach pomocy funkcji testujących rodzaj trybu obiektu: is.atomic(), is.recursive() i is.language().

Praca z interfejsem API Google SocialGraph

Zaczynamy od załadowania pakietów R, które będą nam potrzebne do wygenerowania wykresów na Twitterze. Będziemy używać trzech pakietów R do tworzenia tych wykresów z SGA. Pakiet RCurl zapewnia interfejs do biblioteki libcurl, której będziemy używać do wysyłania żądań HTTP do SGA. Następnie użyjemy RJSONIO do parsowania JSON zwróconego przez SGA na listach R. Tak się składa, że ​​oba te pakiety opracował Duncan Temple Lang, który opracował wiele niezbędnych pakietów R (patrz http://www.omegahat.org/). Na koniec użyjemy igraph do budowy i przechowywania obiektów sieciowych. Pakiet igraph to potężny pakiet R do tworzenia obiektów graficznych i manipulowania nimi, a jego elastyczność będzie dla nas bardzo cenna, gdy zaczniemy pracować z naszymi danymi sieciowymi.

library(RCurl)

library(RJSONIO)

library(igraph)

Pierwsza funkcja, którą napiszemy, działa z SGA na najwyższym poziomie. Wywołamy funkcję twitter.network, aby wysłać zapytanie do SGA dla danego użytkownika początkowego, przeanalizować JSON i zwrócić reprezentację sieci ego tego użytkownika. Ta funkcja przyjmuje pojedynczy parametr user, który jest ciągiem odpowiadającym początkowemu użytkownikowi Twittera. Następnie konstruuje odpowiedni adres URL żądania SGA GET i używa funkcji getURL w RCurl do wykonania żądania HTTP. Ponieważ wyszukiwanie śnieżkami będzie wymagało wielu żądań HTTP naraz, budujemy pętlę while, która sprawdza, czy strona zwrócona nie wskazuje przerwy w działaniu usługi. Bez tego skrypt nieumyślnie pominie te węzły podczas wyszukiwania kuli śnieżnej, ale dzięki tej kontroli po prostu wróci i spróbuje wykonać nowe żądanie, dopóki dane nie zostaną zebrane. Kiedy wiemy, że żądanie API zwróciło JSON, używamy funkcji fromJSON w pakiecie RJSONIO do analizy JSON.

twitter.network <- function(user) {

api.url <-

paste(“https://socialgraph.googleapis.com/lookup?q=http://twitter.com/”,

user, “&edo=1&edi=1″, sep=””)

api.get <- getURL(api.url)

# To guard against web-request issues, we create this loop

# to ensure we actually get something back from getURL.

while(grepl(“Service Unavailable. Please try again later.”, api.get)) {

api.get <- getURL(api.url)

}

api.json <- fromJSON(api.get)

return(build.ego(api.json))

}

Po przeanalizowaniu JSON musimy zbudować sieć z tych danych. Przypomnijmy, że dane zawierają dwa typy relacji: nodes_referenced (out-degree) i nodes_referenced_by (in-degree). Musimy więc wykonać dwa przejścia przez dane, aby uwzględnić oba typy krawędzi. W tym celu napiszemy funkcję build.ego, która pobiera przeanalizowaną SGA JSON jako listę i buduje sieć. Zanim jednak zaczniemy, musimy wyczyścić dane relacyjne zwrócone przez SGA. Jeśli dokładnie przejrzysz wszystkie węzły zwrócone przez żądanie API, zauważysz, że niektóre wpisy nie są właściwymi użytkownikami Twittera. W wynikach uwzględniono relacje niezwiązane z tym ćwiczeniem. Na przykład istnieje wiele list na Twitterze, a także adresy URL, które odnoszą się do przekierowań „konto”. Chociaż wszystkie są częścią grafu społecznościowego Twittera, nie jesteśmy zainteresowani włączeniem tych węzłów do naszego wykresu, dlatego musimy napisać funkcję pomocnika, aby je usunąć.

find.twitter <- function(node.vector) {

twitter.nodes <- node.vector[grepl(“http://twitter.com/”, node.vector,

fixed=TRUE)]

if(length(twitter.nodes) > 0) {

twitter.users <- strsplit(twitter.nodes, “/”)

user.vec <- sapply(1:length(twitter.users),

function(i) (ifelse(twitter.users[[i]][4]==”account”,

NA, twitter.users[[i]][4])))

return(user.vec[which(!is.na(user.vec))])

}

else {

return(character(0))

}

}

Funkcja find.twitter wykorzystuje to, wykorzystując strukturę adresów URL zwracanych przez SGA, aby sprawdzić, czy faktycznie są użytkownikami Twittera, a nie jakąś inną częścią grafu społecznościowego. Pierwszą rzeczą, którą robi ta funkcja, jest sprawdzenie, które węzły zwrócone przez SGA są faktycznie z Twittera, za pomocą funkcji grepl w celu sprawdzenia wzorca http://twitter.com/. W przypadku pasujących adresów URL musimy dowiedzieć się, które odpowiadają rzeczywistym kontom, a nie listom lub przekierowaniom. Jednym ze sposobów jest podzielenie adresów URL ukośnikiem odwrotnym, a następnie sprawdzenie słowa „konto”, które wskazuje adres URL użytkownika spoza Twittera. Po zidentyfikowaniu indeksów pasujących do tego wzorca innego niż Twitter, po prostu zwracamy adresy URL, które nie pasują do tego wzorca. Poinformuje to funkcję build.ego, które węzły powinny zostać dodane do sieci.

build.ego <- function(json) {

# Find the Twitter user associated with the seed user

ego <- find.twitter(names(json$nodes))

# Build the in- and out-degree edgelist for the user

nodes.out <- names(json$nodes[[1]]$nodes_referenced)

if(length(nodes.out) > 0) {

# No connections, at all

twitter.friends <- find.twitter(nodes.out)

if(length(twitter.friends) > 0) {

# No twitter connections

friends <- cbind(ego, twitter.friends)

}

else {

friends <- c(integer(0), integer(0))

}

}

else {

friends <- c(integer(0), integer(0))

}

nodes.in <- names(json$nodes[[1]]$nodes_referenced_by)

if(length(nodes.in) > 0) {

twitter.followers <- find.twitter(nodes.in)

if(length(twitter.followers) > 0) {

followers <- cbind(twitter.followers, ego)

}

else {

followers <- c(integer(0), integer(0))

}

}

else {

followers <- c(integer(0), integer(0))

}

ego.el <- rbind(friends, followers)

return(ego.el)

}

Po zidentyfikowaniu odpowiednich węzłów na liście możemy teraz zacząć budować sieć. Aby to zrobić, użyjemy build.ego, aby stworzyć „listę brzegową” opisującą relacje wewnątrz i na zewnątrz naszego użytkownika początkowego. Lista krawędzi to po prostu macierz dwukolumnowa reprezentująca relacje na grafie kierunkowym. Pierwsza kolumna zawiera źródła krawędzi, a druga kolumna zawiera cele. Możesz myśleć o tym jak o węzłach w pierwszej kolumnie łączących się z węzłami w drugiej. Najczęściej listy krawędzi będą zawierać etykiety liczb całkowitych lub ciągów dla węzłów. W takim przypadku użyjemy ciągu nazwy użytkownika Twittera. Chociaż funkcja build.ego jest długa pod względem liczenia wierszy, jej funkcjonalność jest w rzeczywistości dość prosta. Większość kodu służy do organizowania i sprawdzania błędów budowania list krawędzi. Jak widać, najpierw sprawdzamy, czy API wywołuje zarówno nodes_referenced, jak i nodes_referenced_by zwróciło przynajmniej niektóre relacje. Następnie sprawdzamy, które węzły faktycznie odnoszą się do użytkowników Twittera. Jeśli którakolwiek z tych kontroli nic nie zwróci, zwrócimy specjalny wektor jako wynik naszej funkcji: c (liczba całkowita (0), liczba całkowita (0)). W ramach tego procesu tworzymy dwie matryce list krawędzi, trafnie nazywanych przyjaciółmi i obserwującymi. W ostatnim kroku używamy rbind do powiązania tych dwóch macierzy w jednej liście krawędzi, zwanej ego.el. Zastosowaliśmy specjalny wektor c (liczba całkowita (0), liczba całkowita (0)) w przypadkach, w których nie ma danych, ponieważ rbind skutecznie je zignoruje i nie wpłynie to na nasze wyniki. Możesz to zobaczyć, wpisując następujące polecenie na konsoli R.

rbind(c(1,2), c(integer(0), integer(0)))

[,1] [,2]

[1,] 1 2

Być może zastanawiasz się, dlaczego budujemy tylko listę relacji, zamiast budować wykres bezpośrednio za pomocą igraph. Ze względu na sposób, w jaki igraph przechowuje wykresy w pamięci, iteracyjne tworzenie wykresów może być trudne w sposób wymagany przez próbkę śnieżki. Dlatego dużo łatwiej jest najpierw zbudować cały relacyjny zestaw danych (w tym przypadku jako listę brzegową), a następnie przekonwertować te dane na wykres. Napisaliśmy teraz rdzeń naszego skryptu do tworzenia wykresów. Funkcja build.ego wykonuje trudną pracę polegającą na pobraniu przeanalizowanego JSON-a z SGA i przekształceniu go w coś, co igraph może przekształcić w sieć. Ostatnim elementem, który będziemy musieli zbudować, jest połączenie wszystkiego w celu wygenerowania próbki kuli śnieżnej. Stworzymy funkcję twitter.snowball, aby wygenerować tę próbkę i jedną małą funkcję pomocniczą, get.seeds, aby wygenerować listę nowych nasion do odwiedzenia. Podobnie jak w build.ego, głównym celem twitter.snowball jest wygenerowanie listy krawędzi relacji sieciowych. W tym przypadku będziemy jednak wiązać wyniki wielu wywołań build.ego i zwracać obiekt wykresu igraph. Dla uproszczenia zaczynamy od funkcji get.seeds, chociaż będzie ona dotyczyć rzeczy

generated in twitter.snowball.

get.seeds <- function(snowball.el, seed) {

new.seeds <- unique(c(snowball.el[,1],snowball.el[,2]))

return(new.seeds[which(new.seeds!=seed)])

}

Celem get.seeds jest znalezienie unikalnego zestawu węzłów z listy krawędzi, które nie są węzłami początkowymi. Dokonuje się tego bardzo łatwo, redukując macierz dwukolumnową do pojedynczego wektora, a następnie znajdując unikalne elementy tego wektora. Ten czysty wektor nazywa się new.seed, a następnie zwracane są tylko te elementy, które nie są ziarnem. Jest to prosta i skuteczna metoda, ale jest jedna rzecz, którą musimy wziąć pod uwagę, korzystając z tej metody. Funkcja get.seeds sprawdza tylko, czy nowe nasiona nie są takie same jak bieżące nasiona. Chcielibyśmy uwzględnić coś, co zapewni, że podczas naszej próby śnieżki nie będziemy ponownie odwiedzać węzłów w sieci, dla których struktura została już zregenerowana. Z technicznego punktu widzenia nie jest to koniecznie ważne, ponieważ moglibyśmy bardzo łatwo usunąć zduplikowane wiersze z końcowej listy krawędzi. Jest to jednak ważne z praktycznego punktu widzenia. Usuwając węzły, które były już odwiedzane z listy potencjalnych nowych nasion przed budowaniem nowej struktury, zmniejszyliśmy liczbę wywołań API, które musimy wykonać. To z kolei zmniejsza prawdopodobieństwo uderzenia w limit prędkości SGA i skraca czas działania naszego skryptu. Zamiast obsługiwać to przez funkcję get.seeds, dodajemy tę funkcję do twitter.snowball, gdzie cała lista brzegowa sieci jest już zapisana w pamięci. Zapewnia to, że nie ma wielu kopii całej listy krawędzi w pamięci, ponieważ budujemy całą śnieżkę. Pamiętaj, że w tych skalach musimy być bardzo świadomi pamięci, zwłaszcza w języku takim jak R.

twitter.snowball <- function(seed, k=2) {

# Get the ego-net for the seed user. We will build onto

# this network to create the full snowball search.

snowball.el <- twitter.network(seed)

# Use neighbors as seeds in the next round of the snowball

new.seeds <- get.seeds(snowball.el, seed)

rounds <- 1 # We have now completed the first round of the snowball!

# A record of all nodes hit, this is done to reduce the amount of

# API calls done.

all.nodes <- seed

# Begin the snowball search…

while(rounds < k) {

next.seeds <- c()

for(user in new.seeds) {

# Only get network data if we haven’t already visited this node

if(!user %in% all.nodes) {

user.el <- twitter.network(user)

if(dim(user.el)[2] > 0) {

snowball.el <- rbind(snowball.el, user.el)

next.seeds <- c(next.seeds, get.seeds(user.el, user))

all.nodes <- c(all.nodes, user)

}

}

}

new.seeds <- unique(next.seeds)

new.seeds <- new.seeds[!which(new.seeds %in% all.nodes)]

rounds <- rounds + 1

}

# It is likely that this process has created duplicate rows.

# As a matter of housekeeping we will remove them because

# the true Twitter social graph does not contain parallel edges.

snowball.el <- snowball.el[!duplicated(snowball.el),]

return(graph.edgelist(snowball.el))

}

Funkcjonalność funkcji twitter.snowball jest taka, jak można się spodziewać. Funkcja przyjmuje dwa parametry: seed i k. Pierwszy to ciąg znaków dla użytkownika Twittera, w naszym przypadku może to być „DrawConway” lub „JohnJyleswhite”. K jest liczbą całkowitą większą lub równą dwa i określa liczbę rund dla śnieżki Szukaj. W mowie sieciowej wartość k ogólnie odnosi się do stopnia lub odległości na wykresie. W tym przypadku odpowiada to odległości od nasion w sieci, do której osiągnie próbka śnieżki. Naszym pierwszym krokiem jest zbudowanie początkowej sieci ego z nasion; z tego otrzymamy nowe nasiona do następnej rundy. Robimy to za pomocą połączeń z twitter.network i get.seeds. Teraz można rozpocząć iteracyjną pracę próbki kuli śnieżnej. Całe próbkowanie odbywa się w pętli while twitter.snowball. Podstawowa struktura logiczna pętli jest następująca. Najpierw sprawdź, czy nie osiągnęliśmy końca naszej próbki odległości. Jeśli nie, przejdź do budowy kolejnej warstwy śnieżki. Robimy to poprzez iteracyjne budowanie sieci ego każdego z naszych nowych użytkowników nasion. Obiekt all.nodes służy do śledzenia już istniejących węzłów odwiedzonych; innymi słowy, zanim zbudujemy sieć ego węzła, najpierw sprawdzamy, czy nie ma go już we wszystkich węzłach. Jeśli nie jest, dodajemy relacje tego użytkownika do snowball.el, next.seeds i all.nodes. Zanim przejdziemy do następnej rundy śnieżki, sprawdzamy, czy nowy wektor new.seeds nie zawiera żadnych duplikatów. Ponownie robi się to, aby zapobiec ponownym odwiedzinom węzłów. Na koniec zwiększamy licznik rund. W ostatnim kroku bierzemy macierz snowball.el, która reprezentuje listę krawędzi całej próbki kuli śnieżnej, i przekształcamy ją w obiekt wykresu igraph za pomocą funkcji listy graph.edge. Jest jeszcze jedna ostatnia część sprzątania, którą musimy zrobić przed konwersją. Ponieważ dane w SGA są niedoskonałe, czasami zdarzają się zduplikowane relacje między krawędziami próbki. Graficznie teoretycznie moglibyśmy pozostawić te relacje i użyć specjalnej klasy wykresu zwanej „multi-graf” jako naszej sieci na Twitterze. Multi-wykres to po prostu wykres z wieloma krawędziami między tymi samymi węzłami. Chociaż ten paradygmat może być użyteczny w niektórych kontekstach, istnieje bardzo niewiele wskaźników analizy sieci społecznościowych, które są prawidłowe dla takiego modelu. Ponadto, ponieważ w tym przypadku dodatkowe krawędzie są wynikiem błędów, usuniemy te zduplikowane krawędzie przed konwersją na obiekt wykresu. Mamy teraz wszystkie funkcje potrzebne do budowy sieci Twittera. W następnej sekcji zbudujemy dodatkowe skrypty, które ułatwią szybkie wygenerowanie struktury sieci od danego użytkownika początkowego i wykonanie na nich podstawowych wykresów analiz strukturalnych y, aby odkryć w nich strukturę społeczności lokalnej.

(II) : Rodzaje obiektów

Tu zajmiemy się różnego rodzajem obiektów używanych w R pod względem ich dwóch ważnych cech: trybu i klasy. Pierwsza część zawiera listę trybów i opisuje najczęstsze tryby. Oprócz wyszczególnienia wszystkich trybów obecnych w R, opisuje właściwości  trybu atomowego – NULL, nieprzetworzone, logiczne, numeryczne, złożone i znakowe – oraz lista trybów nieatomowych, funkcja, wywołanie, nazwa i wyrażenie Druga część wprowadza klasy i podaje właściwości kilku z nich. Zawiera specjalną sekcję o wektorach, które nie są klasą, ale bardzo powszechnym rodzajem obiektu. Klasy powiązane z wektorami są surowe, logiczne, całkowite, podwójne, złożone, znakowe, niektóre listy i wyrażenia. W przypadku większości obiektów atomowych tryb i klasa są takie same. Po opisaniu wektorów podajemy właściwości klas dla macierzy, tablic, szeregów czasowych, czynników, ramek danych, dat oraz godzin i dat. Wszystko kończy się informacjami na temat przypisywania nazw do wymiarów wektorów, macierzy, tablic i list.

Hakowanie danych społecznościowych na Twitterze

Twitter zapewnia dwa różne rodzaje dostępu do swojego interfejsu API. Pierwszy jest nieuwierzytelniony, co pozwala na 150 żądań na godzinę przed odcięciem. Alternatywnie, uwierzytelnione połączenia OAuth do API są ograniczone do 350 na godzinę. Ograniczenie do 150 wywołań API na godzinę to zdecydowanie za mało, aby zeskrobać potrzebne nam dane w rozsądnym czasie. Drugi limit 350 to również za mało, a ponadto nie jesteśmy zainteresowani budowaniem aplikacji Twittera, która wymaga uwierzytelnienia. Chcemy szybko uzyskać dane, aby zbudować sieci, abyśmy mogli zacząć hakować dane. Jeśli nie znasz interfejsów API RESTful lub nigdy nie słyszałeś o OAuth, nie martw się. Na potrzeby tego ćwiczenia nie będziemy się martwić o te szczegóły. Jeśli chcesz dowiedzieć się więcej na temat któregokolwiek z nich, zalecamy zapoznanie się z dokumentacją konkretnej usługi, do której próbujesz uzyskać dostęp.  Niestety nie będziemy w stanie tego zrobić, jeśli użyjemy interfejsu API udostępnionego przez Twittera. Aby uzyskać potrzebne nam dane, będziemy musieli skorzystać z innego źródła danych z wykresów społecznościowych na Twitterze: Google SocialGraph API (zwanego także SGA). Google wprowadził SGA w 2008 roku z zamiarem stworzenia jednej tożsamości online używanej we wszystkich serwisach społecznościowych. Na przykład możesz mieć konta z kilkoma usługami online które rozstrzygają się na jeden adres e-mail. Ideą SGA jest wykorzystanie tego jednego bitu informacji do zestawienia całego wykresu społecznościowego w wielu usługach. Jeśli jesteś ciekawy, jak długi jest Twój cyfrowy ślad w Google, wpisz następujące polecenie w swojej ulubionej przeglądarce:

https://socialgraph.googleapis.com/lookup?q=@EMAIL_ADDRESS&fme=1&pretty=1

Jeśli zastąpisz adres EMAIL_ADDRESS odpowiednim adresem, interfejs API zwróci nieprzetworzony kod JSON do okna przeglądarki, które możesz zbadać, aby zobaczyć, ile części Twojego wykresu społecznościowego Google już przechowuje! Jeśli masz konto w serwisie Twitter zarejestrowane na podany adres e-mail, prawdopodobnie zauważysz również, że adres URL Twojej strony na Twitterze jest wyświetlany jako jedna z usług wykresów społecznościowych, która rozwiązuje ten adres e-mail. Twitter jest jednym z wielu serwisów społecznościowych, które SGA indeksuje w celu przechowywania danych publicznych wykresów społecznościowych. Dlatego możemy użyć SGA, aby wysłać zapytanie do sieci społecznościowej określonego użytkownika, a następnie zbudować sieć. Podstawową zaletą korzystania z SGA jest to, że w przeciwieństwie do drobnych zapytań godzinowych, które zapewnia Twitter, SGA pozwala na 50 000 zapytań dziennie. Nawet w skali Twittera będzie to więcej niż wystarczająca liczba zapytań, aby zbudować wykres społecznościowy dla zdecydowanej większości użytkowników. Oczywiście, jeśli jesteś Ashton Kutcher lub Tim O’Reilly, metoda opisana w tym studium przypadku nie będzie działać. To powiedziawszy, jeśli jesteś gwiazdą i nadal chcesz śledzić to ćwiczenie, możesz użyć jednej z użytkowników na Twitterze:

@johnmyleswhite lub @drewconway.

https://socialgraph.googleapis.com/lookup?q=http://twitter.com/drewconway & edo = 1 & edi = 1 & pretty = 1

Na przykład użyjmy strony Twittera Drew, aby zbadać, w jaki sposób SGA porządkuje dane. Wpisz poprzednie zapytanie API w wybranej przeglądarce internetowej. Jeśli chcesz, możesz zapytać SGA o własną nazwę użytkownika na Twitterze. Tak jak poprzednio, SGA zwróci surowy JSON opisujący relacje Drew na Twitterze. Z samego zapytania API widzimy trzy ważne parametry: edo, edi i pretty. Ładny parametr jest użyteczny tylko w tym widoku przeglądarki, ponieważ zwraca sformatowany JSON. Kiedy analizujemy ten JSON w sieci, upuszczamy ten parametr. edi i edo odpowiadają jednak kierunkom relacji na Twitterze. Parametr edo oznacza „przewyższa”, tj. Znajomych na Twitterze, a edi oznacza „przewija”, czyli obserwujących na Twitterze. W przykładzie 1 widzimy skróconą wersję sformatowanego surowego JSON zwróconego dla @drewconway. Obiekt JSON, który najbardziej nas interesuje, to węzły. Zawiera pewne opisowe informacje o użytkowniku Twittera, ale co ważniejsze, relacje przychodzące i wychodzące. Obiekt nodes_referenced zawiera wszystkich znajomych z Twittera dla pytanego węzła. Są to inni użytkownicy, których śledzi węzeł (out-stopień). Podobnie obiekt nodes_referenced_by zawiera użytkowników Twittera śledzących żądany węzeł (w stopniu).

Przykład . Struktura danych Google SocialGraph w surowym JSON

{

“canonical_mapping”: {

“http://twitter.com/drewconway”: “http://twitter.com/drewconway”

},

“nodes”: {

“http://twitter.com/drewconway”: {

“attributes”: {

“exists”: “1”,

“bio”: “Hopeful academic, data nerd, average hacker, student of conflict.”,

“profile”: “http://twitter.com/drewconway”,

“rss”: “http://twitter.com/statuses/user_timeline/drewconway.rss”,

“atom”: “http://twitter.com/statuses/user_timeline/drewconway.atom”,

“url”: “http://twitter.com/drewconway”

},

“nodes_referenced”: {

},

“nodes_referenced_by”: {

}

}

}

Przeszukiwacz SGA po prostu skanuje Twitter w poszukiwaniu publicznych łączy między użytkownikami i przechowuje relacje w swojej bazie danych. Prywatne konta na Twitterze są zatem nieobecne w danych. Jeśli analizujesz własne dane SGA, możesz zauważyć, że nie odzwierciedlają one twoich bieżących relacji na Twitterze. W szczególności obiekt nodes_referenced może zawierać użytkowników, których już nie obserwujesz. Wynika to z faktu, że SGA tylko okresowo indeksuje aktywne linki, więc dane w pamięci podręcznej nie zawsze odzwierciedlają najbardziej aktualne dane.

Oczywiście nie chcemy współpracować z SGA przez przeglądarkę. Ten interfejs API ma być dostępny programowo, a zwracany JSON musi zostać przeanalizowany w obiekt wykresu, abyśmy mogli budować i analizować te sieci na Twitterze. Aby zbudować te obiekty wykresów, naszą strategią będzie wykorzystanie jednego użytkownika Twittera jako źródła (przywołaj numer Erdősa) i zbudowanie sieci z tego źródła. Użyjemy metody zwanej próbkowaniem kuli śnieżnej, która rozpoczyna się od pojedynczego nasiona, a następnie znajduje wszystkie połączenia wejściowe i wyjściowe z tym nasionem. Następnie użyjemy tych połączeń jako nowych nasion i powtórzymy proces dla ustalonej liczby rund. W tym studium przypadku wykonamy tylko dwie rundy próbkowania, co robimy z dwóch powodów. Po pierwsze, jesteśmy zainteresowani mapowaniem i analizowaniem sieci lokalnej użytkownika-nasion ,strukturę, która zawiera zalecenia dotyczące tego, za kim powinien postępować użytkownik seedujący. Po drugie, ze względu na skalę wykresu społecznościowego na Twitterze, możemy szybko przekroczyć limit prędkości SGA i pojemność naszego dysku twardego, jeśli użyjemy więcej rund. Mając to na uwadze, w następnej sekcji zaczynamy od opracowania podstawowych funkcji do pracy z SGA i analizy danych

(I) : Drobiazgi

Dwa systemy obiektowe – S3 i S4 – są używane w R. Sloty są częścią S4. Można przypisywać podzbiory obiektu. Na przykład niech a będzie macierzą i niech użytkownik chce zmienić te wartości, które są większe od 100 do 100. Następnie instrukcja

a [a> 100] = 100

dokona wymiany i pozostawi resztę matrycy nienaruszoną. Operatory ? i ?? otwierają strony pomocy. Dla znanych nazw funkcji, ?nazwa (lub help(nazwa)) zwróci stronę pomocy dla funkcji, gdzie nazwa jest nazwą funkcji. Aby wyszukać funkcje związane z niektórymi technikami lub metodami, operator,? jest używany. Wpisanie „słów kluczowych” (lub help.search („słów kluczowych”)), gdzie słowa kluczowe składają się ze słów kluczowych dotyczących techniki lub metody, mogą dać listę funkcji w pakietach związanych z tematem. Czasami wyszukiwanie jest puste. Spróbuj ponownie, używając różnych słów kluczowych. Dwukropek jest używany w R. na cztery sposoby. Interesujące jest tutaj użycie pojedynczego dwukropka do zdefiniowania sekwencji i podwójnego dwukropka w odniesieniu do funkcji według pakietu i nazwy. Jeśli aib są dwiema liczbami, wyrażenie a: b da sekwencję liczb całkowitych od zaokrąglenia w dół do liczby całkowitej ib zaokrąglonego w dół do liczby całkowitej. Zauważ, że liczba a może być większa niż liczba b. Funkcje dostarczane z R są częścią jakiegoś pakietu. Jeśli pakiet nie zostanie załadowany, wyszukiwanie przy użyciu samej nazwy funkcji nic nie zwróci. Pełna nazwa funkcji to nazwa_pakietu:: nazwa_funkcji, gdzie nazwa_pakietu to nazwa pakietu, a nazwa funkcji to nazwa funkcji.

Aby uzyskać więcej informacji na temat dwukropków, wpisz ?„:” W wierszu polecenia R. Operator ~ jest używany we wzorach modeli do oddzielania lewej i prawej strony modelu. Aby uzyskać więcej informacji, wpisz ?„~” w wierszu polecenia R. Symbol # służy do komentarzy. Podczas pisania funkcji wszystko, co znajduje się po prawej stronie znaku # w wierszu kodu, jest ignorowane.

Strony pomocy CRAN dotyczące podzbiorów można znaleźć, wpisując ?? „Extract or Replace”.

Myślenie graficzne

Zanim przejdziemy do zhakowania wykresu społecznościowego na Twitterze, warto cofnąć się o krok i zdefiniować sieć. Matematycznie sieć lub wykres to po prostu zestaw węzłów i krawędzi. Te zestawy nie mają kontekstu; służą jedynie do przedstawienia świata, w którym krawędzie łączą węzły ze sobą. W najbardziej abstrakcyjnym sformułowaniu krawędzie te nie zawierają żadnych informacji poza faktem, że łączą dwa węzły. Możemy jednak zobaczyć, jak ten ogólny statek organizujący dane może szybko stać się bardziej złożony. Rozważ trzy wykresy na rycinie 11-2.

W górnym panelu rysunku znajduje się przykład niekierowanego wykresu. W takim przypadku krawędzie wykresu nie mają kierunku. Innym sposobem myślenia o tym jest to, że połączenie między węzłami w tym przypadku implikuje wzajemność powiązania. Na przykład Dick i Harry udostępniają połączenie, a ponieważ ten wykres nie jest przekierowany, możemy myśleć o tym jako znaczeniu ,że mogą wymieniać między sobą informacje, towary itp. w ramach tego remisu. Ponieważ jest to bardzo podstawowa konfiguracja sieci, łatwo przeoczyć fakt, że nawet w przypadku nieukierunkowanym zwiększyliśmy złożoność wykresu w stosunku do najbardziej ogólnego przypadku, o którym wspominaliśmy wcześniej. Na wszystkich wykresach na rysunku dodaliśmy etykiety do węzłów. Jest to dodatkowa informacja, która jest tu dość przydatna, ale należy ją wziąć pod uwagę, zastanawiając się, w jaki sposób przechodzimy od abstrakcji sieci do abstrakcji opisującej rzeczywiste dane. Przechodząc do środkowego panelu rysunku, widzimy skierowany wykres. W tej wizualizacji krawędzie mają strzałki wskazujące kierunkowość krawędzi. Teraz krawędzie nie są wzajemne, ale wskazują jednokierunkowy remis. Na przykład Dick i Drew mają powiązania z Johnem, ale John ma tylko związek z Harrym. W ostatnim panelu rysunku dodaliśmy etykiety krawędzi do wykresu. W szczególności dodaliśmy znak pozytywny lub negatywny do każdej etykiety. Może to wskazywać na relację „lubię” lub „nie lubię” między członkami tej sieci lub pewien poziom dostępu. Tak jak etykiety węzłów dodają informacje i kontekst do sieci, podobnie jak etykiety krawędzi. Etykiety te mogą być również znacznie bardziej złożone niż prosta relacja binarna. Etykiety te mogą być wagami wskazującymi siłę lub rodzaj relacji. Ważne jest, aby wziąć pod uwagę różnice między tymi różnymi typami wykresów, ponieważ dane wykresów społecznościowych, które napotkamy w Internecie, mają wiele różnych postaci. Zmiana struktura wykresów może mieć wpływ na to, jak ludzie korzystają z usługi, aw konsekwencji na to, jak możemy analizować dane. Rozważ dwa popularne serwisy społecznościowe, które różnią się klasą używanych wykresów: Facebook i Twitter. Facebook to ogromny, nieukierunkowany wykres społecznościowy. Ponieważ „przyjaźń” wymaga aprobaty, wszystkie krawędzie oznaczają wzajemną przyjaźń. To spowodowało, że Facebook ewoluował jako relatywnie bardziej zamknięta sieć z gęstą strukturą sieci lokalnej, a nie masywne centralne węzły bardziej otwartej usługi. Z drugiej strony Twitter to bardzo duży skierowany wykres. Poniższa dynamika na Twitterze nie wymaga wzajemności, a zatem usługa pozwala na duże asymetrie na ukierunkowanym wykresie, na którym gwiazdy, serwisy informacyjne i inni głośni użytkownicy działają jako główne punkty transmisji tweetów. Chociaż różnice w sposobie nawiązywania połączeń między usługami mogą wydawać się subtelne, wynikające z tego różnice są bardzo duże. Zmieniając nieco dynamikę, Twitter stworzył zupełnie inny rodzaj wykresu społecznościowego, z którego ludzie bardzo korzystają w inny sposób niż za pomocą Facebooka. Oczywiście przyczyny tej różnicy wykraczają poza struktury wykresów, w tym limit 140 znaków na Twitterze i całkowicie publiczny charakter większości kont na Twitterze, ale struktura wykresu ma ogromny wpływ na działanie całej sieci. W tym rozdziale skupimy się na Twitterze do studium przypadku i dlatego będziemy musieli wziąć pod uwagę jego struktury grafów ukierunkowanych podczas wszystkich aspektów analizy. Zaczynamy od zebrania danych o relacjach na Twitterze bez przekraczania limitu stawek API lub naruszenia warunków świadczenia usług

(I) : Listy

Listy są kolekcjami obiektów R. Obiekty mogą być obiektami dowolnego typu i nie muszą być tego samego typu na liście. Obiekty są indeksowane na liście. Do patrzenia na obiekty na liście używane są pojedyncze nawiasy kwadratowe. Na przykład,

blist [1: 5]

zwróci pierwsze pięć obiektów w blist, a także będzie listą. Aby uzyskać dostęp do obiektu na liście, wymagane są podwójne nawiasy kwadratowe lub znak dolara. Na przykład,

blist [[2]]

zwróci drugi obiekt z listy blist, a blist $b1 zwróci obiekt w blist o nazwie b1. Dostęp do obiektów na liście można uzyskać tylko pojedynczo. Jeśli lista jest tworzona z obiektów, które nie mają nazw powiązanych z obiektami, nazwy będą nadawane obiektom podczas tworzenia listy. Nazwiska można zmienić w dowolnym momencie.

Ramki danych są specjalnym rodzajem listy. Ramki danych mają taką samą liczbę elementów dla każdego obiektu na liście i są zdefiniowane jako data.frames. Ramki danych mogą być podzestawione jak macierz lub lista. Jeśli podzbiór jest podobny do macierzy, wynikowy obiekt będzie listą. Jeśli zostanie podzielony jak lista, wynikowy obiekt będzie surowy, złożony, numeryczny, logiczny lub znakowy, w zależności od tego, czy obiekt listy jest surowy, złożony, numeryczny, logiczny lub znakowy. Dostęp do poszczególnych komórek w ramce danych można uzyskać za pomocą wskaźników w podwójnych nawiasach kwadratowych. Na przykład,

adframe [[1,2]]

zwróci element w pierwszym wierszu i drugiej kolumnie listy adframe. Wiele funkcji zwraca dane wyjściowe w postaci list. Aby uzyskać dostęp do danych wyjściowych, zwykle stosuje się indeksowanie dolara, chociaż można stosować indeksowanie w nawiasach kwadratowych. Na przykład dla funkcji modelu liniowego lm() wprowadzanie

lm(y ~ x) $ resid

lub

lm(y ~ x) [[2]]

zwróci reszty z prostej regresji liniowej y na x, podobnie jak dwa zestawy instrukcji

a = lm(y ~ x)

a$resid

lub

a = lm (y ~ x)

a [[2]].

Inne rodzaje

Dwa inne typy obiektów mogą być podzielone na czynniki i szczeliny. Obiekty, które są czynnikami, są wektorami i mogą być dzielone jak wektory. Szczeliny są nowszym typem obiektu i są dzielone za pomocą @. Więcej informacji o podzestawie obu można znaleźć, wpisując ??„Extract or Replace” w wierszu polecenia R.

Analiza wykresów społecznościowych

Analiza sieci społecznościowych

Sieci społecznościowe są wszędzie. Według Wikipedii istnieje ponad 200 aktywnych serwisów społecznościowych w Internecie, z wyłączeniem witryn randkowych. Jest to całkowicie uzasadnione: pragnienie interakcji społecznej jest fundamentalną częścią ludzkiej natury i nie powinno dziwić, że ta wrodzona natura społeczna przejawi się w naszych technologiach. Ale mapowanie i modelowanie sieci społecznościowych nie jest bynajmniej wiadomością. W społeczności matematyki przykładem analizy sieci społecznościowych w pracy jest obliczenie liczby Erdősa danej osoby, która mierzy jej odległość od płodnego matematyka Paula Erdősa. Erdős był prawdopodobnie najbardziej płodnym matematykiem XX wieku i opublikował ponad 1500 artykułów podczas swojej kariery. Wiele z tych artykułów miało współautorów a liczby Erdősa mierzą odległość matematyka od kręgu autorów, których Erdős przyciągnął. Gdyby matematyk współpracował z Erdősem na papierze, miałaby liczbę Erdősa równą jeden, tzn. jego odległość do Erdősa w sieci matematyki XX wieku wynosi jeden. Jeśli inny autor współpracowałby z jednym ze współautorów Erdősa, ale nie bezpośrednio z Erdősem, wówczas autor ten miałby liczbę Erdősa równą dwa itd. Metryka ta była używana, choć rzadko poważnie, jako przybliżona miara znaczenia osoby w matematyce. Liczby Erdősa pozwalają nam szybko podsumować ogromną sieć matematyków krążących wokół Paula Erdősa. Erving Goffman, jeden z najwybitniejszych intelektualistów XX wieku i bardzo podobny do Paula Erdősa w naukach społecznych, oparty na ogromnej skali jego wykładów, zapewnia jedno z najlepszych stwierdzeń na temat natury interakcji międzyludzkich:

Kiedy osoby są wobec siebie obecne, mogą funkcjonować nie tylko jako narzędzia fizyczne, ale także jako narzędzia komunikacyjne. Ta możliwość, nie mniej niż fizyczna, jest fatalna dla wszystkich zainteresowanych, a w każdym społeczeństwie wydaje się podlegać ścisłym normatywnym regulacjom, co prowadzi do pewnego rodzaju porządku ruchu komunikacyjnego. —Erving Goffman, z Zachowania w miejscach publicznych: notatki na temat społecznej organizacji spotkań (1966)

„Kolejność ruchu”, o której mówił Goffman, to dokładnie sieć społecznościowa. Produktem ubocznym naszego pragnienia interakcji i kontaktów towarzyskich są wysoce ustrukturyzowane wykresy, które stanowią swoistą „mapę” naszej tożsamości i historii. Serwisy społecznościowe, takie jak Facebook, Twitter i LinkedIn, po prostu zapewniają wysoce stylizowane szablony do angażowania się w to bardzo naturalne zachowanie. Innowacja tych usług nie polega na ich funkcji, ale raczej na sposobie, w jaki zapewniają wgląd w społeczną kartografię bardzo dużej części ludzkości. Dla hakerów takich jak my dane, które ujawniają serwisy społecznościowe, są prawdziwym gejzerem niesamowitości. Ale wartość wykresów społecznościowych wykracza poza serwisy społecznościowe. Istnieje kilka rodzajów relacji, które można modelować jako sieć, a wiele z nich jest również przechwytywanych przez różne usługi internetowe. Na przykład możemy zmapować relacje między widzami na podstawie filmów oglądanych w serwisie Netflix. Podobnie możemy pokazać, jak różne gatunki muzyczne są ze sobą powiązane w oparciu o wzorce słuchaczy korzystających z usług takich jak Last.fm lub Spotify. W bardziej podstawowy sposób możemy również modelować strukturę lokalnej sieci komputerowej – a nawet całego Internetu – jako ogromną serię węzłów i krawędzi. Chociaż badanie sieci społecznościowych jest obecnie bardzo popularne, w dużej mierze ze względu na rozprzestrzenianie się portali społecznościowych, tak zwana „analiza sieci społecznościowych” to zestaw narzędzi, które były używane i rozwijane w ciągu ostatnich kilku dekad. U podstaw badania sieci opiera się na języku teorii grafów w celu opisania połączonych obiektów. Już w 1736 roku Leonhard Euler wykorzystał koncepcję węzłów i krawędzi do sformalizowania problemu mostu w Królewcu

Problem z mostem Königsberg jest wczesnym wariantem podróżnego problem sprzedawcy, w którym musisz obmyślić ścieżkę przez miasto Królewiec w Prusach (obecnie Kaliningrad, Rosja), przemierzając każdy z siedmiu mostów dokładnie raz. Euler rozwiązał problem, przekształcając mapę miasta w prosty wykres z czterema węzłami (sekcje miasta) i siedem krawędzi (mosty).

W latach dwudziestych XX wieku słynny psycholog Jacob L. Moreno opracował metodę badania relacji międzyludzkich zwaną „socjometrią”. Moreno był zainteresowany tym, jak interakcje społeczne ludzi wpłynęły na ich samopoczucie, więc zapytał ludzi, kim są ich przyjaciele, i zaczął mapować tę strukturę. W 1937 r. Antropolog Joan Criswell zastosował metody socjometryczne Moreno do zbadania podziałów rasowych między czarnymi i białymi dziećmi ze szkoły podstawowej. Większość tego, co uważamy za współczesną analizę sieci społecznościowych, stanowi konglomerat teorii i metod z szerokiego zakresu dyscyplin. Pochodzi duża część od socjologii, w tym wybitnych uczonych, takich jak Linton Freeman, Harrison White, Mark Granovetter i wielu innych. Podobnie wiele wkładów pochodzi również z fizyki, ekonomii, informatyki, nauk politycznych, psychologii oraz niezliczonych innych dyscyplin i uczonych. Istnieje o wiele za dużo autorów i cytatów, aby je tutaj wymienić, a napisano tomy, które dokonują przeglądu metod w tym dużym obszarze badań. W tym krótkim wstępie do analizy sieci społecznościowych omówimy tylko niewielką część tego tematu.

To powiedziawszy, co omówimy? Skupimy  się na studium przypadku w sieciach społecznościowych, które prowadzi nas przez cały cykl hakowania danych w celu pozyskiwania danych z sieci społecznościowych, ich czyszczenia i strukturyzacji, a na końcu ich analizy. W tym przypadku skupimy się na najważniejszej „otwartej” sieci społecznościowej dnia: Twitterze. Słowo „otwarte” jest przerażające, ponieważ Twitter nie jest tak naprawdę otwarty w tym sensie, że możemy swobodnie uzyskiwać dostęp do wszystkich jego danych. Podobnie jak wiele serwisów społecznościowych, posiada interfejs API z surowym limitem stawek. Z tego powodu zbudujemy system do wyodrębniania danych z Twittera bez naruszania tego limitu prędkości i bez naruszania warunków usługi Twittera. W rzeczywistości nigdy nie uzyskamy bezpośredniego dostępu do interfejsu API Twittera. Nasz projekt zaczyna się od zbudowania sieci lokalnej lub sieci ego i stamtąd ścieżkami w taki sam sposób, jak obliczana jest liczba Erdősa. W naszej pierwszej analizie zbadamy metody wykrywania społeczności, które próbują podzielić sieci społecznościowe na spójne podgrupy. W kontekście Twittera może to dostarczyć nam informacji o różnych grupach społecznych, do których należy dany użytkownik. Wreszcie, ponieważ ten tekst dotyczy uczenia maszynowego, zbudujemy własny silnik rekomendacji „kto podąża” przy użyciu struktury wykresu społecznościowego Twittera. Postaramy się unikać używania żargonu lub niszowych terminów akademickich do opisywania tego, co tutaj robimy. Istnieje jednak kilka terminów, które warto stosować i nauczyć się. Właśnie wprowadziliśmy termin ego-sieć, aby opisać rodzaj wykresu. Ponieważ wiele razy będziemy odnosić się do ego-sieci, przydatne będzie zdefiniowanie tego terminu. Sieć ego zawsze odnosi się do wykresu struktury społeczności  natychmiast otaczającej pojedynczy węzeł w sieci. W szczególności ego-sieć jest podzbiorem sieci indukowanej przez ziarno (lub ego) i jego sąsiadów, tj. Te węzły bezpośrednio połączone z ziarnem. Innymi słowy, sieć ego dla danego węzła obejmuje sąsiadów tego węzła, połączenia między nasionem a tymi sąsiadami i powiązania między sąsiadami.

(I) : Macierze i Tablice

Macierze

W przypadku macierzy stosuje się oba rodzaje nawiasów kwadratowych. W przypadku pojedynczych nawiasów kwadratowych instrukcje wyboru wierszy są oddzielone od instrukcji wyboru kolumn przecinkiem. Podobnie jak podzestaw dla wektorów, dla pojedynczych nawiasów kwadratowych, indeksy lub wyrażenie logiczne mogą być użyte do podzestawu macierzy. Aby odwołać się do wszystkich wierszy macierzy, nie umieszczaj nic po lewej stronie przecinka w nawiasach. Aby odwołać się do wszystkich kolumn macierzy, nie umieszczaj nic po prawej stronie przecinka w nawiasach. Podwójne nawiasy kwadratowe zwracają tylko jedną wartość. Jeśli podzbiór jest wierszem i indeksem kolumny oddzielonym przecinkiem, zwracana jest wartość w komórce. Jeśli w podwójnych nawiasach kwadratowych zostanie wprowadzona tylko jedna wartość indeksu, R traktuje macierz jako wektor idący w dół wierszy i zwraca indeksowany element wektora. Przykładem indeksowania macierzy jest

a [a [, 1]> 3, 1: 4],

gdzie a jest macierzą z co najmniej czterema kolumnami. Wyrażenie zwróci te wiersze pierwszych czterech kolumn, dla których elementy pierwszej kolumny są większe niż trzy. Zauważ, że a [, 1] składa się z jednej kolumny i zawiera wszystkie wiersze. Macierz można również podzielić na części za pomocą macierzy z dwiema kolumnami. Macierz dwukolumnowa zawierałaby indeksy wierszy i kolumn i wybrałaby poszczególne komórki w macierzy na podstawie wskaźników w każdym rzędzie. Na przykład, jeśli b jest macierzą z [1 2] w pierwszym rzędzie i [2 3] w drugim rzędzie, wtedy [b] zwróci dwa elementy a [1,2] i a [2,3] .

Tablice

Tablice są jak macierze, ale mogą mieć więcej niż dwa wymiary. Zauważ, że macierz to tablica o dwóch wymiarach, a wektor to tablica o jednym wymiarze. Indeksowane tablice o więcej niż dwóch wymiarach są podobne do indeksowanej macierzy, z tym wyjątkiem, że w nawiasach kwadratowych jest więcej przecinków w nawiasach. Przykładem jest

a [1: 3, 2: 7],

gdzie a jest trójwymiarową tablicą z co najmniej trzema poziomami w pierwszym wymiarze i co najmniej siedmioma poziomami w trzecim wymiarze. Wynikiem podzbioru byłyby wszystkie elementy w drugim wymiarze, dla których indeks w pierwszym wymiarze wynosi jeden, dwa lub trzy, a wskaźniki w trzecim wymiarze wynoszą od dwóch do siedmiu włącznie. Podobnie jak macierze, tablice mogą być podzestawione za pomocą macierzy, która ma taką samą liczbę kolumn, jak liczba wymiarów tablicy, której rzędy składałyby się z indeksów dla poszczególnych komórek tablicy