åã®
èšäºã§ã¯ãVKontakteã®äžè¬çãªå人ã«åºã¥ããŠã°ã©ããäœæããŸãããä»æ¥ã¯ãå人ãå人ã®å人ãªã©ã®ãªã¹ããååŸããæ¹æ³ã«ã€ããŠèª¬æããŸãã åã®
èšäºããã§ã«èªãã§ããããšãåæãšããŠããã®ã§ãããäžåºŠèª¬æããŸããã habrakatã®äžã«ã¯ã倧ããªåçãšããããã®ããã¹ãããããŸãã
ãŸãããã¹ãŠã®ãŠãŒã¶ãŒIDãããŠã³ããŒãããã®ã¯éåžžã«ç°¡åã§ããæå¹ãªIDã®ãªã¹ãã¯
VKontakteãŠãŒã¶ãŒãã£ã¬ã¯ããªã«ãããŸãã ç§ãã¡ã®ã¿ã¹ã¯ã¯ãæå®ãããæ·±ãã«å¿ããŠãéžæããããŠãŒã¶ãŒIDã®å人ãšãã®å人ã®ãªã¹ããååž°çã«ä»»æã®æ·±ãã§ååŸããããšã§ãã
ãã®èšäºã§å
¬éãããŠããã³ãŒãã¯æéãšãšãã«å€åããããã
Githubã®åããããžã§ã¯ãã§ææ°ããŒãžã§ã³ãèŠã€ããããšãã§ããŸãã
å®è£
æ¹æ³ïŒ
- å¿
èŠãªæ·±ããèšå®ããŸã
- ãœãŒã¹ããŒã¿ãŸãã¯ç¹å®ã®æ·±ãã§æ¢çŽ¢ããå¿
èŠãããIDãéä¿¡ããŸã
- çããåŸã
䜿çšãããã®ïŒ
- Python 3.4
- VKã®ã¹ãã¢ãããã·ãŒãžã£
å¿
èŠãªæ·±ããèšå®ããŸã
æåã«å¿
èŠãªã®ã¯ãäœæ¥ã®æ·±ãã瀺ãããšã§ãã
settings.pyã§ããã«ãããè¡ãããšãã§ã
ãŸã ïŒ
deep = 2
æ·±ã 1ã«çããç§ãã¡ã®å人ã2ã¯ç§ãã¡ã®å人ã®å人ãªã©ã§ãã ãã®çµæãããŒããŠãŒã¶ãŒIDã§ãå€ãå人ã®ãªã¹ãã§ããèŸæžãååŸããŸãã
æ¥ãã§å€§ããªæ·±åºŠãèšå®ããªãã§ãã ããã ç§ã®å
ã®å人ã14人ãæ·±ãã2ã®å ŽåãèŸæžã®ããŒã®æ°ã¯2427ã§ãããæ·±ãã3ã®å Žåãã¹ã¯ãªããã®åäœãå®äºããã®ãåŸ
ã€å¿èããããŸããã§ããããã®æç¹ã§èŸæžã¯223,908ã®ããŒãã«ãŠã³ãããŸããã ãã®ãããé ç¹ãããŒã«ãªãããšããžãå€ã«ãªãããããã®ãããªå·šå€§ãªã°ã©ãã¯èŠèŠåããŸããã
ããŒã¿ãéä¿¡ãã
å¿
èŠãªçµæãåŸãã«ã¯ãæ¢ç¥ã®
friends.getã¡ãœããã
圹ç«ã¡ãŸããããã¯ã次ã®åœ¢åŒã®ã¹ãã¢ãããã·ãŒãžã£ã«é
眮ãããŸãã
var targets = Args.targets; var all_friends = {}; var req; var parametr = ""; var start = 0;
ã¹ãã¢ãããã·ãŒãžã£
ã¯ã¢ããªã±ãŒã·ã§ã³èšå®ã§äœæã§ãã
å®è¡ã®ããã«
VkScriptã§èšè¿°ãããããã¥ã¡ã³ãã¯
ãããš
ããã§èªãããšãã§ã
ãŸã ã
次ã«ããã®ä»çµã¿ã«ã€ããŠèª¬æããŸãã ã«ã³ãã§åºåããã25ã®IDã®æååãååŸãã1ã€ã®IDãååŸããŠ
friends.getã«ãªã¯ãšã¹ããéä¿¡ãããšãå¿
èŠãªæ
å ±ãèŸæžã«æ ŒçŽãããŸããããŒã¯idã§ãå€ã¯ãã®idã®ãã¬ã³ããªã¹ãã§ãã
æåã®èµ·åæã«ãã¹ãã¢ãããã·ãŒãžã£ã«çŸåšã®ãŠãŒã¶ãŒã®å人ã®ãªã¹ããéä¿¡ããŸãããã®ãŠãŒã¶ãŒã®IDã¯èšå®ã§æå®ãããŠããŸãã ãªã¹ãã¯ããã€ãã®éšåã«åå²ãããŸãïŒN / 25ã¯ãªã¯ãšã¹ãã®æ°ã§ãïŒãããã¯ãVKontakte APIã®åŒã³åºãæ°ã®å¶éã«ãããã®ã§ãã
å¿çãåãåã
åä¿¡ãããã¹ãŠã®æ
å ±ã¯ãããšãã°æ¬¡ã®ãããªèŸæžã«ä¿åãããŸãã
{1:(0, 2, 3, 4), 2: (0, 1, 3, 4), 3: (0, 1, 2)}
ããŒ1ã2ãããã³3ã¯ãæ·±ã1ã§ååŸãããŸããããããã¯ãã¹ãŠãæå®ããããŠãŒã¶ãŒïŒ0ïŒã®åéã§ãããšæ³å®ããŸãã
æ·±ãã1ãã倧ããå Žåãã»ããã®å·®ã䜿çšããŸããæåã®ã»ããã¯èŸæžã®å€ã§ã2çªç®ã®ã»ããã¯ããŒã§ãã ãããã£ãŠãããŒã«ãªãIDïŒãã®å Žåã¯0ãš4ïŒãååŸããããããåã³25ã®éšåã«åå²ããŠãã¹ãã¢ãããã·ãŒãžã£ã«éä¿¡ããŸãã
ãã®åŸã2ã€ã®æ°ããããŒãèŸæžã«è¡šç€ºãããŸãã
{1:(0, 2, 3, 4), 2: (0, 1, 3, 4), 3: (0, 1, 2), 0: (1, 2, 3), 4:(1, 2, âŠ.)}
deep_friendsïŒïŒã¡ãœãã
èªäœã¯æ¬¡ã®ããã«ãªããŸãã
def deep_friends(self, deep): result = {} def fill_result(friends): for i in VkFriends.parts(friends): r = requests.get(self.request_url('execute.deepFriends', 'targets=%s' % VkFriends.make_targets(i))).json()['response'] for x, id in enumerate(i): result[id] = tuple(r[x]["items"]) if r[x] else None for i in range(deep): if result:
ãã¡ãããããã¯ãã¹ãã¢ãããã·ãŒãžã£ã䜿çšããã«
friends.get oneã§1ã€ã®idãã¹ããŒãããããé«éã§ãããããã§ãå€ãã®æéãããããŸãã
friends.getãusers.getã«äŒŒãŠãã
å Žå ãã€ãŸãã
user_idsããã©ã¡ãŒã¿ãŒãšããŠäœ¿çšã§ããŸããã€ãŸããidã1ã€ã ãã§ã¯ãªããåéã®ãªã¹ããè¿ãå¿
èŠãããã³ã³ãã§åºåãããidã䜿çšã§ããŸããèŠæ±ã®æ°ã¯äœåãå°ãªãã£ãã
é
ããã
èšäºã®æåã«æ»ã£ãŠãç¹°ãè¿ããŸãããéåžžã«ãã£ããã§ãã ã¹ãã¢ãããã·ãŒãžã£ã¯ä¿åãããŸãã
ãalxpyãã«ãã¹ã¬ãããœãªã¥ãŒã·ã§ã³ïŒåœŒã®è²¢ç®ãšåå ã«æè¬
ããŸããå°ãªããšãç§ä»¥å€ã®èª°ããèå³ãæã£ãŠããŸãã ïŒãããã°ã©ã ãæ°ç§éå éããŸãããããã£ãšæ¬²ããã£ãã§ãã
igrishaevããè³¢æãªã¢ããã€ã¹ãåã
ãŸãã -äœããã®ããããªãã¥ãŒãµãŒãå¿
èŠã§ãã
å®éãVKontakteã¯
executeãä»ããŠ25ã®APIãªã¯ãšã¹ããèš±å¯ããŠãã
ãã ãç°ãªãã¯ã©ã€ã¢ã³ããããªã¯ãšã¹ããè¡ãå Žåãæå¹ãªãªã¯ãšã¹ãã®æ°ãå¢ããããšãã§ããŸãã 5å°ã®ææŒãè»-ããã¯1ç§ããã125ãªã¯ãšã¹ãã§ãã ããããããã¯ããã§ã¯ãããŸããã å°æ¥ãèŠæ®ããŠãããã¯å¯èœã§ãããããã«é«éã§ãããšèšããŸããïŒåãã·ã³ã§ïŒæ¬¡ã®ããã«ãªããŸãã
while True: r = requests.get(request_url('execute.getMutual','source=%s&targets=%s' % (my_id, make_targets(lst)),access_token=True)).json() if 'response' in r: r = r["response"] break else: time.sleep(delay)
ãšã©ãŒã¡ãã»ãŒãžãåãåã£ãå Žåã¯ãæå®ãããç§æ°åŸã«å床ãªã¯ãšã¹ããè¡ããŸãã ãã®ææ³ã¯ãã°ããã¯æ©èœããŸãããVKontakteã¯ãã¹ãŠã®å¿çã§
Noneã®éä¿¡ãéå§ãããããåãªã¯ãšã¹ãã®åŸã«æ£çŽã«1ç§åŸ
æ©ããŸãã ãããŸã§ã
次ã«ãæ°ããããŒã«ãéžæããããç¬èªã®èšç»ãäœæããŠèšç»ãå®è¡ããå¿
èŠããããŸãã ãã®çµæãæ°Žå¹³æ¹åã«ã¹ã±ãŒã©ãã«ãªã·ã¹ãã ãååŸããå¿
èŠããããŸããä»äºã®åçã¯æ¬¡ã®ããã«æããŸãã
- ã¡ã€ã³ãµãŒããŒã¯ãã¯ã©ã€ã¢ã³ãããVKontakte IDãšãªãã¬ãŒã·ã§ã³ã³ãŒããåãåããŸãããã¹ãŠã®äžè¬çãªå人ãåŒãåºãããæå®ãããæ·±ãã®å人ã®ãªã¹ããååž°çã«èª¿ã¹ãŸãã
- ããã«ãã©ã¡ãã®å Žåã§ãããµãŒããŒã¯VKontakte APIã«ãªã¯ãšã¹ããéä¿¡ããŸãããŠãŒã¶ãŒã®ãã¹ãŠã®åéã®ãªã¹ããå¿
èŠã§ãã
- ã¹ãã¢ãããã·ãŒãžã£ã®æ©èœãæ倧éã«æŽ»çšããããã«ãã¹ãŠãå®äºããŠãããããããã§ã¯ãå人ã®ãªã¹ãããããã25ã®é£çµ¡å
ã«åå²ããå¿
èŠããããŸãã å®éã75ãããã«ã€ããŠã¯å°ãäœãã
- ã¡ãã»ãŒãžãããŒã«ãŒã䜿çšããŠå€ãã®ããŒããååŸããåããŒããç¹å®ã®åä¿¡è
ïŒãããã¥ãŒãµãŒ-ã³ã³ã·ã¥ãŒãïŒã«é
ä¿¡ããŸãã
- åä¿¡è
ã¯é£çµ¡å
ãåãå
¥ããããã«èŠæ±ãè¡ããçµæããµãã©ã€ã€ãŒã«è¿ããŸãã ã¯ããRPCã«ã€ããŠæ£ããèããŸããã
ãããŠãããªãããã®çµµãèŠããªããããªãã¯ç§ãã»ã®ããããŠããã¡ãã»ãŒãžãããŒã«ãŒãç解ããŸãã
ãã¹ãŠã®åçãåãå
¥ãããããšããããã1ã€ã«ãŸãšããŸãã ããã«ãçµæãç»é¢ã«è¡šç€ºããããå®å
šã«ä¿åããããšãã§ããŸãã詳现ã«ã€ããŠã¯ãåŸã§èª¬æããŸãã
ã³ãŒããå€æŽãããããšã¯æ³šç®ã«å€ããŸãããããžã§ã¯ãã®åã®ããŒãžã§ã³ã䜿çšããå¿
èŠãããå Žåã¯ãå€æŽãããŸããã§ããã 以äžã®ã³ãŒãã¯ãã¹ãŠãæ°ãããªãªãŒã¹çšã§ãã
RabbitMQãã¡ãã»ãŒãžãããŒã«ãŒã
Celery ãéåæåæ£ã¿ã¹ã¯
ãã¥ãŒãšããŠäœ¿çšã
ãŸã ã
ãããã«ééããããšããªã人ã®ããã«ãç§ã¯ããªããèªãããšããå§ãããè³æãžã®ããã€ãã®æçšãªãªã³ã¯ããããŸãïŒ
ç解ããããšãæããªãã§ãã ãããã1å°ã®ã³ã³ãã¥ãŒã¿ãŒã§ã¯ãªããè€æ°ã®ã³ã³ãã¥ãŒã¿ãŒã§èããããšãã«é ãåãããšãã§ãããšèšãããŠããŸãããããã§ã¯ãããŸããã
èè
ãªã©ã®Macã䜿çšããŠããå Žåã
RabbitMQ㯠Homebrewã䜿çšããŠã¹ããŒãã«ã€ã³ã¹ããŒã«ãããŸãã
brew update brew install rabbitmq
3çªç®ã®
Pythonãã©ã³ãã䜿çšãããšã
Celeryã¯ããã«ç°¡åã«ãªããŸãã
pip3 install Celery
Linux Mintã«
Celeryã ãMacã«
RabbitMQãã€ã³ã¹ããŒã«ããŠããŸãã Windowsã§ã¯ããã€ãã®ããã«ãåé¡
ãèŠã€ããã®ã¯
é£ããã倱ãã®ã¯
ç°¡åã§ããäœããã®çç±ã§ã圌女ã¯ç§ã®Macã«å¿çãè¿ããããããŸããã§ããã
次ã«ã
ä»®æ³ãã¹ããäœæãããŠãŒã¶ãŒã«æš©éãä»äžããŸãã
rabbitmqctl add_vhost vk_friends rabbitmqctl add_user user password rabbitmqctl set_permissions -p vk_friends user ".*" ".*" ".*"
RabbitMQæ§æã§ã¯ãã€ã³ã¹ããŒã«å
ã®ãã¹ãã®IPãæå®ããå¿
èŠããããŸãã
vim /usr/local/etc/rabbitmq/rabbitmq-env.conf NODE_IP_ADDRESS=192.168.1.14 //
ããã«ããã€ãã®å¯èœãªæ§æããããŸãããã©ããéžæããã-ããªãã決ããŸãã
ã«ãŒã¿ãŒãªã©ãããå Žåã¯ã
RabbitMQã5672ããŒãã䜿çšããŠããããšãç¥ã£ãŠãããšãããã€ã¹ã®èšå®ããªãã€ã¬ã¯ãã§ããŸãã ã»ãšãã©ã®å Žåããã¹ããããšãç°ãªããã·ã³ã«ã¯ãŒã«ãŒãåæ£ãããããŒã«ãŒã䜿çšããå¿
èŠããããŸãããããã¯ãŒã¯ãæ£ããã»ããã¢ããããªããšã
Celery㯠RabbitMQã«å°éã
ãŸãã ã
éåžžã«è¯ããã¥ãŒã¹ã¯ãVKontakteã䜿çšãããšã1ã€ã®IDãã1ç§ããã3ã€ã®ãªã¯ãšã¹ããäœæã§ããããšã§ãã ãããã®ãªã¯ãšã¹ãã«VKontakte APIã®å¯èœãªåŒã³åºãæ°ïŒ25ïŒãæãããšã1ç§ãããã®åŠçæžã¿é£çµ¡å
ã®æ倧æ°ïŒ75ïŒãåŸãããŸãã
å€ãã®åŽåè
ãããå Žåã蚱容é床ãè¶
ããŠç§»åãå§ãããšããæ¥ãŸãã ãããã£ãŠã
ããŒã¯ã³å€æ°ïŒ
settings.pyå
ïŒã¯ãç°ãªãIDãæã€è€æ°ã®ããŒã¯ã³ãå«ãã¿ãã«ã«ãªã
ãŸã ã ã¹ã¯ãªããã¯ãVKontakte APIãžã®åãªã¯ãšã¹ãã§ãã©ã³ãã ã«ãããã®ãããããéžæããŸãã
def request_url(method_name, parameters, access_token=False): """read https://vk.com/dev/api_requests""" req_url = 'https://api.vk.com/method/{method_name}?{parameters}&v={api_v}'.format( method_name=method_name, api_v=api_v, parameters=parameters) if access_token: req_url = '{}&access_token={token}'.format(req_url, token=random.choice(token)) return req_url
ãã®ç¹ã§ãVKontakteã«è€æ°ã®ã¢ã«ãŠã³ããæã£ãŠããå ŽåïŒå人ã家æã«è² æ
ããããããšãã§ããŸãïŒã4ããŒã¯ã³ãš3ã¯ãŒã«ãŒã§åé¡ã¯ãããŸããã§ããã
ãããã
time.sleepïŒïŒ ããŸãã¯
whileã䜿çšããäžèšã®äŸã䜿çšããããšã誰ãæ°ã«ããŸãããããšã©ãŒã¡ãã»ãŒãžãåä¿¡ããæºåãããŸãïŒéåžžã¯ç©ºã®åçãå¯èœã§ã
-id ïŒNoneïŒããŸãã¯ãã£ãšé·ãåŸ
ã¡ãŸãã
call.pyãã¡ã€ã«ããæãèå³æ·±ããã®ïŒ
def getMutual(): all_friends = friends(my_id) c_friends = group(mutual_friends.s(i) for i in parts(list(all_friends[0].keys()), 75))().get() result = {k: v for d in c_friends for k, v in d.items()} return cleaner(result) def getDeep(): result = {} for i in range(deep): if result:
ã芧ã®ãšããã2ã€ã®é¢æ°ã§
groupsïŒïŒã䜿çšããŸããããã¯ããã€ãã®ã¿ã¹ã¯ãåæã«å®è¡ãããã®åŸãçãããæ¥çãããŸãã
deep_friendsïŒïŒãæåãã©ã®ããã«èŠãŠãããèŠããŠããŸã
ïŒéåžžã«å€ãäŸããããŸã-ãã«ãã¹ã¬ããããªããŠãïŒã æå³ã¯åããŸãŸã§ã-ã»ããã®éãã䜿çšããŸãã
ãããŠæåŸã«ã
tasks.py ã ãã€ããããã®çŽ æŽãããæ©èœã¯äžã€ã«çµ±åãããŸãïŒ
@app.task def mutual_friends(lst): """ read https://vk.com/dev/friends.getMutual and read https://vk.com/dev/execute """ result = {} for i in list(parts(lst, 25)): r = requests.get(request_url('execute.getMutual', 'source=%s&targets=%s' % (my_id, make_targets(i)), access_token=True)).json()['response'] for x, vk_id in enumerate(i): result[vk_id] = tuple(i for i in r[x]) if r[x] else None return result @app.task def deep_friends(friends): result = {} for i in list(parts(friends, 25)): r = requests.get(request_url('execute.deepFriends', 'targets=%s' % make_targets(i), access_token=True)).json()["response"] for x, vk_id in enumerate(i): result[vk_id] = tuple(r[x]["items"]) if r[x] else None return result
ãã¹ãŠãèšå®ãããã
ã次ã®ã³ãã³ãã§
RabbitMQãå®è¡ããŸãã
rabbitmq-server
次ã«ããããžã§ã¯ããã©ã«ããŒã«ç§»åããã¯ãŒã«ãŒãã¢ã¯ãã£ãã«ããŸãã
celery -A tasks worker --loglevel=info
ããŠãäžè¬çãªãŸãã¯ãæ·±ããåéã®ãªã¹ããååŸããŠä¿åããã«ã¯ãã³ã³ãœãŒã«ã§ã³ãã³ããå®è¡ããã ãã§ãïŒ
python3 call.py
枬å®çµæã«ã€ããŠ
æåã®ããŒãã§ç§ã«ã€ã³ã¹ãã¬ãŒã·ã§ã³ãäžãã
èšäºã®èè
ã§ãã
343人ã®å人 ïŒå
±éã®å人ãžã®ãªã¯ãšã¹ãïŒã¯
119ç§ã§ãåŠçããããããšãæãåºãããŠãã ããã
åã®èšäºããã®ç§ã®ããŒãžã§ã³ã¯
9ç§ã§åãããšãããŸããã
äœæè
ã®å人ã®æ°ã¯308ã«ãªããŸãããæåŸã®8ã€ã®IDã«å¯ŸããŠè¿œå ã®èŠæ±ã1ã€è¡ãã貎éãª1ç§ãè²»ããå¿
èŠããããŸãããåã1ç§ã§75 IDãåŠçã§ããŸãã
ã¯ãŒã«ãŒã1人ã®å Žåãã¹ã¯ãªããã«ã¯
4.2ç§ããã ãã¯ãŒã«ãŒã¯2人
-2.2ç§ããããŸãã ã
119ã120ã«äžžãããã2.2ã2ã«äžžãããããšãç§ã®ãªãã·ã§ã³ã¯
60åéããªããŸãã
ãæ·±ãåéãïŒç§ã®åéã®åéãªã©+åŸ
æ©æéãæžããããã«å¥ã®IDã§ãã¹ãããïŒã«ã€ããŠã¯ãæ·±ã2ã§ãèŸæžã®ããŒã®æ°ã¯1,251ã§ããã
èšäºã®åé ã«èšèŒãããŠããã³ãŒãã®å®è¡æéã¯
17.9ç§ã§ãã
ã¯ãŒã«ãŒã1人ã®å Žåãã¹ã¯ãªããã®å®è¡æéã¯
15.1ç§ã§ ãã¯ãŒã«ãŒã¯
8.2ç§ã§ãã
ãããã£ãŠã
deep_friendsïŒïŒã¯çŽ
2.18åé«éã«ãªã
ãŸãã ã
ã¯ããçµæã¯å¿
ãããããã»ã©ãã©è²ã§ã¯ãããŸãã.VKontakteã§ã®1ã€ã®èŠæ±ã«å¯Ÿããåçã¯ã10ç§ãš20ç§åŸ
æ©ããå¿
èŠãããå ŽåããããŸãïŒãã ãã1ã€ã®ã¿ã¹ã¯ã®é »ç¹ãªå®è¡æéã¯1.2-1.6
ç§ã§ã ïŒãããã¯ããããããµãŒãã¹ã®è² è·ã«ãããã®ã§ããå®å®ã ãã§ã¯ãããŸããã
çµæãšããŠãããå€ãã®ã¯ãŒã«ãŒãå®è¡ããã°ããã»ã©ãçµæã¯ããéãåŠçãããŸãã ããŒããŠã§ã¢ã®ãã¯ãŒãè¿œå ã®ããŒã¯ã³ããããã¯ãŒã¯ïŒããšãã°ãäœæè
ãiPhoneãã¢ã¯ã»ã¹ãã€ã³ããšããŠäœ¿çšãããšãã«ã¹ã¯ãªããã®å®è¡æéã倧å¹
ã«å»¶é·ããïŒãªã©ã®èŠçŽ ãå¿ããªãã§ãã ããã
çµæãä¿åãã
ã¯ããå€ãã®ã°ã©ãæåããŒã¿ããŒã¹ããããŸãã å°æ¥çã«ïŒãããŠãããªãå ŽåïŒãåŸãããçµæãåæããåæèªäœãŸã§ããããã©ããã«ä¿åããå¿
èŠãããå Žåã¯ããããã®çµæãã¡ã¢ãªã«ã¢ã³ããŒãããããã€ãã®ã¢ã¯ã·ã§ã³ãå®è¡ããå¿
èŠããããŸãã ãããžã§ã¯ããåæ¥çã§ããå Žåãã©ã®ãããªçš®é¡ã®subdã䜿çšããŠãæå³ããããŸãããããšãã°ãç¹å®ã®ãŠãŒã¶ãŒã®ã°ã©ããã©ããªããèå³ããããŸããã¯ããã°ã©ãæåã®ããŒã¿ããŒã¹ãããã§å¿
èŠã§ããããããŒã ã³ã³ãã£ã·ã§ã³ãã®åæã«åŸäºããããã
ãã¯ã«ã¹ã§ååã§ãã
èŸæžãä¿åããåã«ãå€ã
Noneã§ããããŒãåé€ããããšã¯è«ççã§ãã ãããã¯ãããã¯ãŸãã¯åé€ãããã¢ã«ãŠã³ãã§ãã ç°¡åã«èšãã°ããããã®idã¯ä»ã®èª°ããããããå人ã«æã£ãŠããã®ã§ãã°ã©ãã«ååšããŸãããèŸæžã®ããŒã®æ°ãç¯çŽããŸãïŒ
def cleaner(dct): return {k:v for k, v in dct.items() if v != None} def save_or_load(myfile, sv, smth=None): if sv and smth: pickle.dump(smth, open(myfile, "wb")) else: return pickle.load(open(myfile, "rb"))
ã芧ã®ãšãããçµæãã©ããã«ä¿åããå Žåã¯ãIDãå床åéããªãããã«ãã©ããã«çµæãããŒãããå¿
èŠããããŸãã
ã°ã©ãåæ
ããªãã®èªè»¢è»ãæžããªãããã«ãããªãããç¥ãããŠãã
networkxã䜿çšããŸããããã¯ããã¹ãŠã®
æ±ãä»äºãããŠãããŸãã
networkxã®è©³çŽ°ã«ã€ããŠã¯ããã®
èšäºã ã芧 ãã ãã ã
pip3 install networkx
ã°ã©ãã®åæãå§ããåã«ãã°ã©ããæããŸãã
networkxã«ã¯ããã®ããã«
matplotlibãå¿
èŠã§ãã
pip3 install matplotlib
次ã«ãã°ã©ãèªäœãäœæããå¿
èŠããããŸãã äžè¬çã«ã2ã€ã®æ¹æ³ããããŸãã
1ã€ç®ã¯ã倧éã®RAMãšæéãæ¶è²»ããŸãã
def adder(self, node): if node not in self.graph.nodes(): self.graph.add_node(node) self.graph = nx.Graph() for k, v in self.dct.items(): self.adder(k) for i in v: self.adder(i) self.graph.add_edge(k, i)
ãããŠãããã¯å¿ããçãæ®ã£ãèè
ã§ã¯ãããŸããã åæ§ã®äŸã
ãã©ã€ã¹å€§åŠã®
ããŒãžã®èŠåºãã
ãã£ã¯ã·ã§ããªã°ã©ãè¡šçŸãnetworkxã°ã©ãè¡šçŸã«å€æãã§æäŸãã
ãŠããŸã ã
def dict2nx(aDictGraph): """ Converts the given dictionary representation of a graph, aDictGraph, into a networkx DiGraph (directed graph) representation. aDictGraph is a dictionary that maps nodes to its neighbors (successors): {node:[nodes]} A DiGraph object is returned. """ g = nx.DiGraph() for node, neighbors in aDictGraph.items(): g.add_node(node)
ç§ã®èšèãèããŠãã ãããã°ã©ãã¯å€äžã«äœæãããŠããã®ã«ããã§ã«300,000ãè¶
ããããŒã¯ããã£ãã®ã§ãç§ã®å¿èã¯æã¡åããŸããã
ãã®å€§åŠããPythonã®Courseraã®ã³ãŒã¹ãåè¬ããŠããå Žåã¯ãç§ãèšã£ãŠããããšãç解ã§ããŸãã ãããŠãã³ãŒã¹ã®å
šå¡ã«ã人ã
ã¯ãã®ããã«æããããŠããªããšèšã£ããããŸããŸããã¯ããæåã°ã©ãã®äŸã瀺ãããŠããŸãããæ¬è³ªã¯åããŸãŸã§ã-æåã«ããŒãè¿œå ããŠé ç¹ã«ããé ç¹ã®å€ãäœæãã次ã«ã°ã©ãã«ãŸã ãªãå Žåã¯ãšããžã«æ¥ç¶ããŸãïŒç§ã®ããŒãžã§ã³ã§ã¯ïŒã
ãããŠã2çªç®ã®æ¹æ³ã¯ãã¹ãŠãæ°ç§ã§è¡ããŸãïŒ
self.graph = nx.from_dict_of_lists(self.dct)
ã³ãŒãã¯
graph.pyãã¡ã€ã«ã«ãããçžäºã®å人ã®ã°ã©ããæç»ããã«ã¯ããã®ã¹ã¯ãªãããå®è¡ãã
ã ã
VkGraphïŒïŒã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ã
ã©ããã«äœæããŠããããã®
draw_graphïŒïŒã¡ãœãããåŒã³åºããŸãã

ããã¯ãåèš306ã®ããŒã¯ãš2096ã®rib骚ãæã€ãå
±éã®å人ã®ã°ã©ãã§ãã æ®å¿µãªãããç§ã¯ãã¶ã€ããŒã«ãªã£ãããšã¯ãããŸããïŒã»ãšãã©ãã¹ãŠã®èšå®ãæšæºã§ãïŒããã°ã©ãã®ã¹ã¿ã€ã«ã¯ãã€ã§ããèªåçšãã«ããããšãã§ããŸãã 以äžã«ããã€ãã®ãªã³ã¯ã瀺ããŸãã
ãããŠãã¡ãœããèªäœã¯æ¬¡ã®ããã«ãªããŸãã
def draw_graph(self): plt.figure(figsize=(19,19), dpi=450,) nx.draw(self.graph, node_size=100, cmap=True) plt.savefig("%s graph.png" % datetime.now().strftime('%H:%M:%S %d-%m-%Y'))
ãã®çµæããããžã§ã¯ããã©ã«ããŒã«picture
date graph.pngã衚瀺ãããŸãã æ·±ãå人ã®ããã«ã°ã©ããæãããšã¯ãå§ãããŸããã
308人ã®å人ãš2ã®æ·±ãã§ãèŸæžã¯
145,000以äžã®ããŒã§ããããšãå€æããŸããã ããããå€ããããŸã-idãæã€ã¿ãã«ã¯ãå°ãããšã¯èããããŸããã
é·ãéãç§ã¯VKontakteã§æãç®ç«ããªãå人ã®ãããã£ãŒã«ãæ¢ããŠããŸããããããã§ããéèŠãªã®ã¯å人ãšå人ã§ãã æåã®10人ã®å人ïŒãã®ãã¡1人ã¯ãããã¯ãããèªåçã«åé€ãããŸãïŒãæšæºã®æ·±ãïŒ2ïŒã§ãèŸæžã«ã¯
1234ããŒãš
517 174 idïŒå€ããïŒããããŸããã çŽ
419人ã®å人ã1ã€ã®IDãæã£ãŠããŸãã ã¯ããããã«ã¯äžè¬çãªå人ãããŸããã°ã©ããäœæãããšãã«ããããç解ããŸãã
deep_friends = VkGraph(d_friends_dct) print(' :', deep_friends.graph.number_of_nodes()) print(' :', deep_friends.graph.number_of_edges())
æ»ããŸãïŒ
: 370341 : 512949
ãã®ãããªããã°ããŒã¿ãããã°ãããããè©ŠããŠã¿ããšããã§ãããã
Networkxã«ã¯ãã°ã©ãã«é©çšã§ãã
ã¢ã«ãŽãªãºã ã®éåžžã«å€§ããª
ãªã¹ãããããŸãã ãããã®
ããã€ããåæããŸãã
æ¥ç¶ã°ã©ã
ãŸããæ¥ç¶ãããã°ã©ãããããã©ãããå€æããŸãããã
print(' ?', nx.is_connected(deep_friends.graph))
æ¥ç¶ã°ã©ãã¯ãé ç¹ã®ãã¢ãã«ãŒãã§æ¥ç¶ãããŠããã°ã©ãã§ãã
ãšããã§ãæ·±ãã1ã®åãidã«ã¯ã1268ã®é ç¹ãš1329ã®ãšããžãå«ããã®ãããªçŸããã°ã©ãããããŸãã

æ奜家ãžã®è³ªåã å人ãšå人ã®ã°ã©ããååŸãããããäœããã®æ¹æ³ã§æ¥ç¶ããå¿
èŠããããŸãã æ¢åã®ããŒã¯ã«æ¥ç¶ãããŠããªãããŒã¯ãã©ããããšããªãçŸããããšã¯ããåŸãŸããã ãã ããå³åŽã«ã¯ãã©ã®é ç¹ã«ãæ¥ç¶ãããŠããªãé ç¹ã1ã€ãããŸãã ãªãã§ïŒ æåã«èããŠãã ãããçå®ãç¥ãããšã¯ãã£ãšé¢çœãã§ãããã
æ£è§£ãããç解ããŸãããã ãŸããå人ã®ãªã¹ããååŸããŸããIDXãããããšãããããŸãããã®ãããã°ã©ãã¯äžè²«æ§ããããŸããã 次ã«ããã®Xã®å人ã«ãªã¯ãšã¹ããè¡ããŸãïŒçµå±ã®ãšããïŒã Xããã¹ãŠã®å人ãé衚瀺ã«ããŠããå ŽåãèŸæžã«ãšã³ããªããããŸãã
{X:(), ...}
ã°ã©ããäœæããããšãæ£çŽã«é ç¹Xãè¿œå ããŸããããšããžã¯ãããŸããã ã¯ããçŽç²ã«çè«çã«ã¯ãé ç¹Xã«ã¯
settings.pyã§idãæå®ãããé ç¹ãæã€ãšããžãå¿
èŠã§ããã泚ææ·±ãèªãã§ãã ãã-èŸæžã«ãããã®ã ããè¿œå ããŸãã ãããã£ãŠãæ·±ãã2ã®å Žåãèšå®ã§æå®ãããèŸæžIDãååŸãããŸãã ãããŠãé ç¹Xã«ãšããžããããŸãã
ãã®ãããªç¶æ³ã¯çºçããªããšæ³å®ããŠããŸããã€ãŸããã»ãšãã©ã®å Žå
Trueã衚瀺ãã
ãŸã ã
çŽåŸãäžå¿ããã³ååŸ
ã°ã©ãã®
çŽåŸã¯ã 2ã€ã®é ç¹éã®æ倧è·é¢
ã§ããããšãæãåºããŠãã ããã
print(' :', nx.diameter(deep_friends.graph))
ã°ã©ãã®äžå¿ã¯ãé ç¹ããæãé ãé ç¹ãŸã§ã®è·é¢ãæå°ã«ãªããããªé ç¹ã§ãã ã°ã©ãã®äžå¿ã¯ã1ã€ã®é ç¹ãŸãã¯è€æ°ã®é ç¹ã§ãã ãŸãã¯ç°¡åã ã°ã©ãã®äžå¿ã¯ãé¢å¿çïŒãã®é ç¹ããæãé ãé ç¹ãŸã§ã®è·é¢ïŒãååŸã«çããé ç¹ã§ãã
print(' :', nx.center(deep_friends.graph))
ã°ã©ãã®äžå¿ã«ããé ç¹ã®ãªã¹ããè¿ããŸãã äžå¿ã
settings.pyã§æå®ãããIDã§ãã£ãŠãé©ããªãã§ãã ããã
ã°ã©ãã®ååŸã¯ããã¹ãŠã®é ç¹ã®æå°ã®é¢å¿çã§ãã
print(' :', nx.radius(deep_friends.graph))
æ©é¢ãŸãã¯ããŒãžã©ã³ã¯
ããã¯ããªããèããã®ãšåã
ããŒãžã©ã³ã¯ã§ãã ååãšããŠãã¢ã«ãŽãªãºã ã¯WebããŒãžãŸãã¯ãªã³ã¯ã§ãªã³ã¯ãããä»ã®ããã¥ã¡ã³ãã«äœ¿çšãããŸãã ããŒãžãžã®ãªã³ã¯ãå€ãã»ã©ãéèŠã§ãã ããããã°ã©ãã«ãã®ã¢ã«ãŽãªãºã ã䜿çšããããšãçŠæ¢ãã人ã¯ããŸããã ãã®
èšäºãããããæ£ç¢ºã§é©åãªå®çŸ©ãåçšããŸãã
ãœãŒã·ã£ã«ã°ã©ãã®æš©éã¯ãããŸããŸãªæ¹æ³ã§åæã§ããŸãã æãç°¡åãªæ¹æ³ã¯ãåå è
ãçä¿¡ãšããžã®æ°ã§ãœãŒãããããšã§ãã ããå€ããæã£ãŠãã人ã¯ããæš©åšããããŸãã ãã®æ¹æ³ã¯ãå°ããªã°ã©ãã«é©ããŠããŸãã ã€ã³ã¿ãŒãããæ€çŽ¢ã§ã¯ãGoogleã¯ããŒãžã®ä¿¡é Œæ§ã®åºæºã®1ã€ãšããŠPageRankã䜿çšããŸããããã¯ãããŒããããŒãžã§ããã°ã©ããã©ã³ãã ã«ããŸããããšã«ãã£ãŠèšç®ãããããŒãéã®ãšããžã¯ãããããŒãžãå¥ã®ããŒãžã«ãªã³ã¯ããŠããå Žåã§ããã©ã³ãã ãŠã©ãŒã«ãŒã¯ã°ã©ãäžãåãåããæã
ã©ã³ãã ããŒãã«ç§»åããŠãåã³æ©ãå§ããŸããPageRankã¯ãæŸæµªæéå
šäœã«ããã£ãŠãããããŒãã«æ»åšããå²åã«çãããªããŸãã倧ããã»ã©ãããŒãã®ä¿¡é Œæ§ã¯é«ããªããŸãã
import operator print('Page Rank:', sorted(nx.pagerank(deep_friends.graph).items(), key=operator.itemgetter(1), reverse=True))
ã¯ã©ã¹ã¿ãªã³ã°ä¿æ°
ãŠã£ãããã£ã¢ã®åŒçšïŒã¯ã©ã¹ã¿ãªã³ã°ä¿æ°ã¯ãç¹å®ã®å人ã«é¢é£ä»ãããã2人ã®ç°ãªããŠãŒã¶ãŒãæ¥ç¶ããã確çã®åºŠåãã§ãã
print(' ', nx.average_clustering(deep_friends.graph))
ã芧ã®ãšãããè€éãªããšã¯äœããããŸããããŸããnetworkxã¯ã°ã©ãã«é©çšã§ããããã«å€ãã®ã¢ã«ãŽãªãºã ïŒèè
ã¯148ãæ°ããŸããïŒãæäŸããŸããå¿
èŠãªã¢ã«ãŽãªãºã ãéžæããgraph.pyãã¡ã€ã«ã§é©åãªã¡ãœãããåŒã³åºãã ãã§ãããŸãšã
ç§ãã¡ã¯ãåæ£ã·ã¹ãã ã¯ããããææ¡ãããŠããããããïŒå€åŽè
ã®æ°ã«å¿ããŠïŒããªãã¯60åé«éã«åäœVKontakteãã§å
±éã®å人ã«ãŠã³ããæ§ç¯ããããšãã§ããªãã£ãããŒãžã§ã³ã®Himuraå
šãŠãæ·±ãå人ããèŠæ±ããããã«ãåæããèœåãè¿œå - ããŸããæ°ããæ©èœãå®è£
ããŸãæ§ç¯ãããã°ã©ããè¿œå ã®ãœãããŠã§ã¢ãã€ã³ã¹ããŒã«ããããªãå Žåã§ãåã®èšäºã®å
±éã®å人ã®çŸããã°ã©ããäœæããå¿
èŠãããå Žåã¯ãå€ããªãªãŒã¹ãããªãã®ãµãŒãã¹ã«ãããŸãããã®äžã«ã¯ããŠãŒã¶ãŒã®åéãªã¹ããä»»æã«æ·±ãååž°çã«ååŸããå€ãããŒãžã§ã³ããããŸããããã¯å¶éã§ã¯ãªããããã°ã©ã ã®é床ãäžãç¶ããŸããç¹ã«ããŒã¿ã®èŠèŠåã«é¢äžããŠããå Žåã¯ããã«ãªã¯ãšã¹ãããã«ããã®ãåŸ
ã£ãŠããŸãã ãæž
èŽããããšãããããŸããïŒ