기본 콘텐츠로 건너뛰기

방송대 방통대 파이썬프로그래밍기초 13강 - 실전 프로젝트: 텍스트 데이터 분석기 - 요약 노트 시험족보 예상문제 - 올에이클래스

파이썬프로그래밍기초 13강 - 실전 프로젝트: 텍스트 데이터 분석기

파이썬프로그래밍기초 13강 - 실전 프로젝트: 텍스트 데이터 분석기

지금까지 배운 파일 처리, 문자열, 리스트, 딕셔너리와 함수를 결합하여 텍스트 데이터 분석기를 설계한다. 원시 텍스트를 불러와 전처리하고 단어 빈도를 계산한 뒤 빈도순으로 정렬하여 텍스트 기반으로 시각화하는 전체 데이터 분석 파이프라인을 익힌다.

제1장 프로젝트 개요

1. 텍스트 데이터 분석기의 목표

이번 프로젝트는 텍스트 파일을 읽고 의미 있는 키워드를 추출한 뒤, 키워드를 시각적으로 표현하여 파일로 출력하는 전체 과정을 구현하는 것이다. 단순히 단어 수를 세는 데 그치지 않고 원시 데이터가 분석 결과로 바뀌는 파이프라인을 설계한다.

입력은 가공되지 않은 원시 텍스트 데이터(raw data)이고 출력은 분석 목적에 맞게 정리된 정보(information)다. 프로젝트의 분석 대상은 셜록 홈즈 전집 텍스트로, 강의록에는 https://sherlock-holm.es에서 제공하는 약 657,410단어 규모의 소설 원문이 제시된다.

프로젝트의 핵심 질문

“긴 소설에서 어떤 단어가 중요하며 얼마나 자주 등장하는가?”를 프로그램으로 분석한다. 이를 위해 파일 입력, 문자열 정제, 단어 집계, 정렬과 결과 표현이 하나의 흐름으로 연결되어야 한다.

2. 프로젝트에서 활용하는 파이썬 개념

파일을 열고 읽는 파일 입출력, 대소문자를 통일하고 기호를 제거하는 문자열 메소드, 단어를 순서대로 저장하는 리스트, 단어와 빈도를 대응시키는 딕셔너리, 기능을 나누어 구현하는 함수가 함께 사용된다. 앞에서 배운 개념이 독립된 문법 지식이 아니라 실전 문제를 해결하는 도구로 결합된다.

개념프로젝트에서의 역할
파일 입출력분석할 텍스트 파일을 선택하고 읽음
문자열소문자 변환, 불필요한 기호 제거, 단어 분리
리스트정제된 단어 목록과 정렬된 빈도 목록 저장
딕셔너리단어를 키, 등장 횟수를 값으로 저장
함수전처리·빈도 계산·정렬·출력을 독립 기능으로 분리

제2장 데이터 분석의 생애주기

1. 원시 데이터에서 인사이트까지

데이터 분석은 원시 데이터가 의미 있는 인사이트가 되기까지 표준화된 단계를 거친다. 강의록에서는 데이터 수집, 전처리, 분석, 시각화의 네 단계로 데이터 분석 파이프라인을 설명한다.

단계핵심 활동텍스트 분석기 적용
Collection파일 입출력을 통해 외부 데이터 확보셜록 홈즈 텍스트 파일 선택 및 읽기
Preprocessing분석 가능한 형태로 정제·변환소문자 변환, 구두점 제거, 불용어 제거, 단어 분리
Analysis통계·알고리즘을 적용하여 가치 있는 패턴 추출단어별 등장 빈도 계산과 순위 산출
Visualization인지 부담을 줄이고 정보를 쉽게 파악하도록 표현빈도에 비례한 텍스트 그래프 출력

2. 전처리가 필요한 이유

입력 데이터의 품질이 낮으면 아무리 정교한 분석 기법을 사용해도 잘못된 결과가 나온다. 이를 GIGO(Garbage In, Garbage Out), 즉 쓰레기가 들어가면 쓰레기가 나온다는 원칙으로 설명한다. 데이터 품질을 높여 분석 결과의 신뢰성을 높이려면 전처리가 필요하다.

예를 들어 Holmes, holmes, HOLMES를 서로 다른 단어로 세면 실제 빈도가 분산된다. holmes,holmes.에 구두점이 붙어 있어도 다른 값으로 집계될 수 있다. 대소문자를 통일하고 문장부호를 제거해야 같은 의미의 단어가 하나로 합쳐진다.

전처리는 분석 전에 수행한다

전처리는 결과를 보기 좋게 꾸미는 단계가 아니라 분석할 데이터의 기준을 통일하는 단계다. 어떤 단어를 제거하고 어떤 기호를 바꾸는지에 따라 최종 빈도 순위가 달라질 수 있다.

제3장 프로그램의 구조와 기능 분할

1. 전체 처리 흐름

프로그램은 데이터 로드, 불용어 필터링을 포함한 전처리, 빈도 분석, 텍스트 시각화 순서로 실행된다. 각 단계의 출력은 다음 단계의 입력이 된다. 원시 문자열은 정제된 단어 리스트로, 단어 리스트는 빈도 딕셔너리로, 빈도 딕셔너리는 정렬된 목록으로 변환된다.

분석 파이프라인

데이터 로드 → 불용어 필터링과 텍스트 전처리 → 단어 빈도 분석 → 빈도순 정렬 → 텍스트 시각화 및 저장

2. 함수 단위의 코드 구조

긴 프로그램을 하나의 코드 블록으로 작성하면 각 단계의 역할을 파악하고 수정하기 어렵다. 강의록은 주요 기능을 함수 단위로 나누어 설계한다.

함수역할입력과 출력의 예
clean_text(text)텍스트를 분석하기 쉬운 형태로 정제원시 문자열 → 정제된 단어 리스트
count_words(word_list)각 단어의 등장 횟수 계산단어 리스트 → 빈도 딕셔너리
get_sorted_list(counts_dict)빈도값을 기준으로 항목 정렬빈도 딕셔너리 → 정렬된 키-값 목록
print_save_graph(data)빈도를 텍스트 그래프로 출력하고 저장정렬된 데이터 → 화면 및 파일 결과

기능을 함수로 분리하면 한 단계의 구현을 바꾸더라도 다른 부분에 미치는 영향을 줄일 수 있다. 또한 함수별로 입력과 출력을 확인하여 오류가 발생한 단계를 쉽게 찾을 수 있다.

제4장 데이터 로드와 파일 선택

1. 사용자 인터랙티브 파일 선택

분석할 파일의 경로를 프로그램 안에 고정하면 다른 파일을 분석할 때 코드를 수정해야 한다. 사용자 인터랙티브 방식은 프로그램 실행 중 파일 선택 창을 열거나 사용자 입력을 받아 대상 파일을 선택하게 한다. 파일 선택 기능을 제공하면 프로그램의 재사용성이 높아진다.

2. 운영체제 기능과 OS 모듈

파일 복사, 폴더 생성, 경로 확인 같은 작업은 운영체제의 파일 시스템 기능과 관련된다. 파이썬의 os 모듈은 Windows, macOS, Linux처럼 서로 다른 운영체제에서 파일과 경로를 다루는 기능을 제공한다.

현재 작업 폴더(Current Working Directory, CWD)는 파이썬 프로그램이 실행 중인 기준 위치다. 상대 경로로 파일을 찾거나 결과 파일을 저장할 때 현재 작업 폴더가 기준이 된다. 따라서 프로그램이 어떤 폴더에서 실행되고 있는지 확인하는 것이 중요하다.

import os

print(os.getcwd())
file_name = input("분석할 텍스트 파일 경로를 입력하세요: ")

with open(file_name, "r", encoding="utf-8") as file:
    raw_text = file.read()

강의의 핵심은 사용자가 파일을 선택하고 프로그램이 그 내용을 문자열로 읽어 다음 전처리 단계에 전달하는 것이다.

제5장 텍스트 전처리

1. 불용어의 정의

불용어(stopwords)는 문법적으로 자주 등장하지만 분석 목적에서는 의미가 적은 단어다. 영어 텍스트의 a, the, is, are, of, at 등이 예다. 이런 단어는 빈도가 매우 높아 주요 인물이나 사건 관련 단어를 가릴 수 있으므로 분석 목적에 맞게 필터링한다.

모든 분석에 동일한 불용어 목록을 적용할 수 있는 것은 아니다. 어떤 단어가 의미 없는지는 분석 대상과 목적에 따라 달라지므로 적절한 불용어 목록을 선택해야 한다.

2. 분석 기준을 통일하는 문자열 처리

같은 단어를 하나로 집계하려면 Apple, apple, APPLE을 모두 소문자로 바꾸는 것이 좋다. 강의록은 lower(), replace(old, new), split()을 주요 문자열 메소드로 제시한다.

메소드전처리 역할
lower()영문자를 소문자로 바꾸어 대소문자 차이 제거
replace(old, new)문장부호와 불필요한 기호를 공백 등으로 교체
split()공백을 기준으로 문자열을 단어 리스트로 분리

3. clean_text 함수 설계

def clean_text(text):
    stopwords = {"a", "the", "is", "are", "of", "at"}
    text = text.lower()

    for mark in [".", ",", "!", "?", ";", ":", '"', "'"]:
        text = text.replace(mark, " ")

    words = text.split()
    return [word for word in words if word not in stopwords]

함수는 원시 문자열을 받은 뒤 대소문자를 통일하고 문장부호를 제거하며, 단어 단위로 분리한 뒤 불용어를 제외한다. 결과는 빈도 분석에 바로 사용할 수 있는 단어 리스트다.

전처리 순서

대소문자 통일 → 구두점·특수문자 처리 → 단어 분리 → 불용어 제거 순으로 진행하면 같은 단어가 서로 다른 형태로 집계되는 문제를 줄일 수 있다.

제6장 단어 빈도 분석

1. 딕셔너리의 키-값 모델

단어 빈도는 딕셔너리로 표현하기 적합하다. 키에는 고유한 분석 단어를 저장하고 값에는 그 단어의 등장 횟수를 저장한다. 같은 단어가 다시 나타날 때마다 기존 값에 1을 더한다.

2. 빈도 계산의 두 경우

현재 단어가 딕셔너리에 이미 있으면 기존 카운트에 1을 더한다. 처음 등장한 단어라면 값을 1로 초기화한다. in 연산자로 키의 존재 여부를 나눌 수도 있지만, get 메소드를 사용하면 한 문장으로 표현할 수 있다.

def count_words(word_list):
    counts = {}

    for word in word_list:
        counts[word] = counts.get(word, 0) + 1

    return counts

counts.get(word, 0)은 키가 있으면 현재 빈도를 반환하고, 없으면 기본값 0을 반환한다. 여기에 1을 더해 다시 저장하면 처음 등장한 단어는 1, 기존 단어는 이전 값보다 1 큰 빈도가 된다.

get을 이용한 누적 패턴

dictionary[key] = dictionary.get(key, 0) + 1은 항목 존재 여부를 별도의 조건문으로 나누지 않고 빈도를 누적하는 대표적인 패턴이다.

제7장 데이터 정렬과 시각화

1. 빈도값 기준 정렬

분석 결과에서 자주 등장한 단어를 먼저 보려면 빈도값을 기준으로 내림차순 정렬해야 한다. 딕셔너리는 항목을 키로 관리하므로 빈도값 순서를 직접 나타내기보다 items()로 키-값 쌍을 얻고 sorted 함수로 정렬된 리스트를 만든다.

def get_sorted_list(counts_dict):
    return sorted(
        counts_dict.items(),
        key=lambda item: item[1],
        reverse=True
    )

item[1]은 각 (단어, 빈도) 튜플의 빈도를 뜻한다. reverse=True를 지정하면 큰 빈도부터 작은 빈도 순으로 정렬된다. 강의록의 예에는 holmes, times, watson, mr 같은 단어가 높은 빈도로 제시된다.

2. 데이터 시각화의 목적

데이터 시각화는 복잡한 데이터를 시각적인 형태로 표현하는 과정이다. 데이터에 대한 인사이트를 제공하고 효과적인 의사소통과 의사결정을 지원한다. 단어와 숫자만 나열하는 것보다 빈도의 상대적인 크기를 함께 표현하면 중요한 단어를 빠르게 파악할 수 있다.

3. 텍스트 기반 시각화

실습에서는 별도의 그래프 라이브러리 없이 텍스트만으로 데이터 크기를 표현한다. 가장 큰 빈도를 기준으로 막대 길이를 비례 조정한 뒤 문자 기호를 반복하여 화면에 출력하거나 파일에 저장할 수 있다. Matplotlib이나 Bokeh가 없어도 반복과 문자열 연산으로 간단한 막대그래프를 만들 수 있다.

def print_save_graph(data):
    if not data:
        return

    max_count = data[0][1]

    with open("word_frequency.txt", "w", encoding="utf-8") as file:
        for word, count in data:
            bar_length = int(count / max_count * 40)
            line = f"{word:15} {count:5} {'#' * bar_length}"
            print(line)
            file.write(line + "\n")

가장 빈도가 높은 단어의 막대를 40칸으로 두고 다른 단어는 비율에 맞춰 길이를 계산한다. 출력 순서는 이미 빈도 내림차순으로 정렬되어 있으므로 상위 단어부터 확인할 수 있다.

4. 전체 프로그램의 연결

with open(file_name, "r", encoding="utf-8") as file:
    raw_text = file.read()

word_list = clean_text(raw_text)
counts_dict = count_words(word_list)
sorted_data = get_sorted_list(counts_dict)
print_save_graph(sorted_data)

각 함수의 반환값이 다음 함수의 입력으로 전달된다. 이 구조는 분석 단계가 분명하고 함수별 테스트가 쉬우며, 전처리 규칙이나 시각화 방식을 변경하기도 쉽다.

프로젝트 설계의 핵심

원시 데이터를 곧바로 집계하지 않고, 분석 목적에 맞게 품질을 높인 뒤 구조화하여 분석하고 사람이 이해하기 쉬운 결과로 표현한다. 데이터 흐름과 함수의 책임을 명확히 나누는 것이 정확하고 확장 가능한 프로그램의 출발점이다.

핵심 개념 정리

① 프로젝트 목표: 텍스트 파일에서 의미 있는 키워드를 추출하고 빈도를 시각화하여 파일로 출력한다.

② 분석 생애주기: Collection, Preprocessing, Analysis, Visualization 순으로 진행한다.

③ 전처리: GIGO를 방지하기 위해 대소문자와 기호를 통일하고 불용어를 제거한다.

④ 파일 선택: 사용자 입력과 운영체제의 파일 시스템 기능을 활용하며 현재 작업 폴더를 이해해야 한다.

⑤ 빈도 분석: 딕셔너리에 단어를 키, 빈도를 값으로 저장하고 get으로 누적한다.

⑥ 정렬: items()의 키-값 쌍을 빈도값 기준 내림차순으로 정렬한다.

⑦ 시각화: 빈도의 상대적 크기를 텍스트 막대 길이로 표현하여 화면과 파일에 출력한다.

최종 정리

실전 데이터 분석 프로그램은 문법 하나가 아니라 파일, 문자열, 리스트, 딕셔너리, 반복문과 함수의 협력으로 완성된다. 각 단계의 입력과 출력을 분명히 설계하면 큰 데이터도 일관된 절차로 처리할 수 있다.

예상문제 20선

1. 이번 프로젝트의 주된 목표는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
텍스트 파일을 정제하고 단어 빈도를 계산한 뒤 빈도순 결과를 시각화하는 것이 프로젝트의 목표다.

2. 데이터 분석 생애주기의 올바른 순서는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
외부 데이터를 수집하고 분석 가능한 형태로 정제한 뒤 분석하며 마지막에 결과를 시각화한다.

3. GIGO 원칙이 강조하는 내용은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
입력 데이터의 품질이 낮으면 분석 알고리즘이 좋아도 신뢰할 수 없는 결과가 나온다.

4. 원시 문자열을 분석 가능한 단어 리스트로 정제하는 함수는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
clean_text는 대소문자와 기호를 정리하고 불용어를 제외하여 단어 목록을 만든다.

5. 현재 작업 폴더를 의미하는 약어는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
CWD는 Current Working Directory로 프로그램이 현재 작업 중인 기준 폴더다.

6. 파일과 폴더, 경로 같은 운영체제 기능을 다루는 파이썬 모듈은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
os 모듈은 운영체제와 상호작용하며 현재 경로와 파일 시스템 관련 기능을 제공한다.

7. 불용어에 대한 설명으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
a, the, is처럼 빈도는 높지만 분석 목적에서 정보량이 적은 단어를 불용어로 제외할 수 있다.

8. Apple, apple, APPLE을 같은 단어로 집계하기 위해 사용하는 메소드는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
lower는 모든 영문자를 소문자로 바꾸어 대소문자 차이를 없앤다.

9. 문자열을 공백 기준의 단어 리스트로 나누는 메소드는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
인수를 생략한 split()은 연속된 공백을 기준으로 문자열을 나누어 리스트를 반환한다.

10. 단어 빈도 분석에 가장 적합한 자료형은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
딕셔너리는 각 고유 단어와 그 단어의 등장 횟수를 키-값 관계로 표현할 수 있다.

11. counts.get(word, 0)에서 두 번째 인수 0의 의미는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
처음 등장한 단어는 기존 값이 없으므로 기본값 0에서 1을 더해 빈도 1로 시작한다.

12. 빈도 딕셔너리를 정렬하기 전에 키-값 쌍을 얻는 메소드는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
items()는 각 항목을 (키, 값) 쌍으로 제공하여 빈도값 기준 정렬에 사용할 수 있다.

13. 빈도가 큰 단어부터 정렬하려면 sorted에 지정할 설정은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
키-값 쌍의 두 번째 원소인 빈도를 정렬 기준으로 삼고 역순을 지정해야 내림차순이 된다.

14. get_sorted_list 함수의 입력으로 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
이 함수는 빈도 딕셔너리의 항목을 빈도값 기준으로 정렬된 목록으로 변환한다.

15. 데이터 시각화의 주된 목적은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
시각화는 인지 부담을 줄이고 중요한 패턴을 빠르게 발견하여 의사소통과 의사결정을 돕는다.

16. 그래프 라이브러리 없이 빈도 크기를 표현하는 방법으로 강의에서 제시한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
문자열 반복을 이용하면 Matplotlib이나 Bokeh 없이도 빈도에 비례하는 텍스트 그래프를 만들 수 있다.

17. 함수 단위로 프로그램을 나누는 장점은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①
로드, 전처리, 분석, 정렬, 출력 기능을 분리하면 각 단계의 입력과 출력을 독립적으로 확인할 수 있다.

18. replace(old, new)의 전처리 용도로 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②
구두점을 공백으로 교체하면 word,word.를 같은 단어 word로 분리할 수 있다.

19. 전체 파이프라인에서 count_words 바로 앞에 실행되어야 하는 함수는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③
먼저 원시 텍스트를 정제한 단어 리스트로 만든 뒤 그 리스트를 빈도 계산 함수에 전달해야 한다.

20. 프로젝트의 데이터 변환 흐름으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④
각 단계가 앞 단계의 결과를 입력으로 받아 분석 가능한 정보와 최종 표현으로 변환한다.

댓글