Hacker News를 모두 다운로드해 봤어요
(jasonthorsness.com)- hn.unlurker.com을 만들며 작성한 HN API 클라이언트에 전체 item을 순서대로 받는
scan기능을 넣고, Hacker News 전체 데이터를 로컬에 내려받음 hn scan --no-cache --asc -c- -o full.json실행 중 다운로드가 몇 차례 멈췄지만, 재개 가능한 scan 덕분에 몇 시간 뒤 20 GiB JSON 파일을 확보함- DuckDB의
read_json_auto로 JSON을 테이블화한 뒤,text ILIKE와 12주 이동평균 SQL로 Python, JavaScript, Java, Ruby, Rust 언급 비율을 집계함 - 단순
grep만으로도 “correct horse battery staple” 문구가 Hacker News에 231번 등장한 것을 확인했고, DuckDB는 이 규모의 일회성 분석에 잘 맞아 보임 - 로컬에 전체 데이터가 생기면 Hacker News의 과거 콘텐츠를 여러 방식으로 분석할 수 있지만, 이 프로젝트는 여기서 마무리되고 다음 단계는 다른 사람이 이어갈 몫으로 남음
Hacker News 전체 item 내려받기
- hn.unlurker.com을 만들기 위해 HN API 클라이언트를 작성함
- 이미 여러 클라이언트가 있었지만, 새 프로젝트에서 최신 Go 기능과 린터를 써보고 싶었음
- HN API에서 댓글과 스토리는 item으로 불림
- 클라이언트는 활성 item과 item 목록 등을 가져올 수 있음
- 실제 프로젝트에는 최근 item만 필요했지만, 완성도를 위해
scan기능을 추가함 scan은 item을 0부터 최신까지 또는 반대 방향으로 순서대로 다운로드함
- 실제 프로젝트에는 최근 item만 필요했지만, 완성도를 위해
- 전체 다운로드는 수만 GiB가 아니라 수십 GiB JSON 정도로 예상되어 시도함
hn scan --no-cache --asc -c- -o full.json
- 다운로드가 몇 차례 멈춰
CTRL-C로 중단했지만,scan이 재개 가능해서 몇 시간 뒤 완료됨 - 결과물은 Hacker News에서 발생한 모든 내용을 담은 20 GiB JSON 파일임
- 같은 명령을 다시 실행하면 최신 데이터로 다시 채울 수 있음
DuckDB로 로컬 데이터 분석하기
- 처음에는 단순히
grep으로 검색함- “correct horse battery staple” 문구는 Hacker News에 231번 등장함
- 마지막 등장 사례는 작성 시점 기준 “오늘” 올라온 item이었음
- 이후 DuckDB로 분석을 시도함
- DuckDB는 임베드 가능한 빠른 분석 실행 엔진이며 명령줄 도구로도 제공됨
- 새 UI 덕분에 초보자도 쓰기 쉬웠고, LLM이 SQL 쿼리 작성에 도움을 줌
- JSON 데이터는 DuckDB에서 다음 방식으로 가져옴
CREATE TABLE items AS
SELECT *
FROM read_json_auto('/home/jason/full.json', format='nd', sample_size=-1);
- 예시 쿼리는 주 단위로 item을 묶고, 전체 item 중 특정 단어가 포함된 비율을 계산함
python,javascript,java,ruby,rust를text ILIKE로 검색함- 각 비율에 대해 12주 이동평균을 계산함
- 같은 방식으로 데이터베이스 관련 단어도 시각화함
- 예시 그래프에는
mysql,postgres,mongo,redis,sqlite의 12주 이동평균 언급 비율이 포함됨
- 예시 그래프에는
- DuckDB는 이 정도 크기의 데이터셋을 분석하는 데 매우 좋아 보였음
- 전체 Hacker News 콘텐츠의 로컬 복사본을 갖게 되었지만, 프로젝트는 여기서 끝내기로 함
댓글과 토론
Hacker News 의견들
-
먼저 내려받지 않고도 분석을 돌릴 수 있는, 갱신된 Hacker News 테이블을 가진 데이터베이스를 두 가지 알고 있음
BigQuery는 Google Cloud 계정이 필요하고 쿼리는 아마 무료 등급으로 가능하며bigquery-public-data.hacker_news.full을 쓰면 됨
ClickHouse는 가입이 필요 없고 브라우저에서 바로 쿼리를 실행할 수 있음: https://play.clickhouse.com/play?user=play#U0VMRUNUICogRlJPT...- 심지어 이 댓글의
clickhouse도 찾아냄: https://play.clickhouse.com/play?user=play#U0VMRUNUICogRlJPT... - ClickHouse 리소스가 정말 훌륭함. 히스토리까지 있음
ClickHouse HN 데이터베이스를 알기 전에 이미 전체 JSON을 내려받는 작업을 직접 해봤었음
- 심지어 이 댓글의
-
예전에 @fesshole Twitter/Bluesky 계정으로 비슷한 일을 해봤음. 전체 아카이브를 내려받고 모델을 미세조정해서 더 정신 나간 고백들을 만들게 했음
꽤 뿌듯했는데, 결국 순진한 기계에게 자위와 이혼을 가르친 것뿐이라는 걸 깨달았음
SF 영화에서 외계인이나 초지능 AI가 인류 역사를 초고속으로 보고는 우리가 구할 가치가 없다고 판단하는 장면 같았음- “순진한 기계에게 자위와 이혼을”이라는 부분에서, 오래전에 사라진 문명의 펜드라이브를 발견해 그 텍스트 데이터로 모델을 학습시킨다고 해보자
그 데이터에 대한 외부 세계와의 연결이 전혀 없다면, 그 펜드라이브에 자위와 이혼에 관한 데이터가 들어 있다는 걸 사람이나 모델이 어떻게 알 수 있을까? - 자위와 이혼이 뭐가 문제인지 모르겠음. 각각 사람들이 더 행복하고 자립적으로 살 수 있게 하는 방법이고, 맞지 않는 상황에서 벗어나는 방법임
둘 다 전체적으로는 긍정적이라고 보며, 이런 것들이 정상화된 사회에 살 수 있어 감사함
- “순진한 기계에게 자위와 이혼을”이라는 부분에서, 오래전에 사라진 문명의 펜드라이브를 발견해 그 텍스트 데이터로 모델을 학습시킨다고 해보자
-
Java 쿼리는 JavaScript의 모든 사례도 포함하므로, Java가 과대표집됨
- 마찬가지로 Rust 쿼리도
trust,antitrust,frustration같은 단어들을 잔뜩 포함하게 됨 - 맞음… 그렇다면 하락세가 보이는 게 오히려 더 예상 밖일 수도 있겠음
- 마찬가지로 Rust 쿼리도
-
Hacker News에서 일어난 모든 일을 담은 20GiB JSON 파일이 있었다는 게, 텍스트만 있는 사이트라는 점을 생각하면 의외로 큼
HN이 존재한 18년 동안 사람들이 200억 바이트가 넘는 텍스트를 올렸다는 뜻인가? 하루 평균 2MB 이상, 초당 약 7.5KB 정도가 됨- 하루 2MB는 그리 많아 보이지 않음. 특히 Reddit 사태 이후 최근이자 가장 큰 “끝나지 않는 9월”이 오면서 게시물 수가 몇 년에 걸쳐 지수적으로 늘었을 가능성이 큼
게다가 그중 꽤 많은 양은 인간이 아닐 것임./newest는 봇 스팸으로 가득함 - 7.5KB/s, 즉 초당 7500자는 현실적으로 들리지 않아서 계산해봤더니[0], 실제로는 초당 약 34바이트, 즉 0.03KB/s에 가까움
JSON의 메타데이터와 문법까지 포함되어 있으니 실제 텍스트량은 그보다 더 낮을 것임. “하루 2MB 이상”이라는 계산은 맞았음
[0] 사실 계산은 ChatGPT가 했지만 맞아 보임: https://chatgpt.com/share/68124afc-c914-800b-8647-74e7dc4f21... - Reddit 전체 아카이브는 API를 제거하기 직전쯤 압축된 상태로 약 4TB였음. 예전에는 the-eye에 호스팅되어 있었고, 원한다면 아직도 파일을 토렌트할 수 있는 곳들이 있음
그중 상당수는 쓰레기지만, 특히 더 똑똑한 봇들이 등장한 2018~2019년 전의 초기 데이터는 살펴볼 가치가 있을 듯함 - 20GB JSON이라는 건 놀라움. 모든 HN 데이터를 담은 SQLite 파일을 갖고 있는데 그게 20GB라서, JSON이라면 훨씬 더 커야 할 것 같음
- 전체 용량은 오히려 작게 느껴짐. 거의 20년에 걸쳐 수십만 명의 활성 회원과 총 수백만 명이 기여한 결과임
HN은 Facebook 이전 기준으로는 꽤 큰 사회관계망이었을 것이고, 규모가 적당하고 활발히 관리된 덕분에 가치도 높은 편임
2019년에 Google+가 종료될 때 그 사이트에 기여된 텍스트 데이터가 얼마나 되는지 모델링해본 적이 있음
여기서 텍스트 데이터는 이미지·오디오·비디오 같은 미디어와 HTML 골격, CSS, JS 같은 부가 페이지 요소를 제외한 것임
참여율이 매우 낮고 게시물 평균이 약 120자였다는 점을 고려하면, 수천만 활성 계정의 7년 기록도 몇 GiB에 불과했음. 등록 프로필은 40억 개가 넘었지만 실제 활동은 훨씬 적었음
Archive Team은 Internet Archive와 협력하지만 별개로 Google+ 보존 작업을 했고, 성과는 복합적이었음. 많은 콘텐츠가 보존됐지만 훨씬 더 많은 것이 빠졌고, 댓글은 거의 남지 않았으며, 스레드는 최근 10개 정도로 잘렸고, 검색이 없어서 대체로 쓸모가 떨어졌음. 임의 해시가 아니라 선택한 계정명을 쓰는 “vanity accounts”는 접근성이 더 나빴음
게다가 전체 페이지를 스크레이핑해 온라인에서 보이던 형태를 재현하려 하면서 저장 요구량은 크게 늘리는 반면, 실제로 사이트를 흥미롭게 만들던 요소는 많이 놓치고 있음
큰 인구 집단의 텍스트 기여를 저장하려는 경우에도 저장 요구량은 꽤 modest함. 예를 들어 하루 평균 온라인 시간이 45분, 타자 속도 45wpm, 온라인 시간의 절반만 읽기가 아니라 쓰기라고 해도 사람당 하루 약 1,000단어, 즉 약 6KiB임. 1,000명당 6MiB, 100만 명당 6GiB, 10억 명당 6PiB 정도임
실제 값은 거의 확실히 더 낮음. 쓰기 시간이 과대평가됐고 실제로는 10%에 가까울 것이며, 모바일 입력 속도도 20~30wpm 정도일 가능성이 큼. 예컨대 Facebook에는 하루 약 24.5억 개의 “콘텐츠 조각”이 올라오고 그 절반이 비디오임. 게시물당 120자라고 보면 텍스트 데이터는 하루 300GiB보다 훨씬 적은, 의외로 작은 양임
현재 데이터 수집과 감시 자본주의 시스템의 대부분은 위치, 비디오, 온라인 상호작용, 상거래 같은 사람이 직접 입력하지 않은 데이터가 차지함
- 하루 2MB는 그리 많아 보이지 않음. 특히 Reddit 사태 이후 최근이자 가장 큰 “끝나지 않는 9월”이 오면서 게시물 수가 몇 년에 걸쳐 지수적으로 늘었을 가능성이 큼
-
HN을 내려받을 때의 네티켓은 뭘까? 서버에 부하를 주기 전에 dang에게 먼저 물어봐야 하나?
아니면 이제 수십억 달러 규모의 기술 기업들이 이미 여러 번 하고 있을 테니 눈에 띄지도 않을 거라고 봐도 되나?- 기사에도 나오듯 HN에는 API가 있고, 심지어 속도 제한도 없음. 모든 데이터는 YC 회사인 Firebase에 호스팅되어 있으니 괜찮음
- 말 그대로 공개 데이터베이스가 있음
https://console.cloud.google.com/marketplace/product/y-combi... - 세 글자 기관들이 HN 별칭에 실명을 붙이고 있을 가능성도 빼놓을 수 없음
- 이름이 Hacker News이니, 적어도 좋은 의미에서의 해킹은 공정한 게임
- 공개 웹에 올라온 것이라면 이미 수천 개의 봇이 스크레이핑하고 있음
-
비슷한 일을 해봤음. BigQuery 데이터셋을 쓰는 꼼수를 썼는데, 어째선지 계속 갱신되고 있었고, 데이터를 Parquet로 내보낸 뒤 내려받아 DuckDB로 질의했음
- 그건 꼼수가 아니라 그냥 실용적인 선택임
-
“이제 Hacker News의 모든 콘텐츠를 로컬에 내려받았으니, 수백 개의 LLM 기반 봇을 학습시켜 기여자로 돌리고, 과거를 영원히 메아리치고 재활용하는 중국어 방 진동자의 출력으로 모든 인간 텍스트를 천천히, 필연적으로 대체할 수 있다”는 농담이지만 언젠가 누군가는 시도할 것 같아 두려움
그런 일이 없길 바라지만, 일어난다면 막을 수 있을까?- 시간이 갈수록 더 중요해지는 오래된 아이디어를 점점 더 믿게 됨. 인간들 사이에 신뢰망을 만들어, 어떤 계정이 내가 모르는 누군가가 신뢰하고, 그 누군가는 내가 아는 사람이 신뢰하며, 그 사람은 내가 신뢰하는 식의 경로로 검증되게 하는 방식임
해결할 문제가 많고, 프라이버시도 그중 하나임. 연결 관계를 사용자에게 공개할 필요는 없지만, 순진한 구현에서는 서버에는 남게 됨
불신 경로를 음수 가중치로 더할 수도 있음. 직접 또는 간접적으로 누군가를 불신하면, 나와 그 사람을 잇는 신뢰 사슬의 값이 낮아지는 식임
네트워크이기 때문에 시스템을 조작하려는 시도에 스스로 조정될 수 있지만, 얼마나 견고할지는 여전히 질문으로 남음 - 이미 일어나고 있지 않다는 걸 어떻게 알 수 있나?
길고 내용이 있는 댓글은 보통 구분할 수 있지만, 1~2년 전보다 훨씬 어려워졌음. 짧은 한두 문장 댓글이라면 LLM은 이제 인간처럼 통과할 만큼 충분히 좋아졌다고 봄 - 우리 LLM들은 여러 출처에서 확인된 결과만 줄 수 있으므로 인간의 평균적인 응답만 출력함
반대로 HN의 많은 댓글은 평균적인 대중적 생각과 어긋나는 꽤 독특한 통찰임. 이것을 LLM이 흉내 내려 하면 헛소리만 내놓게 될 것임
그 헛소리에 합리적이고 말이 되는 답만 통과시키는 필터를 붙이면, 답변은 지루해지고 여전히 헛소리에 가까울 것임
답변이 정확하고 정밀하며 독특해지려면 LLM이 아닌 무언가를 써야 함 - HN에는 이미 이런 종류에 꽤 좋은 면역 체계가 있음. 저노력·반복 댓글은 빠르게 다운보트, 신고, 속도 제한을 당함
사이트의 카르마와 속도 휴리스틱은 화려한 기계학습에 비하면 조잡하지만, 커뮤니티가 Reddit이나 Twitter에 비해 작고 운영진이 직접 개입하기 때문에 작동함
LLM 가짜 계정 무리가 인간 텍스트를 “대체”하려면 사람들이 실제로 흥미롭다고 느끼는 글을 계속 올려야 함. 그렇지 않으면 훨씬 전에 제한되거나 조용히 제거될 것임
AI 계정 몇 개를 살려두더라도 한계비용이 큼. 24시간 새 스레드 수십 개에 추론을 돌리는 건 무료가 아니고, 출력이 흔한 SEO 쓰레기로 미끄러지지 않게 유지하는 것도 놀랄 만큼 어려움
수익도 사실상 없음. HN 트래픽을 현금화할 수 없고, 카르마는 봇 운영자에게 형편없는 화폐임
자원이 있는 집요한 악성 행위자를 막을 수 있냐면 아마 가능하겠지만, 대응책은 지금과 같을 것임. 강한 속도 제한, 신규 계정 상한 강화, 사람 운영자의 검토, 어쩌면 문체 분석 정도임
합법적인 신규 사용자에게는 성가시겠지만 치명적이지는 않음. 결국 HN은 여기 있는 인간들이 다른 인간의 글을 읽고 싶어 하기 때문에 살아남음. 댓글이 확률적 앵무새처럼 들리기 시작하면 독자는 무시하거나 신고할 것이고, 봇들은 서로에게 말하게 될 것임
GPT-3o가 작성함 - Metal Gear 프랜차이즈[0], 죽은 인터넷 이론[1] 등 이미 이런 흐름을 예견한 것들이 있음
“Metal Gear Solid 2에서 Hideo Kojima의 야심찬 각본은 포스트모던 비디오게임의 첫 사례로 평가받기도 했고, 탈진실 정치, 가짜 뉴스, 반향실, 대안적 사실 같은 개념을 예견했다는 평가도 받았다”
[0] https://en.wikipedia.org/wiki/Metal_Gear
[1] https://en.wikipedia.org/wiki/Dead_Internet_theory
- 시간이 갈수록 더 중요해지는 오래된 아이디어를 점점 더 믿게 됨. 인간들 사이에 신뢰망을 만들어, 어떤 계정이 내가 모르는 누군가가 신뢰하고, 그 누군가는 내가 아는 사람이 신뢰하며, 그 사람은 내가 신뢰하는 식의 경로로 검증되게 하는 방식임
-
앞으로 몇 년 안에 많은 API가 그냥 DuckDB 파일을 반환하는 옵션을 제공하기 시작할 것 같음
어차피 JSON을 데이터베이스에 적재할 거라면, 응답으로 데이터베이스를 받지 않을 이유가 없음- DuckDB 1.2 파일에서 내보낸 zstd Parquet가 2~3배 더 잘 압축됨
-
누적 차트는 쓰지 말아줬으면 함. 독자의 인상을 왜곡하지 않기가 거의 불가능하다고 봄
특정 데이터 지점의 높이를 잡음 속에서 가늠하기가 매우 어렵고, 아마 없을 의존성을 암시하기 때문임- 나도 처음 든 생각이 그거였음. uPlot 작성자가 함정을 잘 보여주는 데모를 갖고 있음: https://leeoniya.github.io/uPlot/demos/stacked-series.html
- 사실임 :( 하지만 같은 데이터를 선 그래프로 그리면 너무 많이 겹쳐서 아무것도 보기 어려웠음
다음에는 지역별로 하나의 계열만 담은 여러 선 그래프를 정렬해 쌓는 방식을 생각 중임 - 3D 접근이 이 문제를 해결하는 지점임. 쌓되 약간의 오프셋을 주면, 게임 엔진 기술을 실제 비즈니스 인텔리전스에 써서 대용량 데이터를 한 번에 이해하는 데 이보다 나은 게 없음
https://flowimmersive.com/의 작업을 보면 됨 - 로그 y축의 누적 플롯은 어떻게 생각하나? 어떤 물리 실험들은 늘 이렇게 하지만[1], 꽤 직관적이지 않다고 느낌
[1]: https://atlas.web.cern.ch/Atlas/GROUPS/PHYSICS/PUBNOTES/ATL-...
-
예전에 하나 만들었고 https://github.com/ashish01/hn-data-dumps 꽤 재미있었음
구현하면 멋질 기능은, 최근 항목일수록 시간이 지나며 더 자주 업데이트되므로 최근에 내려받은 항목이 오래된 항목보다 더 빨리 낡은 캐시가 된다는 점을 반영하는 것임- HN이 다른 많은 사이트처럼 잠그지 않고 이런 API를 제공해서 정말 좋음
나는 나이에 기반한 함수를 써서 오래됨을 판단했음. 처음에는 생성 후 1~2분 뒤부터 오래된 것으로 보고, 며칠 동안은 자주 갱신하다가, 첫 주 이후 빠르게 줄여서 약 2주가 지나면 불변으로 취급함
// DefaultStaleIf marks stale at 60 seconds after creation, then frequently for the first few days after an item is
// created, then quickly tapers after the first week to never again mark stale items more than a few weeks old.
const DefaultStaleIf = "(:now-refreshed)>" +
"(60.0*(log2(max(0.0,((:now-Time)/60.0))+1.0)+pow(((:now-Time)/(24.0*60.0*60.0)),3)))"
https://github.com/jasonthorsness/unlurker/blob/main/hn/core...
- HN이 다른 많은 사이트처럼 잠그지 않고 이런 API를 제공해서 정말 좋음