커리큘럼 홈
Phase 3

지식 그래프

Phase 3: Knowledge Graph (8주) - 실무 중심 재설계

목표: Neo4j 기반 Knowledge Graph를 구축하고, GraphRAG로 LLM과 연동할 수 있다.

기간: 2개월 (8주)

포트폴리오: 도메인 Knowledge Graph + GraphRAG 시스템

핵심 변경: RDF/OWL 학술 중심 → Neo4j/Cypher 실무 중심


🚀 Phase 3를 시작하며

Phase 2에서 데이터 분석과 ML 모델링을 배웠습니다.

하지만 현실의 데이터는 단순한 테이블이 아닙니다. 기업, 제품, 사람, 이벤트가 복잡하게 연결되어 있습니다.

예를 들어:

  • "삼성전자와 관련된 모든 협력사는?"
  • "이 환자와 비슷한 증상을 보인 다른 환자들은?"
  • "이 제품을 산 고객이 함께 구매한 다른 제품은?"

이런 관계 기반 질문에 답하려면 Knowledge Graph가 필요합니다.

Phase 3에서는:

  • 엔티티 간 관계를 모델링하고 (Neo4j)
  • 그래프 알고리즘으로 인사이트를 도출하고 (PageRank, 커뮤니티 탐지)
  • LLM과 그래프를 연결합니다 (GraphRAG)

Phase 2의 ML + Phase 3의 KG = 구조화된 지식 기반 AI


왜 Neo4j/Property Graph인가?

항목RDF/OWLProperty Graph (Neo4j)
학습 곡선가파름 (SPARQL, 온톨로지 이론)완만 (Cypher, SQL과 유사)
실무 채택률낮음 (연구/정부)높음 (기업 대부분)
도구 생태계제한적풍부 (Neo4j, GraphRAG, LangChain)
LLM 통합어려움GraphRAG, LangChain 네이티브
취업 시장극소수활발

RDF/OWL은 1주차에 개념만 소개하고, 나머지는 Neo4j 집중


Month 5: 그래프 데이터베이스 기초


Week 17: 그래프 이론 & Neo4j 입문

학습 목표

  • 그래프 데이터 모델의 개념과 장점을 설명할 수 있다
  • Neo4j를 설치하고 기본 조작을 할 수 있다
  • Cypher 기본 문법으로 CRUD를 수행할 수 있다
  • 관계형 DB와 그래프 DB의 차이를 이해할 수 있다

핵심 개념

1. 그래프 데이터 모델

Property Graph 구성 요소:

    ┌─────────────┐
    │   Node      │
    │ (노드/정점)  │
    │ - labels    │
    │ - properties│
    └──────┬──────┘
           │
    ┌──────▼──────┐
    │ Relationship│
    │ (관계/엣지)  │
    │ - type      │
    │ - properties│
    │ - direction │
    └─────────────┘

예시:
(Person:User {name: "Kim", age: 30})
    -[:FOLLOWS {since: 2023}]->
(Person:User {name: "Lee", age: 28})

관계형 vs 그래프

-- 관계형: 3단계 친구 찾기 (복잡한 JOIN)
SELECT DISTINCT f3.name
FROM users u
JOIN friendships f1 ON u.id = f1.user_id
JOIN friendships f2 ON f1.friend_id = f2.user_id
JOIN friendships f3 ON f2.friend_id = f3.user_id
JOIN users u3 ON f3.friend_id = u3.id
WHERE u.name = 'Kim' AND u3.id != u.id;
// 그래프: 동일 쿼리 (직관적)
MATCH (u:User {name: 'Kim'})-[:FRIEND*3]->(friend)
RETURN DISTINCT friend.name

2. Neo4j 설치 & 설정

# Docker로 설치 (권장)
docker run \
    --name neo4j \
    -p 7474:7474 -p 7687:7687 \
    -e NEO4J_AUTH=neo4j/password123 \
    -v $HOME/neo4j/data:/data \
    neo4j:latest

# 접속
# Browser: http://localhost:7474
# Bolt: bolt://localhost:7687

3. Cypher 기초

// CREATE - 노드 생성
CREATE (p:Person {name: 'Kim', age: 30, city: 'Seoul'})
RETURN p

// CREATE - 관계 생성
MATCH (a:Person {name: 'Kim'}), (b:Person {name: 'Lee'})
CREATE (a)-[:KNOWS {since: 2020}]->(b)

// READ - 노드 조회
MATCH (p:Person)
WHERE p.age > 25
RETURN p.name, p.age
ORDER BY p.age DESC
LIMIT 10

// READ - 관계 조회
MATCH (a:Person)-[r:KNOWS]->(b:Person)
RETURN a.name, type(r), b.name

// UPDATE
MATCH (p:Person {name: 'Kim'})
SET p.age = 31, p.updated = datetime()
RETURN p

// DELETE
MATCH (p:Person {name: 'Temp'})
DETACH DELETE p  // 관계도 함께 삭제

4. 패턴 매칭

// 단순 패턴
MATCH (a)-[:KNOWS]->(b)

// 양방향
MATCH (a)-[:KNOWS]-(b)

// 가변 길이 (1~3 hop)
MATCH (a)-[:KNOWS*1..3]->(b)

// 여러 관계 유형
MATCH (a)-[:KNOWS|FOLLOWS]->(b)

// 필터링
MATCH (a:Person)-[r:KNOWS]->(b:Person)
WHERE a.age > 25 AND r.since > 2020
RETURN a, r, b

실습 과제

과제: 소셜 네트워크 그래프 구축

요구사항:
1. Neo4j 환경 설정 (Docker 또는 Aura Free)
2. 데이터 모델링:
   - Person 노드 (name, age, city, interests)
   - KNOWS, FOLLOWS, WORKS_AT 관계
   - Company 노드 (name, industry)
3. 샘플 데이터 생성 (30+ 노드, 50+ 관계)
4. Cypher 쿼리 작성:
   - 특정 사용자의 친구 목록
   - 2촌 친구 찾기
   - 공통 친구 찾기
   - 같은 회사 동료
   - 특정 관심사를 가진 사람들
5. Neo4j Browser에서 시각화

산출물:
- Cypher 스크립트 (create_data.cypher)
- 쿼리 모음 (queries.cypher)
- 그래프 시각화 스크린샷

평가 기준

항목통과 기준배점
환경 설정Neo4j 정상 동작15%
데이터 모델3개 노드 타입, 3개 관계25%
데이터 생성30+ 노드, 50+ 관계20%
Cypher 쿼리5개 쿼리 정확30%
시각화의미 있는 그래프 표현10%

추천 자료

유형제목링크
공식Neo4j Getting Startedhttps://neo4j.com/docs/getting-started/
무료Neo4j Aura Freehttps://neo4j.com/cloud/aura-free/
코스Neo4j GraphAcademyhttps://graphacademy.neo4j.com/
영상Neo4j Fundamentalshttps://www.youtube.com/watch?v=8jNPelugC2s
치트시트Cypher Refcardhttps://neo4j.com/docs/cypher-refcard/current/

Week 18: Cypher 심화 & 데이터 모델링

학습 목표

  • 복잡한 Cypher 쿼리를 작성할 수 있다
  • 집계, 서브쿼리, APOC을 활용할 수 있다
  • 효과적인 그래프 데이터 모델을 설계할 수 있다
  • 관계형 데이터를 그래프로 마이그레이션할 수 있다

핵심 개념

1. Cypher 심화

// 집계
MATCH (p:Person)-[:KNOWS]->(friend)
RETURN p.name, count(friend) as friend_count
ORDER BY friend_count DESC

// COLLECT (배열로 수집)
MATCH (p:Person)-[:KNOWS]->(friend)
RETURN p.name, collect(friend.name) as friends

// WITH (파이프라인)
MATCH (p:Person)-[:KNOWS]->(friend)
WITH p, count(friend) as cnt
WHERE cnt > 5
RETURN p.name, cnt

// UNWIND (배열 풀기)
WITH ['Seoul', 'Busan', 'Incheon'] as cities
UNWIND cities as city
CREATE (:City {name: city})

// CASE 문
MATCH (p:Person)
RETURN p.name,
       CASE
         WHEN p.age < 20 THEN 'Teen'
         WHEN p.age < 40 THEN 'Adult'
         ELSE 'Senior'
       END as age_group

// 서브쿼리 (EXISTS)
MATCH (p:Person)
WHERE EXISTS {
  MATCH (p)-[:WORKS_AT]->(:Company {industry: 'Tech'})
}
RETURN p.name

2. APOC (Awesome Procedures on Cypher)

// 설치 확인
CALL apoc.help('apoc')

// JSON 로드
CALL apoc.load.json('https://api.example.com/data')
YIELD value
CREATE (p:Person {name: value.name})

// CSV 벌크 로드
LOAD CSV WITH HEADERS FROM 'file:///users.csv' AS row
CREATE (p:Person {
  name: row.name,
  age: toInteger(row.age)
})

// 배치 처리
CALL apoc.periodic.iterate(
  "MATCH (p:Person) RETURN p",
  "SET p.processed = true",
  {batchSize: 1000, parallel: true}
)

// 경로 탐색
MATCH (start:Person {name: 'Kim'}), (end:Person {name: 'Lee'})
CALL apoc.algo.dijkstra(start, end, 'KNOWS', 'weight')
YIELD path, weight
RETURN path, weight

// 그래프 내보내기
CALL apoc.export.json.all('graph.json', {})

3. 그래프 데이터 모델링

모델링 원칙:

1. 노드는 "명사" (Person, Product, Order)
2. 관계는 "동사" (PURCHASED, KNOWS, WORKS_AT)
3. 속성은 노드/관계의 특성 (name, since, amount)

안티 패턴:
❌ 관계를 노드로 만들기 (FRIENDSHIP 노드)
✅ 관계에 속성 추가 ([:KNOWS {since: 2020}])

❌ 배열 속성으로 관계 표현
✅ 명시적 관계로 연결

이커머스 예시:

// 모델
(:Customer)-[:PLACED]->(:Order)-[:CONTAINS]->(:Product)
(:Product)-[:BELONGS_TO]->(:Category)
(:Customer)-[:REVIEWED {rating: 5}]->(:Product)

// 추천 쿼리: 같은 상품을 산 다른 고객이 구매한 상품
MATCH (c:Customer {id: $customerId})-[:PLACED]->(:Order)-[:CONTAINS]->(p:Product)
      <-[:CONTAINS]-(:Order)<-[:PLACED]-(other:Customer)
      -[:PLACED]->(:Order)-[:CONTAINS]->(rec:Product)
WHERE NOT (c)-[:PLACED]->(:Order)-[:CONTAINS]->(rec)
RETURN rec.name, count(*) as score
ORDER BY score DESC
LIMIT 10

4. 관계형 → 그래프 마이그레이션

// 1. 테이블 → 노드
LOAD CSV WITH HEADERS FROM 'file:///customers.csv' AS row
CREATE (:Customer {
  id: row.customer_id,
  name: row.name,
  email: row.email
})

// 2. 외래키 → 관계
LOAD CSV WITH HEADERS FROM 'file:///orders.csv' AS row
MATCH (c:Customer {id: row.customer_id})
CREATE (c)-[:PLACED]->(:Order {
  id: row.order_id,
  date: date(row.order_date),
  total: toFloat(row.total)
})

// 3. 조인 테이블 → 관계
LOAD CSV WITH HEADERS FROM 'file:///order_items.csv' AS row
MATCH (o:Order {id: row.order_id}), (p:Product {id: row.product_id})
CREATE (o)-[:CONTAINS {quantity: toInteger(row.quantity)}]->(p)

실습 과제

과제: 이커머스 Knowledge Graph 구축

데이터: 제공된 CSV 또는 Kaggle 이커머스 데이터

요구사항:
1. 데이터 모델 설계:
   - ERD → 그래프 모델 변환
   - 노드: Customer, Order, Product, Category
   - 관계: PLACED, CONTAINS, BELONGS_TO, REVIEWED
2. 데이터 마이그레이션:
   - CSV 로드
   - 관계 생성
3. 비즈니스 쿼리 10개:
   - 고객별 주문 이력
   - 카테고리별 베스트셀러
   - 함께 구매된 상품 (장바구니 분석)
   - 고객 세그먼트별 선호 카테고리
   - 리뷰 기반 추천
4. 성능 최적화:
   - 인덱스 생성
   - 쿼리 프로파일링 (PROFILE)

산출물:
- 그래프 모델 다이어그램
- 마이그레이션 스크립트
- 비즈니스 쿼리 10개 + 설명
- 성능 최적화 리포트

평가 기준

항목통과 기준배점
모델 설계4개 노드, 4개 관계25%
마이그레이션데이터 정확히 로드25%
비즈니스 쿼리10개 중 8개 정확30%
성능인덱스 + PROFILE20%

추천 자료

유형제목링크
문서APOC Documentationhttps://neo4j.com/labs/apoc/
가이드Graph Data Modelinghttps://neo4j.com/developer/guide-data-modeling/
영상Graph Modeling Tipshttps://www.youtube.com/watch?v=oXziS-PPIUA

Week 19: 그래프 알고리즘

학습 목표

  • 중심성 알고리즘을 적용하여 중요 노드를 찾을 수 있다
  • 커뮤니티 탐지로 클러스터를 발견할 수 있다
  • 유사도 알고리즘으로 추천을 구현할 수 있다
  • 경로 탐색 알고리즘을 활용할 수 있다

핵심 개념

1. Graph Data Science (GDS) 라이브러리

// GDS 설치 확인
CALL gds.list()

// 그래프 프로젝션 (메모리에 로드)
CALL gds.graph.project(
  'myGraph',
  'Person',
  'KNOWS',
  {
    nodeProperties: ['age'],
    relationshipProperties: ['weight']
  }
)

// 프로젝션 확인
CALL gds.graph.list()

2. 중심성 (Centrality)

// PageRank - 영향력 있는 노드
CALL gds.pageRank.stream('myGraph')
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score
ORDER BY score DESC
LIMIT 10

// Betweenness - 브릿지 역할 노드
CALL gds.betweenness.stream('myGraph')
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score
ORDER BY score DESC

// Degree - 연결 수
CALL gds.degree.stream('myGraph')
YIELD nodeId, score
RETURN gds.util.asNode(nodeId).name AS name, score
ORDER BY score DESC
알고리즘의미비즈니스 활용
PageRank중요도/영향력인플루언서 발견
Betweenness중개자 역할정보 흐름 병목
Closeness접근성빠른 전파 가능 노드
Degree연결 수허브 노드

3. 커뮤니티 탐지

// Louvain - 모듈성 기반 커뮤니티
CALL gds.louvain.stream('myGraph')
YIELD nodeId, communityId
RETURN communityId, collect(gds.util.asNode(nodeId).name) AS members
ORDER BY size(members) DESC

// Label Propagation - 빠른 커뮤니티 탐지
CALL gds.labelPropagation.stream('myGraph')
YIELD nodeId, communityId
RETURN communityId, count(*) AS size

// 결과를 노드에 저장
CALL gds.louvain.write('myGraph', {writeProperty: 'community'})

4. 유사도 & 링크 예측

// Node Similarity (Jaccard)
CALL gds.nodeSimilarity.stream('myGraph')
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).name AS person1,
       gds.util.asNode(node2).name AS person2,
       similarity
ORDER BY similarity DESC
LIMIT 10

// KNN (K-Nearest Neighbors)
CALL gds.knn.stream('myGraph', {
  nodeProperties: ['age', 'income'],
  topK: 5
})
YIELD node1, node2, similarity
RETURN gds.util.asNode(node1).name, gds.util.asNode(node2).name, similarity

// 링크 예측: 미래 연결 가능성
CALL gds.linkPrediction.adamicAdar(
  gds.util.asNode($node1Id),
  gds.util.asNode($node2Id)
) YIELD score
RETURN score

5. 경로 탐색

// 최단 경로
MATCH (start:Person {name: 'Kim'}), (end:Person {name: 'Lee'})
CALL gds.shortestPath.dijkstra.stream('myGraph', {
  sourceNode: start,
  targetNode: end,
  relationshipWeightProperty: 'weight'
})
YIELD path, totalCost
RETURN [node IN nodes(path) | node.name] AS path, totalCost

// 모든 최단 경로
MATCH (start:Person {name: 'Kim'}), (end:Person {name: 'Lee'})
MATCH path = allShortestPaths((start)-[*]-(end))
RETURN path

실습 과제

과제: 소셜 네트워크 분석

데이터: Week 17 소셜 네트워크 확장 (100+ 노드)

요구사항:
1. 그래프 프로젝션 생성
2. 중심성 분석:
   - PageRank (인플루언서 Top 10)
   - Betweenness (브릿지 Top 5)
   - 중심성 점수를 노드에 저장
3. 커뮤니티 탐지:
   - Louvain 알고리즘 적용
   - 커뮤니티별 특성 분석
   - 시각화
4. 유사도 & 추천:
   - 친구 추천 (Node Similarity)
   - "알 수도 있는 친구" 구현
5. 경로 분석:
   - 두 사용자 간 분리 정도
   - 영향력 전파 경로

산출물:
- Cypher 스크립트
- 분석 결과 리포트
- 시각화 (Neo4j Bloom 또는 Python)
- 비즈니스 인사이트 3개

평가 기준

항목통과 기준배점
중심성3개 알고리즘 적용25%
커뮤니티탐지 + 해석25%
유사도추천 시스템 동작25%
인사이트비즈니스 활용 제안15%
시각화명확한 표현10%

추천 자료

유형제목링크
문서GDS Documentationhttps://neo4j.com/docs/graph-data-science/
코스Graph Algorithmshttps://graphacademy.neo4j.com/courses/gds-product-introduction/
영상PageRank Explainedhttps://www.youtube.com/watch?v=P8Kt6Abq_rM

Week 20: RDF/OWL 개념 & 시맨틱 웹 (1주 집중)

학습 목표

  • RDF 트리플의 구조를 이해할 수 있다
  • OWL 온톨로지의 개념을 설명할 수 있다
  • Property Graph와 RDF의 차이를 이해할 수 있다
  • 시맨틱 웹의 역사와 현재를 파악할 수 있다

핵심 개념 (개념 위주, 실습 최소화)

1. RDF (Resource Description Framework)

구조: Subject - Predicate - Object (트리플)

예시:
<http://example.org/person/Kim>
    <http://xmlns.com/foaf/0.1/name>
    "Kim Cheolsu" .

<http://example.org/person/Kim>
    <http://xmlns.com/foaf/0.1/knows>
    <http://example.org/person/Lee> .

형식: Turtle, RDF/XML, JSON-LD, N-Triples

2. SPARQL (SQL for RDF)

# 모든 사람과 이름 조회
SELECT ?person ?name
WHERE {
  ?person rdf:type foaf:Person .
  ?person foaf:name ?name .
}

# 특정 사람의 친구
SELECT ?friendName
WHERE {
  :Kim foaf:knows ?friend .
  ?friend foaf:name ?friendName .
}

3. OWL (Web Ontology Language)

클래스 계층:
Thing
├── Agent
│   ├── Person
│   └── Organization
└── Event
    ├── Meeting
    └── Conference

관계 정의:
- ObjectProperty: knows (Person → Person)
- DatatypeProperty: age (Person → Integer)
- Transitive: ancestorOf
- Symmetric: marriedTo
- Inverse: hasFather ↔ isFatherOf

4. Property Graph vs RDF

항목Property Graph (Neo4j)RDF
데이터 모델노드 + 관계 + 속성트리플 (S-P-O)
쿼리 언어CypherSPARQL
스키마유연 (선택적)온톨로지 (OWL)
추론제한적내장 (Reasoner)
생태계Neo4j, TigerGraphApache Jena, Virtuoso
사용처기업 애플리케이션연구, 정부, 의료

5. 시맨틱 웹 현황

성공 사례:
- Google Knowledge Graph (검색 향상)
- Wikidata (구조화된 위키피디아)
- FIBO (금융 온톨로지)
- FHIR (의료 데이터 표준)

한계:
- 학습 곡선 높음
- 도구 복잡
- 기업 채택 저조
- Property Graph가 실무에서 승리

현재 트렌드:
- Property Graph + LLM (GraphRAG)
- RDF는 특수 도메인 (의료, 금융, 정부)에서 사용

실습 (간단히)

과제: RDF/SPARQL 맛보기

요구사항 (2시간 분량):
1. Wikidata SPARQL 엔드포인트 사용:
   https://query.wikidata.org/
2. 간단한 SPARQL 쿼리 5개:
   - 모든 한국 도시
   - 특정 인물의 정보
   - 노벨상 수상자 목록
3. RDF/Property Graph 비교 리포트 (1페이지)

산출물:
- SPARQL 쿼리 5개
- 비교 리포트

추천 자료

유형제목링크
튜토리얼Wikidata SPARQLhttps://www.wikidata.org/wiki/Wikidata:SPARQL_tutorial
문서RDF Primerhttps://www.w3.org/TR/rdf11-primer/
영상Semantic Web Explainedhttps://www.youtube.com/watch?v=OGg8A2zfWKg

Month 6: 고급 Knowledge Graph & GraphRAG


Week 21: Entity Resolution & Knowledge Graph 구축

학습 목표

  • Entity Resolution으로 중복 엔티티를 통합할 수 있다
  • 다양한 소스에서 Knowledge Graph를 구축할 수 있다
  • 데이터 품질을 관리할 수 있다
  • 그래프 스키마를 진화시킬 수 있다

핵심 개념

1. Entity Resolution (ER)

# 문제: 같은 엔티티, 다른 표현
# "삼성전자", "Samsung Electronics", "Samsung", "SEC"

import recordlinkage

# 인덱싱 (비교 쌍 생성)
indexer = recordlinkage.Index()
indexer.block('city')  # 같은 도시만 비교
candidate_pairs = indexer.index(df)

# 비교
compare = recordlinkage.Compare()
compare.string('name', 'name', method='jarowinkler', threshold=0.85)
compare.exact('industry', 'industry')
features = compare.compute(candidate_pairs, df)

# 분류
matches = features[features.sum(axis=1) >= 2]
// Neo4j에서 Entity Resolution
// 1. 유사 노드 찾기
MATCH (a:Company), (b:Company)
WHERE a.id < b.id
  AND apoc.text.jaroWinklerDistance(a.name, b.name) > 0.85
RETURN a.name, b.name, apoc.text.jaroWinklerDistance(a.name, b.name) as similarity

// 2. 병합
MATCH (a:Company {name: 'Samsung'}), (b:Company {name: '삼성전자'})
CALL apoc.refactor.mergeNodes([a, b], {
  properties: 'combine',
  mergeRels: true
})
YIELD node
RETURN node

2. 다중 소스 통합

소스 예시:
- 내부 DB (고객, 제품)
- 외부 API (뉴스, SNS)
- 문서 (PDF, 계약서)
- 공개 데이터 (Wikidata, DBpedia)

통합 파이프라인:
1. Extract: 각 소스에서 엔티티/관계 추출
2. Normalize: 스키마 정규화
3. Match: Entity Resolution
4. Merge: 통합 그래프 생성
5. Validate: 품질 검증

3. 데이터 품질

// 고아 노드 (관계 없는 노드)
MATCH (n)
WHERE NOT (n)--()
RETURN labels(n), count(n)

// 중복 관계
MATCH (a)-[r1]->(b), (a)-[r2]->(b)
WHERE id(r1) < id(r2) AND type(r1) = type(r2)
RETURN a, b, count(*) as duplicates

// 필수 속성 누락
MATCH (p:Person)
WHERE p.name IS NULL OR p.email IS NULL
RETURN p

// 무결성 검사
MATCH (o:Order)-[:PLACED_BY]->(c:Customer)
WHERE c IS NULL
RETURN o.id as orphan_order

4. 스키마 진화

// 새 속성 추가
MATCH (p:Person)
SET p.createdAt = datetime()

// 레이블 추가
MATCH (p:Person)
WHERE p.isEmployee = true
SET p:Employee

// 관계 타입 변경
MATCH (a)-[r:KNOWS]->(b)
CREATE (a)-[:FRIEND {since: r.since}]->(b)
DELETE r

// 마이그레이션 스크립트
CALL apoc.periodic.iterate(
  "MATCH (p:Person) WHERE NOT EXISTS(p.status) RETURN p",
  "SET p.status = 'active'",
  {batchSize: 1000}
)

실습 과제

과제: 기업 Knowledge Graph 구축

데이터 소스:
1. 기업 정보 CSV (회사명, 산업, 직원수)
2. 뉴스 API (기업 관련 기사)
3. 관계 데이터 (협력, 경쟁, 투자)

요구사항:
1. 다중 소스 통합:
   - CSV 로드
   - 뉴스에서 기업명 추출 (간단한 NER)
2. Entity Resolution:
   - 기업명 정규화
   - 중복 통합
3. 관계 추출:
   - 뉴스에서 관계 추론 (키워드 기반)
4. 품질 관리:
   - 고아 노드 제거
   - 무결성 검사
5. 시각화 대시보드

산출물:
- 통합 파이프라인 코드
- Entity Resolution 결과
- 품질 리포트
- Neo4j Browser 시각화

평가 기준

항목통과 기준배점
소스 통합3개 소스 처리25%
Entity Resolution정확도 80% 이상25%
관계 추출의미 있는 관계20%
품질 관리검증 쿼리 5개20%
문서화파이프라인 설명10%

Week 22: Neo4j + Python 통합

학습 목표

  • Python에서 Neo4j를 연동할 수 있다
  • 그래프 데이터를 DataFrame으로 분석할 수 있다
  • 시각화 도구를 활용할 수 있다
  • ML과 그래프를 결합할 수 있다

핵심 개념

1. Neo4j Python Driver

from neo4j import GraphDatabase

class Neo4jConnection:
    def __init__(self, uri, user, password):
        self.driver = GraphDatabase.driver(uri, auth=(user, password))

    def close(self):
        self.driver.close()

    def query(self, query, parameters=None):
        with self.driver.session() as session:
            result = session.run(query, parameters)
            return [record.data() for record in result]

# 사용
conn = Neo4jConnection("bolt://localhost:7687", "neo4j", "password")

# 조회
results = conn.query("""
    MATCH (p:Person)-[:KNOWS]->(friend)
    WHERE p.name = $name
    RETURN friend.name as name, friend.age as age
""", {"name": "Kim"})

# DataFrame으로 변환
import pandas as pd
df = pd.DataFrame(results)

2. py2neo (고수준 OGM)

from py2neo import Graph, Node, Relationship

graph = Graph("bolt://localhost:7687", auth=("neo4j", "password"))

# 노드 생성
person = Node("Person", name="Kim", age=30)
graph.create(person)

# 관계 생성
friend = Node("Person", name="Lee", age=28)
knows = Relationship(person, "KNOWS", friend, since=2020)
graph.create(knows)

# OGM (Object Graph Mapping)
from py2neo.ogm import GraphObject, Property, RelatedTo

class Person(GraphObject):
    __primarykey__ = "name"

    name = Property()
    age = Property()
    friends = RelatedTo("Person", "KNOWS")

# 사용
kim = Person()
kim.name = "Kim"
kim.age = 30
graph.push(kim)

3. 시각화

# NetworkX + Matplotlib
import networkx as nx
import matplotlib.pyplot as plt

# Neo4j → NetworkX
query = """
MATCH (a:Person)-[r:KNOWS]->(b:Person)
RETURN a.name as source, b.name as target
"""
edges = conn.query(query)

G = nx.DiGraph()
for edge in edges:
    G.add_edge(edge['source'], edge['target'])

plt.figure(figsize=(12, 8))
pos = nx.spring_layout(G)
nx.draw(G, pos, with_labels=True, node_color='lightblue',
        node_size=500, font_size=10, arrows=True)
plt.savefig('graph.png')

# PyVis (인터랙티브)
from pyvis.network import Network

net = Network(notebook=True, height="600px", width="100%")
net.from_nx(G)
net.show("graph.html")

# neovis.js (Neo4j 전용)
# HTML에서 직접 Neo4j 연결

4. Graph + ML

# Node2Vec - 그래프 임베딩
from node2vec import Node2Vec

node2vec = Node2Vec(G, dimensions=64, walk_length=30, num_walks=200)
model = node2vec.fit(window=10, min_count=1)

# 노드 벡터 얻기
vector = model.wv['Kim']

# 유사 노드 찾기
similar = model.wv.most_similar('Kim', topn=5)

# 임베딩 → 분류/클러스터링
from sklearn.cluster import KMeans

embeddings = [model.wv[node] for node in G.nodes()]
kmeans = KMeans(n_clusters=5)
clusters = kmeans.fit_predict(embeddings)

실습 과제

과제: 그래프 분석 대시보드

요구사항:
1. Neo4j 연결 유틸리티 클래스
2. 분석 함수:
   - 기본 통계 (노드 수, 관계 수, 밀도)
   - 중심성 분석 결과 DataFrame
   - 커뮤니티 분포
3. 시각화:
   - NetworkX 정적 그래프
   - PyVis 인터랙티브 그래프
4. Node2Vec 임베딩:
   - 노드 임베딩 생성
   - 유사 노드 검색
   - 클러스터링 시각화
5. Streamlit 대시보드

산출물:
- Python 패키지 구조
- Streamlit 앱
- 문서화 (README)

평가 기준

항목통과 기준배점
연결안정적 연결15%
분석3개 분석 함수25%
시각화2가지 방식25%
임베딩Node2Vec 동작20%
대시보드Streamlit 완성15%

Week 23: GraphRAG 구현

학습 목표

  • GraphRAG의 개념과 장점을 설명할 수 있다
  • Neo4j + LLM을 연동할 수 있다
  • Knowledge Graph 기반 RAG를 구현할 수 있다
  • 벡터 검색과 그래프 탐색을 결합할 수 있다

핵심 개념

1. GraphRAG란?

기존 RAG:
Query → 벡터 검색 → 관련 청크 → LLM → 답변

문제:
- 문서 간 관계 놓침
- 다단계 추론 어려움
- "전체 맥락" 질문에 약함

GraphRAG:
Query → 그래프 탐색 + 벡터 검색 → 관련 엔티티/관계 → LLM → 답변

장점:
- 엔티티 간 관계 활용
- 다단계 추론 가능
- 구조화된 지식 활용

2. LangChain + Neo4j

from langchain_community.graphs import Neo4jGraph
from langchain.chains import GraphCypherQAChain
from langchain_openai import ChatOpenAI

# 그래프 연결
graph = Neo4jGraph(
    url="bolt://localhost:7687",
    username="neo4j",
    password="password"
)

# 스키마 확인
print(graph.schema)

# 자연어 → Cypher 변환
llm = ChatOpenAI(model="gpt-4", temperature=0)
chain = GraphCypherQAChain.from_llm(
    llm=llm,
    graph=graph,
    verbose=True,
    validate_cypher=True
)

# 질문
response = chain.invoke({
    "query": "김철수와 연결된 사람들은 누구인가요?"
})
print(response)

3. 하이브리드 검색 (Vector + Graph)

from langchain_community.vectorstores.neo4j_vector import Neo4jVector
from langchain_openai import OpenAIEmbeddings

# 벡터 인덱스 생성
vector_store = Neo4jVector.from_existing_graph(
    OpenAIEmbeddings(),
    url="bolt://localhost:7687",
    username="neo4j",
    password="password",
    index_name="person_index",
    node_label="Person",
    text_node_properties=["bio", "description"],
    embedding_node_property="embedding"
)

# 하이브리드 검색
def hybrid_search(query, k=5):
    # 1. 벡터 검색
    vector_results = vector_store.similarity_search(query, k=k)

    # 2. 엔티티 추출
    entities = extract_entities(query)

    # 3. 그래프 탐색
    cypher = """
    MATCH (e)-[r*1..2]-(related)
    WHERE e.name IN $entities
    RETURN DISTINCT related
    LIMIT $limit
    """
    graph_results = graph.query(cypher, {"entities": entities, "limit": k})

    # 4. 결합 및 랭킹
    return combine_and_rank(vector_results, graph_results)

4. Microsoft GraphRAG (참고)

# Microsoft GraphRAG 스타일 (개념)

# 1. 문서 → 엔티티/관계 추출
# 2. 커뮤니티 탐지 (Leiden)
# 3. 커뮤니티별 요약 생성
# 4. 쿼리 시:
#    - Local Search: 특정 엔티티 중심
#    - Global Search: 커뮤니티 요약 활용

# 장점: 전체 맥락 질문 가능
# 단점: 인덱싱 비용 높음 (LLM 호출 많음)

실습 과제

과제: 도메인 Knowledge Graph + QA 시스템

도메인 선택 (1개):
1. 영화/드라마 (IMDb 스타일)
2. 뉴스 기사 (기업/인물 관계)
3. 기술 문서 (API/라이브러리 관계)

요구사항:
1. Knowledge Graph 구축:
   - 100+ 노드
   - 다양한 관계 유형
2. 벡터 인덱스 추가:
   - 설명/내용 임베딩
3. GraphRAG 구현:
   - 자연어 → Cypher
   - 하이브리드 검색
4. 평가:
   - 질문 10개 테스트
   - 기존 RAG 대비 개선 확인
5. 데모:
   - Streamlit 챗봇

산출물:
- Knowledge Graph
- GraphRAG 파이프라인
- 평가 결과
- 데모 앱

평가 기준

항목통과 기준배점
KG 구축100+ 노드, 3+ 관계유형25%
벡터 인덱스임베딩 생성 완료20%
GraphRAGQA 동작25%
평가정량적 비교15%
데모사용 가능한 UI15%

추천 자료

유형제목링크
문서LangChain Neo4jhttps://python.langchain.com/docs/integrations/graphs/neo4j_cypher
GitHubMicrosoft GraphRAGhttps://github.com/microsoft/graphrag
영상GraphRAG Explainedhttps://www.youtube.com/watch?v=r09tJfON6kE
블로그Neo4j + LLMhttps://neo4j.com/developer-blog/knowledge-graph-rag-application/

Week 24: 도메인 Knowledge Graph 프로젝트

학습 목표

  • 실제 도메인에 맞는 Knowledge Graph를 설계할 수 있다
  • E2E KG 파이프라인을 구축할 수 있다
  • GraphRAG 기반 애플리케이션을 배포할 수 있다
  • 프로젝트를 문서화하고 발표할 수 있다

프로젝트 개요

포트폴리오 #3: 도메인 Knowledge Graph + GraphRAG 시스템

아키텍처:

[Data Sources]     [Processing]      [Knowledge Graph]    [Application]
┌─────────┐       ┌─────────┐       ┌─────────────┐      ┌─────────┐
│  CSV    │──────▶│ Entity  │──────▶│             │      │ Streamlit│
│  API    │       │ Extract │       │    Neo4j    │◀────▶│ ChatBot  │
│  Docs   │       │ + NER   │       │             │      │          │
└─────────┘       └─────────┘       └─────────────┘      └─────────┘
                       │                   │
                       ▼                   ▼
                  ┌─────────┐        ┌─────────┐
                  │ Entity  │        │ Vector  │
                  │ Resolve │        │ Index   │
                  └─────────┘        └─────────┘
                                          │
                                          ▼
                                     ┌─────────┐
                                     │GraphRAG │
                                     │  + LLM  │
                                     └─────────┘

도메인 옵션

도메인노드 예시관계 예시난이도
영화/엔터영화, 배우, 감독ACTED_IN, DIRECTED
기술 문서API, 라이브러리, 함수DEPENDS_ON, IMPLEMENTS
의료질병, 증상, 약물TREATS, CAUSES
금융회사, 인물, 거래INVESTED_IN, ACQUIRED
학술논문, 저자, 주제CITED_BY, AUTHORED

프로젝트 요구사항

1. 데이터 수집 & 처리

  • 최소 3개 데이터 소스
  • 500+ 노드, 1000+ 관계
  • Entity Resolution 적용

2. Knowledge Graph

  • 잘 설계된 스키마
  • 인덱스 최적화
  • 품질 검증

3. GraphRAG

  • 자연어 → Cypher
  • 하이브리드 검색
  • 10+ 질문 테스트

4. 애플리케이션

  • Streamlit 챗봇
  • 그래프 시각화
  • 배포 (Streamlit Cloud)

5. 문서화

  • README.md
  • 아키텍처 다이어그램
  • API 문서 (선택)

평가 기준

항목통과 기준배점
데이터3소스, 500+ 노드15%
KG 설계명확한 스키마, 품질20%
GraphRAGQA 정확도 80%+25%
배포 완료, 사용 가능20%
문서화README, 다이어그램10%
발표5분 데모10%

프로젝트 일정

일차활동산출물
1-2도메인 선정, 설계스키마, 아키텍처
3-4데이터 수집원본 데이터
5-6KG 구축Neo4j 그래프
7-8Entity Resolution정제된 그래프
9-10GraphRAG 구현QA 시스템
11앱 개발Streamlit 앱
12문서화 & 발표최종 산출물

Phase 3 완료 기준

필수 산출물

  1. Week 17: 소셜 네트워크 그래프
  2. Week 18: 이커머스 Knowledge Graph
  3. Week 19: 그래프 알고리즘 분석 리포트
  4. Week 20: RDF/SPARQL 비교 리포트
  5. Week 21: 기업 Knowledge Graph
  6. Week 22: 그래프 분석 대시보드
  7. Week 23: GraphRAG QA 시스템
  8. Week 24: 포트폴리오 #3 - 도메인 KG + GraphRAG

역량 체크리스트

  • Cypher로 복잡한 그래프 쿼리를 작성할 수 있다
  • 그래프 알고리즘을 적용하여 인사이트를 도출할 수 있다
  • 다중 소스에서 Knowledge Graph를 구축할 수 있다
  • GraphRAG로 LLM과 그래프를 연동할 수 있다
  • 도메인 KG 프로젝트를 E2E로 완수할 수 있다

자격증 (선택)


Phase 3 완료 → Phase 4: 클라우드 & 인프라로 이동