Counting sentiment words¶
Instead of a model’s probability, you can classify text by counting sentiment
words — the number and proportion of positive vs. negative words. kosac
provides this word-counting (frequency) method via count(). It is the approach
commonly used in content analysis and social-science studies.
Per-document counts¶
count() tallies each matched morpheme by its dominant label (max.value):
from kosac import SentimentAnalyzer
analyzer = SentimentAnalyzer("polarity")
c = analyzer.count("서비스가 형편없고 너무 실망스러웠다")["features"]["polarity"]
c["counts"] # {'COMP': 0, 'NEG': 3, 'NEUT': 0, 'None': 0, 'POS': 2}
c["proportions"] # {'NEG': 0.6, 'POS': 0.4, ...}
c["total"] # 5
c["label"] # 'NEG' (most frequent label)
Over a corpus¶
count_frame() returns one row per document, with a count column per label:
texts = [
"이 정책은 정말 훌륭하고 만족스럽다",
"서비스가 형편없고 너무 실망스러웠다",
"그저 그런 평범한 하루였다",
]
analyzer.count_frame(texts)
text polarity.label polarity.total polarity.NEG polarity.POS ...
0 이 정책은 정말 훌륭하고 만족스럽다 NEG 8 5 3
1 서비스가 형편없고 너무 실망스러웠다 NEG 5 3 2
2 그저 그런 평범한 하루였다 COMP 5 2 0
⚠️ Caveat: function morphemes add noise¶
Look at row 0: a clearly positive sentence is counted as NEG, because every matched morpheme is counted — including particles and endings (조사, 어미) whose lexicon polarity is noisy. This is a known limitation of the pure word-counting approach.
For per-sentence classification, prefer the probability method analyze(),
which weighs the evidence instead of counting it:
analyzer.analyze_frame(texts)
text polarity.label polarity.prob
0 이 정책은 정말 훌륭하고 만족스럽다 POS 0.59
1 서비스가 형편없고 너무 실망스러웠다 NEG 0.66
2 그저 그런 평범한 하루였다 NEG 0.46
Now row 0 is correctly POS.
When the count method shines: corpus-level trends¶
Word counts are most useful as descriptive statistics over a whole corpus, not single sentences. Sum the per-document counts to gauge the overall tone of a collection:
frame = analyzer.count_frame(texts)
totals = frame[["polarity.POS", "polarity.NEG", "polarity.NEUT"]].sum()
totals.to_dict()
# {'polarity.POS': 5, 'polarity.NEG': 10, 'polarity.NEUT': 1}
positivity = totals["polarity.POS"] / (totals["polarity.POS"] + totals["polarity.NEG"])
round(positivity, 3) # 0.333
With only three sentences here the noise still dominates (positivity is 0.33
despite a balanced set) — which is exactly why this method needs a large corpus.
Across thousands of documents the per-morpheme noise averages out and the
positive/negative ratio becomes a meaningful indicator, as used in the literature.
Reading texts from a file¶
count_frame / analyze_frame take any iterable of strings, so a pandas column
works directly:
import pandas as pd
df = pd.DataFrame({"text": texts}) # e.g. pd.read_csv("reviews.csv")
analyzer.count_frame(df["text"]).shape # (3, 8)