تحلیل شبکه های اجتماعی در پایتون – راهنمای کاربردی


پیش از این، در مطالب «تحلیل شبکه های اجتماعی از صفر تا صد — راهنمای جامع» و «تحلیل شبکه های اجتماعی (Social Network Analysis) — به زبان ساده و جامع» به بحث تحلیل شبکههای اجتماعی پرداخته شد. در این مطلب، به چگونگی تحلیل شبکه های اجتماعی در پایتون پرداخته میشود.
«شبکهها» (Networks) امروزه بخشی از زندگی روزمره انسانها شدهاند. در این مطلب، چگونگی بصریسازی و درک یک شبکه اجتماعی در «زبان برنامهنویسی پایتون» (Python Programming Language) و با استفاده از کتابخانه Networks آموزش داده شده است. شبکهها در همه جا هستند، شبکه جادهها، شبکه دوستان و دنبالکنندگان در شبکههای اجتماعی و شبکه همکاران، تنها برخی از انواع شبکههایی هستند که در اطراف ما وجود دارند. این شبکهها نقش اساسی در زندگی روزمره انسانها دارند. این نقش، از توزیع اطلاعات مفید گرفته تا تحت تاثیر قرار دادن انتخابات ملی را شامل میشود.
توانایی تحلیل این شبکهها و انجام تصمیمگیریهای اطلاعاتمحور بر پایه آنها، مهارتی است که برای هر تحلیلگر دادهای حائز اهمیت محسوب میشود. تمرکز این مطلب، آموزش دادن روش تحلیل شبکه های اجتماعی در پایتون و با استفاده از کتابخانه NetworkX است. NetworkX یک کتابخانه پایتون برای مطالعه ساختار، پویاییشناسی و توابع شبکههای پیچیده است. در این راهنما، فرض بر آن است که مطالعه کننده با نحو پایهای پایتون آشنا است. نیاز به دانش پیشین پیرامون تحلیل شبکههای اجتماعی وجود ندارد، هر چند آشنایی با این مبحث، یک مزیت محسوب میشود.
مقدمهای بر تحلیل شبکه های اجتماعی در پایتون
در ابتدا، مفهوم «شبکه اجتماعی» (Social Network) بیان میشود. در تصویر زیر، میتوانید شبکهای از بازیگران بالیوود را مشاهده کنید.
در این شبکه، بازیگرها به عنوان «گرههای» (Nodes) شبکه هستند. این بازیگران (گرهها)، در صورتی که با یکدیگر حداقل در یک فیلم همکاری داشتهاند، با خطهای مستقیمی به یکدیگر وصل شدهاند.
بنابراین، میتوان مشاهده کرد که «آمیتا باچان» (Amitabh Bachchan) و «آبیشک باچان» (Abhishek Bachchan) با همه بازیگران در شبکه همکاری داشتهاند، در حالی که «آکشی کومار» (Akshay Kumar) تنها با باچانها همکاری داشته و با دیگر بازیگرها، همکاری نکرده است.
این یک «شبکه اجتماعی» (Social Network) است. هر شبکهای که در آن اتصالاتی بین افراد وجود داشته باشد و در آن، اتصالات ارتباط بین آنها را نشان دهند، یک شبکه اجتماعی محسوب میشود. تحلیل این شبکههای اجتماعی، میتواند بینش خوبی پیرامون افراد درون شبکه ارائه کند؛ به عنوان مثال، میتوان به اینکه چه کسانی «تاثیرگذاران» (Influencers) واقعی هستند، چه کسانی بیشترین اتصالات را دارند و دیگر موارد، اشاره کرد. هر شبکه شامل موارد زیر است.
- گرهها (Nodes): افرادی که شبکه آنها ساخته میشود. در مثال بالا، بازیگران، در واقع گرههای شبکه هستند.
- یالها (Edges): اتصالات بین گرهها را یال میگویند. یال، ارتباط بین گرهها در شبکه را نشان میدهد. در مثال بازیگران بالیوود، ارتباط در واقع همکاری داشتن بازیگران با یکدیگر است که با خطوط صاف و سیاه که یالهای شبکه هستند، نمایش داده شده است.
ساخت یک شبکه با استفاده از NetworkX
انواع گوناگونی از شبکهها وجود دارد. از NetworkX برای توسعه و تحلیل شبکههای گوناگون استفاده میشود.
برای شروع، کاربر باید networkX را نصب کند. برای انجام این کار، میتوان از دستور زیر استفاده کرد:
کاربرانی که از «آناکوندا» (Anaconda) استفاده میکنند، میتوانند از دستور زیر استفاده کنند.
استفاده از دستورهای ارائه شده در بالا، موجب میشود که آخرین نسخه از networkx روی کامپیوتر کاربر نصب شود. کدهای ارائه شده در این راهنما، در پایتون 3.5 و NetworkX 2.0 نوشته شدهاند.
شبکههای متقارن
شبکه بازیگران که در ابتدای این راهنما ساخته شد، یک «شبکه متقارن» (Symmetric Networks) است، زیرا ارتباط «با هم همکاری دارند» یک رابطه متقارن است. یعنی اگر A مرتبط با B باشد، B نیز مرتبط با A است.
اکنون، شبکهای که در بالا مشاهده شد، در NetworkX ساخته میشود. از متد Graph() برای ساخت یک شبکه جدید و از add_edge() برای اضافه کردن یک یال بین دو گره، استفاده میشود.
اکنون، شبکهای که ساخته شده است، با استفاده از دستور nx.draw_networkx(G_symmetric)، بصریسازی میشود.
شبکههای نامتقارن
اگر رابطه بین گرهها به صورت «فرزندِ ...» باشد، رابطه متقارن محسوب نمیشود. در واقع، اگر A فرزند B باشد و B فرزند A نباشد، رابطه نامتقارن است. به چنین شبکهای که در آن رابطه نامتقارن است (مرتبط بودن A به B به معنای مرتبط بودن B به A نیست)، «شبکه نامتقارن» (Asymmetric Network) گفته میشود.
میتوان شبکه نامتقارن را در NetworkX با استفاده از متد DiGraph ساخت. DiGraph، کوتاه شده عبارت Directional Graph است. در ادامه، یک گراف نامتقارن ساخته میشود.
اکنون، این گراف بصریسازی میشود. برای بصریسازی این گراف، همچون مثال پیشین، میتوان از تابع draw_networkx() استفاده کرد. این امکان وجود دارد که گرهها جدا نشوند و در شبکه رسم شده، به طور کاملا مجزا قابل مشاهده نباشند. برای پیشگیری از وقوع این مورد، میتوان از تابعی استفاده کرد که یک لایه را وادار کند تا گرهها را به صورتی قرار دهد که بتوان آنها به طور متمایز مشاهده کرد. این کار با استفاده از تابع spring_layout() قابل انجام است که به وسیله تابع draw_networkx() دنبال شده است.
در زیر میتوان شبکهای را با و بدون استفاده از دستور layout مشاهده کرد. یکی از تصاویر زیر با دستور layout و دیگری بدون آن ساخته شده است، هر چند، تصویر ساخته شده با استفاده از دستور layout دارای شفافیت بیشتری است.
شبکههای وزندار
تا این لحظه، شبکههای مورد بررسی، بدون وزن بودند. اما این امکان وجود دارد که شبکه دارای وزن ساخته شود. برای مثال، اگر در شبکهای که در ابتدای این مطلب معرفی شد تعداد فیلمهایی که دو بازیگر با یکدیگر در آنها همکاری داشتهاند به عنوان وزن در نظر گرفته شود، حاصل یک «شبکه وزندار» (Weighted Network) است.
در ادامه، یک شبکه دیگر از بازیگران ساخته میشود، اما اینبار، وزن نیز به شبکه اضافه میشود و هر یال دارای وزنی است که تعداد فیلمهایی که دو بازیگر با یکدیگر در آنها همکاری داشتهاند را نشان میدهد.
تصویر بالا یک شبکه وزندار از بازیگران را در قالب circular نشان میدهد. پهنای یال، نشانگر وزن بین گرهها است.
گراف چندگانه
میتوان خصیصههای گوناگونی را به یالها داد. برای مثال، میتوان رابطه همسایگی بین دو گره A و B را با استفاده از خصیصه relation تعریف کرد. اگر درون شبکه، دو گره با دو یال متفاوت (ارتباط) متصل شده باشند، حاصل یک «گراف چندگانه» (Multigraph) است.
میتوان یک Multigraph را با استفاده از کلاس MultiGraph ساخت.
این کد یک گراف جدید را با دو یال بین A و B میسازد. میتوان اتصالات را با استفاده از G.edges() بررسی کرد. خروجی به صورت زیر خواهد بود.
اتصالات شبکه
پرسشی که در این وهله مطرح میشود این است که اکنون که شبکه ساخته شد، آیا میتوان اطلاعات بیشتری را پیرامون یک گره خاص در شبکه داشت؟ پاسخ مثبت است. برخی از این موارد، در ادامه مورد بررسی قرار خواهد گرفت.
درجه
درجه یک گره، تعداد اتصالاتی که یک گره دارد را مشخص میکند. NetworkX دارای تابع degree است که میتوان از آن برای تعیین درجه یک گره در شبکه استفاده کرد.
با اجرای این کد، مقدار ۳ بازگردانده میشود، زیرا «دو آناند» (Dev Anand) تنها با سه نفر از بازیگرانی که در این شبکه وجود دارند، همکاری کرده است.
ضریب خوشهبندی
مشاهده میشود که افرادی که ارتباطات خود در شبکههای اجتماعی را به اشتراک میگذارند، گرایش به تشکیل انجمنها دارند. به بیان دیگر، در شبکههای اجتماعی، گرایشی نسبت به ساخت خوشهها وجود دارد. میتوان خوشه یک گره، «ضریب خوشهبندی محلی» (Local Clustering Coefficient)، را تعیین کرد که کسری از جفت دوستان گره است که به یکدیگر متصل شدهاند.
برای تعیین ضریب خوشهبندی محلی، میتوان از تابع nx.clustering(Graph, Node) استفاده کرد. در شبکه بازیگر متقارن، دو آناند دارای ضریب خوشهبندی محلی ۱ و آبیشیک باچان دارای ضریب خوشهبندی محلی ۰/۶۷ است. ضریب خوشهبندی میانگین (مجموع همه ضرایب خوشهبندی محلی تقسیم بر تعداد گرهها) برای شبکه بازیگران برابر با ۰.۸۶۷ است.
فاصله
میتوان کوتاهترین مسیر بین دو گره و طول آن را در NetworkX به ترتیب با استفاده از توابعی که در ادامه آمده است، تعیین کرد.
دستور زیر اجرا میشود.
خروجی به صورت زیر است.
['Dev Anand', 'Amitabh Bachchan', 'Akshay Kumar']
میتوان فاصله یک گره از دیگر گرهها در شبکه را با استفاده از «الگوریتم جستجوی اول عمق» (Breadth-First Search Algorithm)، با شروع از آن گره، پیدا کرد. networkX تابع bfs_tree را برای انجام جستجوی اول عمق ارائه میکند. بنابراین، اگر دستور T = nx.bfs_tree(G_symmetric, 'Dev Anand') آزموده و این درخت ساخته شود، میتوان یک ساختار شبکه به دست آورد که نشان میدهد چگونه میتوان از گره Dev Anand به دیگر گرههای شبکه رسید.
دوری از مرکز
دوری از مرکز برای گره A به عنوان بزرگترین فاصله بین A و کلیه گرههای دیگر تعیین شده است. این مقدار را میتوان با استفاده از تابع nx.eccentricity() پیدا کرد. در شبکه متقارن بازیگران، دو آناند دارای دوری از مرکز ۲ و آبیشیک باچان دارای دوری از مرکز ۱ است (به همه گرهها متصل شده است).
تاثیرگذاران شبکه
پیش از این، برخی از سنجههای فاصله در شبکه مورد بررسی قرار گرفتهاند. این سنجهها برای دانستن آنکه اطلاعات چگونه در شبکه توزیع میشوند مفید است. در این بخش، چگونگی توزیع اطلاعات از طریق شبکه بیان و روش پیدا کردن مهمترین گرهها (افراد) در شبکه آموزش داده شده است. این پارامترها «سنجههای مرکزی» (Centrality Measures) نامیده میشوند.
احتمالا همه، فرد یا افرادی را از دوران مدرسه میشناسند که از محبوبیت بالایی برخوردار بوده (اند) و توانایی انجام هر کاری را داشتند. آنچه به این افراد چنین توانایی را میداد، «سنجههای مرکزی» (Centrality Measures) است. سنجههای مرکزی میتوانند به تعیین محبوبیت، مورد پسند قرار گرقتهترین و بزرگترین تاثیرگذاران شبکه کمک کنند.
مرکزیت درجه
افرادی که محبوبتر هستند یا در واقع، بیشتر مورد پسند قرار میگیرند، افرادی هستند که دوستان بیشتری دارند. مرکزیت درجه سنجهای از تعداد ارتباطاتی است که یک گره مشخص در شبکه دارد. این سنجه بر اساس این حقیقت است که گرههای مهمتر ارتباطات زیادی دارد. NetworkX دارای تابع degree_centrality() برای محاسبه مرکزیت درجه همه گرههای شبکه است.
مرکزیت ویژهبردار
نه فقط تعداد افرادی که یک گره به آنها متصل شده، بلکه نوع افرادی که یک گره به آنها متصل شده است نیز میتوانند در تعیین اهمیت یک گره نقشآفرین باشد. «مرکزیت ویژهبردار» (Eigenvector Centrality)، دقیقا سنجهای برای این مورد است. این سنجه بیان میکند که یک گره مهم است اگر به دیگر گرههای مهم متصل باشد. میتوان از تابع eigenvector_centrality() از NetworkX برای محاسبه مرکزیت ویژهبردار همه گرهها در شبکه استفاده کرد. الگوریتم پیچرنک گوگل (Google's Pagerank) نوعی از الگوریتمهای مرکزیت ویژهبردار است.
مرکزیت میانی
«مرکزیت میانی» (Betweenness Centrality)، در واقع مرکزیت کنترل است. این مرکزیت میزان تکراری را نشان میدهد که یک نقطه در «ژئودزیک» (Geodesic) (کوتاهترین مسیر) که جفتی از نقاط را به یکدیگر متصل کرده، به وقوع میپیوندد. در واقع، این سنجه تعداد دفعاتی که یک گره خاص در کوتاهترین مسیر انتخاب شده بین دو گره دیگر به وقوع میپیوندد را کمیسازی میکند. گرههایی با مرکزیت میانی بالا، نقش اساسی در جریان ارتباطاتی/اطلاعاتی ایفا میکنند.
گرههایی با مرکزیت میانی بالا میتوانند روی دیگر گرهها کنترل استراتژیک داشته باشند. یک فرد در چنین موقعیت استراتژیکی میتواند کل گروه را با ممانعت کردن از اطلاعات در حال انتقال و یا تغییر دادن آن، تحت تاثیر قرار دهد. Networkx دارای تابع betweenness_centrality() برای اندازهگیری مرکزیت میانی برای شبکه است. این تابع دارای گزینههایی است که کاربر با استفاده از آنها میتواند مقدار میانی را نرمال کند یا نکند و یا نقاط پایانی را در شمارش کوتاهترین مسیر قرار دهد یا ندهد.
بررسی موردی
اکنون، کار با دادههای فیسبوک آغاز میشود. در این مثال، از مجموعه داده «شبکههای اگو» (Ego Networks) ترکیب شده استفاده میشود؛ این مجموعه داده حاوی شبکه تجمیع شده لیست دوستان فیسبوکی ده نفر است. میتوان فایل facebook_combined.txt را از اینجا [+] دانلود کرد.
علاقهمندان میتوانند دادههای فیسبوک/توییتر خودشان را با استفاده از API فیسبوک/توییتر دریافت و از آنها برای انجام این مثال استفاده و دادههای خود را تحلیل کنند. برای انجام این پروژه، ابتدا فایل خوانده و گراف آن ساخته میشود.
شبکه شامل ۴۰۳۹ گره است که با ۸۸۲۳۹ یال به یکدیگر متصل شدهاند. میتوان اطلاعات را با استفاده از تابع info() دریافت کرد.
در تصویر زیر میتوان شبکه حاصل شده را مشاهده کرد.
همچنین، میتوان شبکه را به نوعی بصریسازی کرد که رنگ گرهها بر اساس درجه و اندازه گرهها بر اساس مرکزیت میانی تغییر کند. کد لازم برای انجام این کار، در ادامه آمده است.
گراف حاصل، به صورت زیر است.
همچنین، میتوان برچسب گرههای دارای بالاترین مرکزیت میانی را نیز با استفاده از دستور زیر داشت.
در جدول زیر، برچسبهای پنج گره با بالاترین سنجههای مرکزیت ارائه شدهاند.
میتوان مشاهده کرد که برخی از گرهها دارای مرکزیت درجه که سنجه درجه است و مرکزیت میانی که جریان اطلاعات را کنترل میکند، مشابه هستند. طبیعی است که گرههایی که متصلتر هستند نیز روی کوتاهترین مسیر بین دیگر گرهها تکیه دارند. گره ۱۹۱۲ یک گره مهم است زیرا دارای بالاترین نوع مرکزیت در هر سه نوع مرکزیت محاسبه شده است.
اگر نوشته بالا برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای دادهکاوی و یادگیری ماشین
- آموزش تحلیل شبکههای اجتماعی با نرم افزار نودایکسال (NodeXL)
- مجموعه آموزشهای آمار و احتمالات
- تشخیص ناهنجاری در شبکههای اجتماعی برخط — راهنمای جامع
- تحلیل شبکههای اجتماعی با R — به زبان ساده
- روشهای تحلیل احساسات در پایتون — راهنمای کاربردی
^^
این آموزش، عالی بود. بسیار مفید و کاربردی
ممنون از مطالب خوبتون
سلام خیلی خیلی خوب بود . من یه همچین چیزی برا اینستاگرام می خوام درست کنم بحث ریاضی و الگریتمیش درست شده فقط تو جمع کردن دیتا فالور و فالویینگ های افراد مشکل دارم چه لایبرری یا پلتفرمی رو پیشنهاد می کنید ؟
https://www.instagram.com/developer/libraries/
https://pypi.org/project/InstagramAPI/
https://github.com/LevPasha/Instagram-API-python#egg=InstagramAPI
عالی و خیلی مفید و کاربردی بود ممنون از بهترین نویسنده فرادرس 🙂