4P by GN⁺ | ★ favorite | 댓글 1개
  • Map of GitHub는 69만 개 이상의 GitHub 프로젝트를 점으로 배치한 지도이며, 공통 stargazer가 많은 프로젝트일수록 서로 가깝게 놓임
  • 지도 제작에는 Google BigQuery의 GitHub 활동 이벤트 공개 데이터셋이 쓰였고, 2011년 2월부터 2025년 5월까지의 이벤트에서 약 5억 개 star 데이터를 사용함
  • 저장소 간 관계 계산에는 정확한 Jaccard Similarity가 사용됐으며, 24GB RAM 가정용 컴퓨터로는 부족해 512GB RAM AWS EC2 인스턴스에서 몇 시간 동안 처리함
  • 클러스터링에는 여러 알고리듬을 시험한 뒤 Leiden clustering을 선택했고, 결과적으로 약 69만 개 프로젝트가 1,500개 이상의 클러스터로 나뉨
  • 렌더링은 자체 레이아웃 도구와 maplibre, GeoJSON, tippecanoe를 조합해 구현됐으며, 국가명 라벨 상당수는 ChatGPT 도움으로 생성됨

프로젝트 개요

  • Map of GitHub는 GitHub 프로젝트 69만 개 이상을 시각화한 지도임
  • 각 점은 하나의 프로젝트를 나타냄
  • 공통으로 star를 준 사용자가 많은 프로젝트끼리 지도에서 더 가깝게 배치됨

공개 버전

데이터 수집과 유사도 계산

  • 첫 단계에서는 어떤 사용자가 어떤 저장소에 star를 줬는지 가져옴
    • Google BigQuery의 GitHub 활동 이벤트 공개 데이터셋을 사용함
    • 대상 기간은 2011년 2월부터 2025년 5월까지임
    • 이 과정에서 약 5억 개 star 데이터를 얻음
  • 두 번째 단계에서는 각 저장소 사이의 정확한 Jaccard Similarity를 계산함
    • 24GB RAM 가정용 컴퓨터에는 계산량이 너무 컸음
    • 512GB RAM을 가진 AWS EC2 인스턴스에서는 몇 시간 안에 처리됨
    • 다른 유사도 방식도 시험했지만 Jaccard가 가장 믿을 만한 결과를 냄

클러스터링과 지도 레이아웃

  • 세 번째 단계에서는 저장소를 묶기 위해 여러 클러스터링 알고리듬을 사용해 봄
  • 최종적으로 Leiden clustering을 가장 선호했고, 69만 개 안팎의 프로젝트가 1,500개 이상의 클러스터로 나뉨
  • 네 번째 단계에서는 클러스터 내부 노드 배치에 자체 ngraph.forcelayout을 사용함
  • 클러스터 전체의 전역 배치에는 별도 설정을 사용함

렌더링 방식

  • 다섯 번째 단계는 지도를 렌더링하는 과정임
  • 이전 프로젝트들과 달리 바퀴를 다시 만들지 않기 위해 maplibre를 사용함
  • 데이터는 GeoJSON 형식으로 변환됨
  • 타일 생성에는 tippecanoe가 사용됨
  • 이후 지도 탐색 경험을 구성함

국가명 라벨 생성

  • 지도에 표시되는 많은 국가 라벨은 ChatGPT의 도움으로 생성됨
  • 잘못된 라벨을 발견하면 우클릭으로 수정하고 pull request를 보낼 수 있음
  • 라벨 생성을 위한 시스템 프롬프트는 GitHub 저장소 묶음을 특정 프로그래밍 커뮤니티의 “국가”로 보고, 고유하고 기억하기 쉬운 이름을 만들도록 요구함
    • 이름은 1~3단어로 간결해야 함
    • 해당 저장소 묶음의 공통 주제, 기술, 목적을 포착해야 함
    • “JSWorld”, “UI”, “Web”, “Forge”, “Archipelago”, “Hub”, “Republic”, “Nexus” 같은 일반적 표현은 피해야 함
    • 비슷한 저장소 이름을 단순 결합하지 않아야 함
    • 지도 위에서 즉시 식별될 만큼 다른 국가명과 구별되어야 함
  • 사용자 입력에는 repoListrepoNamesOnly가 들어가며, 해당 저장소들의 구체적 주제와 기술을 분석해 이름을 만들도록 요청함
  • LLM이 이전 이름과 너무 비슷한 이름을 반환하면 다시 시도하게 하고 temperature를 높여 더 창의적인 결과를 유도함

검색과 디자인

  • 검색 상자는 모든 저장소의 단순 덤프를 첫 글자 또는 작성자 기준으로 인덱싱해 구현함
  • 검색창에 a를 입력하면 a로 시작하는 저장소를 찾아 클라이언트에서 퍼지 매처로 보여줌
  • 현재 데이터 표현은 마음에 들지만 지도 시각 디자인은 아직 맞는 스타일을 찾고 있음
  • 지도 디자인 경험이나 시각적 아이디어가 있으면 공유를 요청함

라이선스

  • 저장소는 MIT 라이선스로 공개됨
  • 데이터를 다른 작업에 사용할 경우 이 프로젝트에 attribution을 고려해 달라고 요청함

댓글과 토론

Hacker News 의견들
  • 어째서인지 torvalds/linux가 JS 프로젝트, awesome-X 목록, 프런트엔드 체크리스트 옆의 Fronterra에 있음
    커널 해커들이 갑자기 프런트엔드를 사랑하게 됐거나, 더 가능성 높게는 코드를 쓰는 사람들과 GitHub 프로젝트에 별을 누르는 사람들이 별로 겹치지 않는 듯함

    • 자카드 유사도는 “유명인” 프로젝트에는 별로 좋지 않음
      의미적으로 관계가 있어서 비슷한 게 아니라, 그냥 둘 다 인기 있어서 비슷하게 나옴
      reddit 지도에서도 같은 문제를 겪었음: https://anvaka.github.io/map-of-reddit/ — 인기 있는 서브레딧들은 전부 서로 “비슷”해져 버림
      그래도 작고 덜 유명한 프로젝트에는 여전히 잘 동작함 :D
    • 프로젝트를 정리하는 데 코드 임베딩이 더 나았을지도 궁금함
      다만 각 파일을 내려받고 임베딩을 계산하는 데 필요한 자원을 생각하면 아마 현실적으로 어렵겠음
    • 히트맵이 사실상 인구 지도가 되는 경우가 많은 것과 비슷한 이유일지도 모름
      https://xkcd.com/1138/
    • react 때문인가?
  • 실제 링크: https://anvaka.github.io/map-of-github/

    • 맞음, 저장소가 아니라 이 링크가 걸렸어야 함
  • Among Us 구역 이름이 Sussex인 걸 보고 웃었음

    • 내가 본 것 중 제일 웃긴 건 Lispaña였음
  • Rustland가 이렇게 작아서 놀랐음. Clouderra 안의 한 주 정도밖에 안 됨
    Bevy와 Veloren이 둘 다 Rustland에 있는 것도 흥미로움. 아마 별이 게임 개발 커뮤니티보다는 Rust 커뮤니티에서 더 많이 온 듯함
    Rust 생태계가 아직 비교적 작고, “X를 Rust로 하는 사람들”이 많아 보인다는 점에서는 납득됨

    • nodelandia도 이렇게 작고 심지어 독립 대륙도 아니라는 게 충격임
      다들 자기 버블의 크기를 과대평가하는 듯함
    • “PlusPlus Nation”의 다른 커널들 근처에 운영체제 개발 Rust 프로젝트가 많이 보임
      그러면 “X but in Rust”는 “RustLand”가 아니라 “X” 쪽에 들어갈 수도 있음
    • 그렇게 놀랍지는 않음. Rust는 목소리 큰 소수가 전도하는 언어로도 알려져 있음
    • OP에 따르면 데이터가 2023년 3월 기준이라, 더 최근 Rust 프로젝트들은 아직 많이 포함되지 않았을 것임
    • 그래도 그 사이에 bevy가 보여서 반가움 :)
  • 내 프로젝트 mapbox-gl-utils를 여기서 찾을 수 있어서 아주 재미있음
    https://anvaka.github.io/map-of-github/#12/24.78947/18.85186

  • 검색 기능 없이 지도만으로 특정 프로젝트를 찾아보는 게 재미있는 미니게임이 됨 :-)

    • 또는 한 프로젝트에서 시작해 다른 프로젝트까지 길을 찾아가도 됨. 항로가 있다고 상상할 수 있음 :)
  • Julia 팬으로서 julialang/julia에 연결이 이렇게 적은 게 놀라움
    틈새 언어이긴 한데, 이 지도에서 이렇게 고립돼 보이는 모습이 사용자나 개발자 경험과 아주 동떨어진 것도 아닌 듯함

    • julialang/julia가 있는 섬의 서쪽에 JuliaLand가 있음
      julialang/julia 자체는 tensorflow와 opencv 근처에 있고, 실제 Julia 패키지들은 다른 곳에 모인 건 “희망 사용자”와 “실제 사용자”의 차이를 보여주는 듯함
      Julia 프로젝트 자체에 별을 단 많은 사람은 새로운 Python을 찾던 수치 계산 Python 사용자였지만 대부분 Python에 남았고, 그래서 다른 별들도 수치 계산 Python 쪽에 있음
      반면 JuliaLand 패키지에 별을 단 사람들은 실제 Julia 사용자라서, 그럴듯하게도 Moleculandia, AstroSpace, Quantumia 근처에 모였음
  • 아주 깔끔하고 창의적인 접근이지만, 국가/지도 은유가 최선인지는 솔직히 갈등됨
    많은 경우 이름만으로는 명확하지 않아서, 무엇을 나타내는지 이해하려면 확대해야 함
    차라리 계층적 군집화를 하고, 더 설명적이고 충실한 LLM 생성 라벨을 붙인 뒤, 상위 군집 간 평균 연결성을 선으로 보여주는 식이 더 흥미로웠을 수도 있음

    • 선이 잔뜩 그어진 무거운 그림이 아니라서 오히려 기분 좋게 놀랐음
      90년대에 그런 그림을 처음 만들고 거의 바로 한계를 배운 입장에서는, 이건 과도한 주장을 하지 않아서 좋음. 논문이 아니라 하나의 보기일 뿐임
      축에 의미가 있는 도표를 좋아함. 선, 모양, 박스/그룹, 거리, X 대 Y, 색, 두께, 질감, 배경, 전경 같은 것들 말임
      단순한 것도 좋음. 너무 자주 아무 의미 없이 멋 내려고 선을 긋는데, 이건 그냥 약간의 그룹이 있는 그림이고 개성이 있음. 좋지 않나?
      물론 선은 여전히 좋아하지만, 언제 어디서나 다 필요한 건 아님
    • 아직 보편적인 군집화 알고리즘은 찾지 못했음
      데이터를 묶는 방식이 여러 개여도 각각 말이 되는 경우가 자주 있고, 그래서 어떤 최종 군집화를 고르든 완벽하지 않음
      음… 어쩌면 양자 군집화 같은 걸 하면 재미있는 프로젝트가 될 수도 있겠음
      지금은 좀 흐릿하지만 hdbscan 알고리즘, 즉 계층적 군집화를 시도했던 기억이 있음. GitHub 규모의 그래프에서는 메모리에 올릴 수가 없었음
      결국 계층적 군집화와 비슷한 것, louvain/leiden/직접 만든 방식을 섞은 것을 사용했고, 최종 지도에 보이는 게 그 결과임
    • 그렇게 할 수도 있었겠지만, 이 프로젝트는 지도를 만들기로 한 것임
  • QuitlessiaNeoQuitlessia라니… 이름들이 사악함
    Doom Emacs가 Emacsia가 아니라 NeoQuitlessia에 있는데, 놀랍게도 말이 됨 :)

    • 하하! vim을 사랑함
      우리는 종료하지 않을 것임
  • 저장소 간 연결은 어떻게 정해지는지 궁금함
    내 저장소 몇 개를 확인해 봤는데, 일부 연결은 어느 방향으로도 참조가 보이지 않음

    • 작성자가 원래 HN 글에서 답했음: https://news.ycombinator.com/item?id=35933981
      기본적으로 다른 사람들이 추측한 것처럼, 선은 “별을 누른 사람들” 기준의 가장 높은 유사도 점수를 나타내고, 전체 지도도 그 기준으로 형성됨
      헷갈릴 수 있는데, 선은 특정 국가를 클릭했을 때만 나타남
    • 첫 줄에 나와 있음: “공통으로 별을 누른 사람이 많으면 점들이 서로 가깝다”
    • 자카드 유사도는 0과 1 사이의 값을 반환함. 이 경우 대부분의 값은 0에 가까울 것임
      간선을 만들지 말지 정하는 하드코딩된 임계값이 있을 것 같음. 예를 들어 A와 B 사이의 자카드 유사도가 0.2보다 크면 간선을 만드는 식임