Sentiment Lexicon BuilderSAFE
Overview
An agent skill published by revfactory.
459e1bb8f76eOBSERVED · 2026-10-12What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
name: sentiment-lexicon-builder
description: "감성 사전 구축, ABSA(Aspect-Based Sentiment Analysis) 설계, 감성 점수 보정, 도메인 특화 감성 분석 방법론 가이드. '감성 사전', '감성 분석 모델', 'ABSA', '측면별 감성', '감성 점수', '극성 사전', '도메인 감성', '감정 분류' 등 감성분석 설계 시 이 스킬을 사용한다. sentiment-analyzer의 감성분석 역량을 강화한다. 단, 텍스트 전처리나 보고서 작성은 이 스킬의 범위가 아니다."
---
# Sentiment Lexicon Builder — 감성 사전 및 ABSA 설계 가이드
도메인 특화 감성 분석 시스템을 설계하고 구축하는 방법론.
## 감성 분석 접근법 비교
| 접근법 | 장점 | 단점 | 적합 |
|--------|------|------|------|
| 사전 기반 | 빠름, 해석 가능 | 도메인 한계, 문맥 무시 | 소규모, 빠른 프로토타입 |
| ML 기반 (전통) | 도메인 적응 | 학습 데이터 필요 | 레이블 데이터 있을 때 |
| 딥러닝 (BERT) | 문맥 이해, 높은 정확도 | 리소스 필요 | 대규모, 정확도 중시 |
| LLM (프롬프트) | 제로샷, 유연 | 비용, 속도 | 다양한 도메인, 소량 |
## 감성 사전 구축
### 한국어 기본 사전
```python
SENTIMENT_LEXICON = {
# 긍정 (1.0 ~ 0.1)
"좋다": 0.8, "훌륭하다": 0.9, "만족": 0.7, "추천": 0.8,
"편리하다": 0.7, "깔끔하다": 0.6, "최고": 0.9, "친절하다": 0.8,
"빠르다": 0.6, "저렴하다": 0.5,
# 부정 (-0.1 ~ -1.0)
"나쁘다": -0.8, "불만": -0.7, "실망": -0.8, "느리다": -0.6,
"비싸다": -0.5, "불편하다": -0.7, "최악": -0.9, "불친절": -0.8,
"고장": -0.7, "환불": -0.6,
# 강도 수정자
"매우": 1.5, # 강화
"약간": 0.5, # 약화
"정말": 1.5,
"조금": 0.5,
"너무": 1.3, # 문맥 따라 긍/부정 모두
}
NEGATION_WORDS = {"않다", "않", "못", "없다", "없", "안"}
```
### 도메인 특화 사전 자동 구축
```python
def build_domain_lexicon(corpus, labels, base_lexicon, top_n=200):
"""
TF-IDF + PMI 기반 도메인 감성 사전 자동 구축
1. 긍정/부정 리뷰에서 각각 TF-IDF 상위 단어 추출
2. PMI(Pointwise Mutual Information)로 감성 극성 계산
3. 기존 사전과 병합
"""
pos_texts = [t for t, l in zip(corpus, labels) if l == 'positive']
neg_texts = [t for t, l in zip(corpus, labels) if l == 'negative']
# 각 클래스에서의 출현 확률
for word in vocabulary:
p_word = count(word, corpus) / len(corpus)
p_pos = count(word, pos_texts) / len(pos_texts)
p_neg = count(word, neg_texts) / len(neg_texts)
pmi_pos = log2(p_pos / p_word) if p_pos > 0 else 0
pmi_neg = log2(p_neg / p_word) if p_neg > 0 else 0
polarity = pmi_pos - pmi_neg # 양수=긍정, 음수=부정
return domain_lexicon
```
## ABSA (Aspect-Based Sentiment Analysis)
### 설계 구조
```
입력: "배송은 빠른데 제품 품질이 별로예요"
1. 측면(Aspect) 추출:
- "배송" → [배송/서비스]
- "품질" → [제품/품질]
2. 측면별 감성 분석:
- 배송: "빠른" → 긍정 (0.6)
- 품질: "별로" → 부정 (-0.7)
3. 결과:
{
"overall": -0.05,
"aspects": {
"배송": {"sentiment": "positive", "score": 0.6, "keywords": ["빠른"]},
"품질": {"sentiment": "negative", "score": -0.7, "keywords": ["별로"]}
}
}
```
### 측면 카테고리 설계 (이커머스 예시)
```yaml
aspects:
제품:
품질: [품질, 퀄리티, 소재, 재질, 마감, 내구성]
디자인: [디자인, 색상, 색깔, 모양, 외관]
사이즈: [사이즈, 크기, 사이즈감, 피팅]
가격: [가격, 가성비, 비싸, 저렴, 합리적]
서비스:
배송: [배송, 택배, 도착, 배달]
포장: [포장, 박스, 패키지]
교환환불: [교환, 환불, 반품, AS]
고객응대: [응대, 상담, 친절, 불친절]
```
## 감성 점수 보정
### 부정어 처리
```python
def handle_negation(tokens, scores):
"""부정어 뒤 3토큰 이내 감성 반전"""
negation_window = 0
adjusted = []
for token, score in zip(tokens, scores):
if token in NEGATION_WORDS:
negation_window = 3
elif negation_window > 0:
score = -score * 0.8 # 완전 반전이 아닌 80% 반전
negation_window -= 1
adjusted.append(score)
return adjusted
```
### 강도 수정자 처리
```python
def apply_intensifiers(tokens, scores):
"""강도 수정자에 따른 점수 조정"""
adjusted = []
for i, (token, score) in enumerate(zip(tokens, scores)):
if i > 0 and tokens[i-1] in INTENSIFIERS:
score *= INTENSIFIERS[tokens[i-1]]
adjusted.append(score)
return adjusted
```
### 이모지 감성 매핑
```python
EMOJI_SENTIMENT = {
"😊": 0.8, "😍": 0.9, "👍": 0.7, "❤️": 0.8, "🙏": 0.5,
"😡": -0.9, "😤": -0.7, "👎": -0.8, "😢": -0.6, "💔": -0.7,
"😐": 0.0, "🤔": -0.1,
}
```
## 감성 분석 평가 메트릭
```python
# 감성 분류 평가
from sklearn.metrics import classification_report
print(classification_report(y_true, y_pred,
target_names=['부정', '중립', '긍정']))
# ABSA 평가
# - 측면 추출: Precision, Recall, F1
# - 측면별 감성: Accuracy, Macro-F1
# - 전체: Micro-F1 (측면추출 + 감성 모두 정확해야 정답)
```
## 보고서 구조
```markdown
## 감성 분석 결과
### 전체 요약
| 극성 | 건수 | 비율 |
|------|------|------|
| 긍정 | 650 | 65% |
| 중립 | 150 | 15% |
| 부정 | 200 | 20% |
### 측면별 감성
| 측면 | 긍정 | 부정 | 점수 | 주요 키워드 |
|------|------|------|------|-----------|
| 배송 | 80% | 10% | +0.6 | 빠른, 정확 |
| 품질 | 40% | 45% | -0.2 | 별로, 약함 |
### 시계열 추이
### 주요 부정 패턴 (액션 아이템)
```Trust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | NA |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (0)
No findings outside the package's declared scope.
Gates applied: no_behavioural_pass.
459e1bb8f76efull audit observations/trust-audit/skill/revfactory__sentiment-lexicon-builder.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-12 | 459e1bb8f76e | SAFE | B | 89 | first audit |
Questions
Is Sentiment Lexicon Builder safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can Sentiment Lexicon Builder access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
How current is this page?
The grade is for one exact copy of the source (459e1bb8f76e), read on 2026-10-12. The repository is watched, and a new audit runs when it changes — this is the first audit.