แผนที่ของ GitHub
(github.com/anvaka)- Map of GitHub คือแผนที่ที่วางโปรเจ็กต์ GitHub มากกว่า 690,000 โปรเจ็กต์เป็นจุด โดยโปรเจ็กต์ที่มีผู้กดดาวร่วมกันมากจะถูกวางไว้ใกล้กัน
- การสร้างแผนที่ใช้ชุดข้อมูลสาธารณะของเหตุการณ์กิจกรรม GitHub จาก Google BigQuery และใช้ข้อมูล star ราว 500 ล้านรายการจากเหตุการณ์ตั้งแต่ กุมภาพันธ์ 2011 ถึงพฤษภาคม 2025
- การคำนวณความสัมพันธ์ระหว่างรีโพซิทอรีใช้ Jaccard Similarity แบบแม่นยำ ซึ่งเกินกำลังคอมพิวเตอร์ส่วนตัว RAM 24GB จึงต้องประมวลผลบน AWS EC2 อินสแตนซ์ที่มี RAM 512GB เป็นเวลาหลายชั่วโมง
- สำหรับการทำคลัสเตอร์ ได้ทดลองหลายอัลกอริทึมก่อนเลือก Leiden clustering และผลลัพธ์คือโปรเจ็กต์ราว 690,000 โปรเจ็กต์ถูกแบ่งเป็นมากกว่า 1,500 คลัสเตอร์
- การเรนเดอร์ทำด้วยเครื่องมือจัดเลย์เอาต์ที่พัฒนาขึ้นเองร่วมกับ maplibre, GeoJSON และ tippecanoe ขณะที่ป้ายชื่อประเทศจำนวนมากสร้างขึ้นด้วยความช่วยเหลือจาก ChatGPT
ภาพรวมโปรเจ็กต์
- Map of GitHub คือแผนที่ที่แสดงภาพโปรเจ็กต์ GitHub มากกว่า 690,000 โปรเจ็กต์
- แต่ละจุดแทน โปรเจ็กต์ หนึ่งตัว
- โปรเจ็กต์ที่มีผู้ใช้กด star ร่วมกันจำนวนมากจะถูกจัดวางให้ใกล้กันมากขึ้นบนแผนที่
เวอร์ชันสาธารณะ
- Current release, May 10, 2025: 690,000 โปรเจ็กต์, 1,500 คลัสเตอร์
- Initial release, May 8, 2023: 400,000 โปรเจ็กต์, 1,000 คลัสเตอร์
การเก็บข้อมูลและการคำนวณความคล้ายคลึง
- ขั้นตอนแรกคือดึงข้อมูลว่าผู้ใช้คนใดกด star ให้รีโพซิทอรีใดบ้าง
- ใช้ ชุดข้อมูลสาธารณะ ของเหตุการณ์กิจกรรม GitHub จาก Google BigQuery
- ช่วงเวลาที่ครอบคลุมคือ กุมภาพันธ์ 2011 ถึงพฤษภาคม 2025
- กระบวนการนี้ได้ข้อมูล star ประมาณ 500 ล้านรายการ
- ขั้นตอนที่สองคือคำนวณ Jaccard Similarity แบบแม่นยำระหว่างแต่ละรีโพซิทอรี
- ปริมาณการคำนวณมากเกินไปสำหรับคอมพิวเตอร์ส่วนตัวที่มี RAM 24GB
- บน AWS EC2 อินสแตนซ์ที่มี RAM 512GB สามารถประมวลผลเสร็จได้ภายในไม่กี่ชั่วโมง
- แม้จะทดลองวิธีวัดความคล้ายคลึงแบบอื่นด้วย แต่ Jaccard ให้ผลที่น่าเชื่อถือที่สุด
การทำคลัสเตอร์และเลย์เอาต์ของแผนที่
- ขั้นตอนที่สามคือทดลองใช้ อัลกอริทึมการทำคลัสเตอร์ หลายแบบเพื่อจัดกลุ่มรีโพซิทอรี
- สุดท้ายเลือก Leiden clustering เป็นวิธีที่ชอบที่สุด และทำให้โปรเจ็กต์ราว 690,000 โปรเจ็กต์ถูกแบ่งออกเป็นมากกว่า 1,500 คลัสเตอร์
- ขั้นตอนที่สี่ใช้ ngraph.forcelayout ที่พัฒนาขึ้นเองสำหรับการจัดวางโหนดภายในคลัสเตอร์
- ส่วนการจัดวางภาพรวมของทั้งคลัสเตอร์ใช้การตั้งค่าแยกต่างหาก
วิธีการเรนเดอร์
- ขั้นตอนที่ห้าคือกระบวนการเรนเดอร์แผนที่
- ต่างจากโปรเจ็กต์ก่อนหน้า เพื่อไม่ต้องสร้างทุกอย่างขึ้นมาใหม่ จึงเลือกใช้ maplibre
- ข้อมูลถูกแปลงเป็นรูปแบบ GeoJSON
- การสร้างไทล์ใช้ tippecanoe
- จากนั้นจึงประกอบประสบการณ์การสำรวจแผนที่
การสร้างป้ายชื่อประเทศ
- ป้ายชื่อประเทศ จำนวนมากที่แสดงบนแผนที่ถูกสร้างขึ้นด้วยความช่วยเหลือจาก ChatGPT
- หากพบป้ายชื่อผิด สามารถคลิกขวาเพื่อแก้ไขและส่ง pull request ได้
- system prompt สำหรับสร้างป้ายกำหนดให้มองกลุ่มรีโพซิทอรี GitHub เป็น “ประเทศ” ของคอมมูนิตี้โปรแกรมมิงเฉพาะทาง และให้สร้างชื่อที่ไม่ซ้ำและจำง่าย
- ชื่อต้องกระชับ อยู่ในช่วง 1-3 คำ
- ต้องสะท้อนธีม เทคโนโลยี หรือจุดประสงค์ร่วมของกลุ่มรีโพซิทอรีนั้น
- ควรหลีกเลี่ยงคำทั่วไปอย่าง “JSWorld”, “UI”, “Web”, “Forge”, “Archipelago”, “Hub”, “Republic”, “Nexus”
- ไม่ควรเป็นการนำชื่อรีโพซิทอรีคล้ายกันมารวมกันแบบตรงๆ
- ต้องแตกต่างจากชื่อประเทศอื่นมากพอที่จะระบุได้ทันทีบนแผนที่
- อินพุตของผู้ใช้ประกอบด้วย
repoListและrepoNamesOnlyและขอให้วิเคราะห์หัวข้อกับเทคโนโลยีเฉพาะของรีโพซิทอรีเหล่านั้นเพื่อสร้างชื่อ - หาก LLM ส่งคืนชื่อที่คล้ายกับชื่อก่อนหน้ามากเกินไป ระบบจะให้ลองใหม่และเพิ่ม temperature เพื่อชักนำผลลัพธ์ที่สร้างสรรค์มากขึ้น
การค้นหาและการออกแบบ
- กล่องค้นหาถูกสร้างโดยทำดัชนีจากดัมพ์อย่างง่ายของรีโพซิทอรีทั้งหมดตามตัวอักษรแรกหรือผู้เขียน
- เมื่อพิมพ์
aในช่องค้นหา ระบบจะหารายการรีโพซิทอรีที่ขึ้นต้นด้วยaแล้วแสดงผลด้วย fuzzy matcher ฝั่งไคลเอนต์ - ปัจจุบันผู้สร้างพอใจกับการแสดงข้อมูล แต่ยังคงมองหาสไตล์ที่ใช่สำหรับงานออกแบบภาพของแผนที่
- หากมีประสบการณ์ด้านการออกแบบแผนที่หรือไอเดียด้านภาพ ก็ขอเชิญช่วยแบ่งปัน
ใบอนุญาต
- รีโพซิทอรีเผยแพร่ภายใต้ MIT License
- หากนำข้อมูลไปใช้ในงานอื่น ขอให้พิจารณาให้ attribution แก่โปรเจ็กต์นี้
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ด้วยเหตุผลบางอย่าง torvalds/linux ไปอยู่ใน Fronterra ข้าง ๆ โปรเจกต์ JS, รายการ awesome-X และเช็กลิสต์ฟรอนต์เอนด์
ไม่ใช่ว่าแฮกเกอร์เคอร์เนลจู่ ๆ ก็หลงรักฟรอนต์เอนด์หรอก น่าจะเป็นเพราะคนที่เขียนโค้ดกับคนที่กดดาวโปรเจกต์บน GitHub แทบไม่ทับซ้อนกันมากกว่า
มันออกมาคล้ายกันไม่ใช่เพราะมีความสัมพันธ์เชิงความหมาย แต่เพราะทั้งคู่ดังเฉย ๆ
แผนที่ reddit ก็เจอปัญหาเดียวกัน: https://anvaka.github.io/map-of-reddit/ — subreddit ยอดนิยมทั้งหมดกลายเป็นว่า “คล้าย” กันไปหมด
ถึงอย่างนั้น มันก็ยังทำงานได้ดีกับโปรเจกต์เล็ก ๆ ที่ไม่ค่อยดัง :D
แต่ถ้าคิดถึงทรัพยากรที่ต้องใช้ในการดาวน์โหลดแต่ละไฟล์และคำนวณ embedding แล้ว คงทำได้ยากในทางปฏิบัติ
https://xkcd.com/1138/
ลิงก์จริง: https://anvaka.github.io/map-of-github/
ขำตอนเห็นว่าโซน Among Us ชื่อ Sussex
แปลกใจที่ Rustland เล็กขนาดนี้ เป็นแค่รัฐหนึ่งใน Clouderra เท่านั้นเอง
ที่ Bevy กับ Veloren อยู่ใน Rustland ทั้งคู่ก็น่าสนใจ น่าจะเพราะดาวมาจากคอมมูนิตี้ Rust มากกว่าคอมมูนิตี้พัฒนาเกม
ก็พอเข้าใจได้เมื่อคิดว่า ecosystem ของ Rust ยังถือว่าค่อนข้างเล็ก และดูเหมือนมีคนจำนวนมากที่ทำ “X ด้วย Rust”
ดูเหมือนทุกคนจะประเมินขนาดฟองสบู่ของตัวเองสูงเกินไป
ถ้าอย่างนั้น “X but in Rust” ก็อาจไปอยู่ฝั่ง “X” ไม่ใช่ “RustLand” ได้
สนุกมากที่หาโปรเจกต์ของผม mapbox-gl-utils เจอในนี้
https://anvaka.github.io/map-of-github/#12/24.78947/18.85186
การลองหาโปรเจกต์เฉพาะจากแผนที่อย่างเดียวโดยไม่มีฟังก์ชันค้นหา กลายเป็น มินิเกม สนุก ๆ ไปเลย :-)
ในฐานะแฟน Julia แปลกใจที่ julialang/julia มีการเชื่อมโยงน้อยขนาดนี้
ถึงจะเป็นภาษาเฉพาะกลุ่ม แต่ภาพที่ดูโดดเดี่ยวบนแผนที่นี้ก็ไม่ได้ห่างไกลจากประสบการณ์ของผู้ใช้หรือนักพัฒนามากนัก
ตัว julialang/julia เองอยู่ใกล้ tensorflow กับ opencv ส่วนแพ็กเกจ Julia จริง ๆ ไปรวมกันอีกที่หนึ่ง ซึ่งดูเหมือนจะแสดงความต่างระหว่าง “ผู้ใช้ที่คาดหวัง” กับ “ผู้ใช้จริง”
คนจำนวนมากที่กดดาวโปรเจกต์ Julia เองคือผู้ใช้ Python ด้าน numerical computing ที่กำลังมองหา Python ตัวใหม่ แต่ส่วนใหญ่ก็ยังอยู่กับ Python และดาวอื่น ๆ ของพวกเขาจึงอยู่ฝั่ง numerical Python
ส่วนคนที่กดดาวแพ็กเกจใน JuliaLand คือผู้ใช้ Julia จริง ๆ จึงไปรวมอยู่ใกล้ Moleculandia, AstroSpace, Quantumia อย่างสมเหตุสมผล
เป็นแนวทางที่เนี้ยบและสร้างสรรค์มาก แต่พูดตามตรง ผมยังลังเลว่า อุปมาแบบประเทศ/แผนที่ เป็นตัวเลือกที่ดีที่สุดหรือไม่
หลายกรณีแค่ชื่อยังไม่ชัดเจน ต้องซูมเข้าไปถึงจะเข้าใจว่าหมายถึงอะไร
อาจน่าสนใจกว่าถ้าทำ hierarchical clustering แล้วติดป้ายที่ LLM สร้างให้แบบอธิบายได้ชัดและตรงกว่า จากนั้นใช้เส้นแสดงค่าเชื่อมโยงเฉลี่ยระหว่างกลุ่มระดับบน
ในฐานะคนที่เคยสร้างภาพแบบนั้นครั้งแรกในยุค 90 แล้วก็เรียนรู้ข้อจำกัดของมันแทบจะทันที ผมชอบที่อันนี้ไม่ได้อ้างเกินจริง มันเป็นแค่มุมมองหนึ่ง ไม่ใช่งานวิจัย
ผมชอบแผนภูมิที่แกนมีความหมาย รวมถึงเส้น รูปร่าง กล่อง/กลุ่ม ระยะทาง X เทียบกับ Y สี ความหนา texture พื้นหลัง foreground อะไรพวกนั้น
แบบเรียบง่ายก็ดี บ่อยครั้งเกินไปที่คนลากเส้นเพื่อให้ดูเท่โดยไม่มีความหมาย แต่อันนี้เป็นแค่ภาพที่มีกลุ่มอยู่เล็กน้อยและมีคาแรกเตอร์ ก็ดีไม่ใช่เหรอ?
แน่นอนว่าผมยังชอบเส้นอยู่ แต่ไม่จำเป็นต้องมีทุกที่ทุกเวลา
บ่อยครั้งมีหลายวิธีในการจัดกลุ่มข้อมูลที่ต่างก็สมเหตุสมผล ดังนั้นไม่ว่าจะเลือก clustering สุดท้ายแบบไหนก็ไม่สมบูรณ์แบบ
อืม… บางทีถ้าทำอะไรอย่าง quantum clustering ก็น่าจะเป็นโปรเจกต์ที่สนุก
ตอนนี้จำได้ลาง ๆ ว่าเคยลองอัลกอริทึม hdbscan หรือก็คือ hierarchical clustering แต่กราฟขนาด GitHub เอาเข้าเมโมรีไม่ได้
สุดท้ายเลยใช้สิ่งที่คล้าย hierarchical clustering ผสม louvain/leiden/วิธีที่ทำเอง และสิ่งที่เห็นบนแผนที่สุดท้ายก็คือผลลัพธ์นั้น
Quitlessia กับ NeoQuitlessia เนี่ย… ชื่อโหดร้ายมาก
Doom Emacs อยู่ใน NeoQuitlessia ไม่ใช่ Emacsia ซึ่งแปลกที่มันก็สมเหตุสมผลนะ :)
เราจะไม่ออกจากมัน
สงสัยว่าการเชื่อมโยงระหว่าง repository ถูกกำหนดยังไง
ลองดู repository ของตัวเองบางอันแล้ว บางการเชื่อมโยงดูไม่เห็นการอ้างอิงกันทั้งสองทิศทาง
โดยพื้นฐานตามที่คนอื่นเดา เส้นแสดงคะแนนความคล้ายกันสูงสุดตาม “คนที่กดดาว” และแผนที่ทั้งหมดก็ถูกสร้างจากเกณฑ์นั้น
จุดที่อาจทำให้สับสนคือ เส้นจะแสดงก็ต่อเมื่อคลิกประเทศใดประเทศหนึ่งเท่านั้น
น่าจะมี threshold ที่ hardcode ไว้เพื่อตัดสินว่าจะสร้าง edge หรือไม่ เช่น ถ้า Jaccard similarity ระหว่าง A กับ B มากกว่า 0.2 ก็สร้าง edge