Python

ollama-advisor: 내 PC에 맞는 Ollama 모델을 자동 추천해주는 Python 라이브러리

개요

ollama-advisor는 시스템 사양(RAM, GPU VRAM)과 사용 목적(코딩, 추론, 비전, 임베딩 등)에 따라 실행 가능한 Ollama 모델을 자동으로 추천해주는 Python 라이브러리입니다.

Mac, Windows, Linux, Google Colab 모두 지원합니다.

설치

pip install ollama-advisor

사용법

시스템 사양 확인

Ollama가 설치되어 있지 않아도 시스템 사양을 확인할 수 있습니다.

import ollama_advisor as oa

specs = oa.get_system_specs()
for k, v in specs.items():
    print(f"{k}: {v}")
ram_gb: 16.0
gpu: {'type': 'apple', 'name': 'Apple Silicon (unified memory)', 'vram_gb': 16.0}
usable_gb: 12.8
platform: mac

Apple Silicon Mac (16GB)에서 실행한 결과입니다. 사용 가능한 메모리가 12.8GB(전체의 80%)로 계산됩니다.

빅데이터 분석기사 실기 (Python)

과정 개요

빅데이터 분석기사 실기 시험을 완벽하게 대비하는 Python 기반 실전 과정입니다. 실제 시험 환경과 동일한 조건에서 데이터 분석, 모델링, 평가까지 전 과정을 학습합니다.

과정 정보

학습 목표

  • 빅데이터 분석기사 실기 시험의 3가지 유형 완벽 마스터
  • Python 라이브러리(Pandas, NumPy, Scikit-learn)를 활용한 데이터 분석

커리큘럼

1단계: 작업형 1유형 - 데이터 전처리

  • 데이터 읽기 및 탐색
  • 결측치 처리
  • 이상치 탐지 및 처리
  • 데이터 변환 및 인코딩
  • 그룹화 및 집계

2단계: 작업형 2유형 - 머신러닝 모델링

  • 분류 모델 (로지스틱 회귀, 의사결정나무, 랜덤포레스트 등)
  • 회귀 모델 (선형회귀, Ridge, Lasso 등)
  • 교차 검증 및 하이퍼파라미터 튜닝
  • 모델 평가 지표 (정확도, F1-score, ROC-AUC, RMSE 등)
  • 예측 결과 제출 형식

3단계: 작업형 3유형 - 통계 분석

  • 기술통계 분석
  • 가설 검정
  • 상관분석 및 회귀분석
  • 통계적 유의성 해석

실습 환경

  • 언어: Python

Logstash 실행 및 확인 - 기본예제

개요

  • Logstash 기본 설치 과정을 확인한다.
  • Logstash 활용 예제를 확인한다.

사전준비

  • 기존에 Elasticsearch와 Kibana 실행 방법을 알고 있어야 한다.
  • 모든 코드는 Windows 에서 실행하였다.

Logstash의 역할

  • 데이터 수집 (Ingest) - 데이터 변환 및 처리 (Processing / Filtering) - 데이터 출력 (Output)

데이터 수집

  • 다양한 데이터 소스로부터 데이터 수집
    • 로그파일
    • TCP/UDP/HTTP 요청
    • Kafka, Redis, JDBC(DB) 등

데이터 변환 및 처리 (Processing / Filtering)

  • 주요 내용

    • Logstash는 수집한 원시 데이터를 구조화된 형식으로 파싱하고 정제 및 가공
    • 정규표현식 기반 grok 필터로 로그 파싱
    • 날짜 포맷 통일 (date)
    • 필드 추가/삭제/이름 변경
    • 조건 분기 처리 (if, else)
    • JSON, CSV 파싱
    • 지오IP, 위치 정보 추가 등
  • 예시 코드

Elasticsearch - Transformers 임베딩 입력 저장 (Local Mode)

개요

  • 엘라스틱서치에서 밀집 벡터 위한 매핑 구성 방법 살펴보기
  • 밀집 벡터가 저장될 embedding 이라는 필드 정의
  • Python 코드로 엘라스틱서치 코드 구현

코드 전체 시나리오

  • Elasticsearch에 연결 및 인덱스 초기화
  • dense_vector 타입으로 매핑 정의
  • 문서 배열 정의
  • BERT 모델을 이용해 각 문서를 벡터 임베딩
  • 벡터 포함 문서를 Elasticsearch에 색인

Elasticsearch 클라이언트 연결

  • 로컬에서 실행 중인 Elasticsearch 서버에 접속
  • basic_auth: 로그인 자격 (ID: elastic, PW: 123456)
  • verify_certs=False: 인증서 검증 생략 (로컬에서 SSL 없이 사용 시 편의용)
es_admin = Elasticsearch("http://localhost:9200", 
                         basic_auth=("elastic", "123456"), 
                         verify_certs=False)

Mapping 정의 및 인덱스 생성

  • dense_vector: 벡터 검색용 필드 (벡터 유사도 기반 검색 가능)
  • dims: BERT의 출력 벡터는 기본적으로 768차원이므로 그에 맞춤
mapping = {
    "properties": {
        "embedding": {
            "type": "dense_vector",
            "dims": 768  # BERT의 출력 벡터 차원 수
        }
    }
}

기존 인덱스 삭제 후 새로 생성

  • 기존에 있던 chapter-2 인덱스를 삭제 (중복 방지)
  • 새로운 인덱스를 위에서 정의한 벡터 매핑으로 생성
try:
    es_admin.indices.delete(index="chapter-2")
    print("기존 chapter-2 인덱스를 삭제했습니다.")
except:
    print("chapter-2 인덱스가 존재하지 않습니다.")

es_admin.indices.create(index="chapter-2", body={'mappings': mapping})
print("새로운 chapter-2 인덱스를 생성했습니다.")

색인할 문서 데이터 구성

  • titletext로 구성된 단순 문서 리스트
  • text는 BERT 임베딩의 입력값이 된다
docs = [
    {"title": "Document 1", "text": "This is the first document"},
    {"title": "Document 2", "text": "This is the second document"},
    {"title": "Document 3", "text": "This is the third document"}
]

BERT 모델과 토크나이저 초기화

  • bert-base-uncased: Hugging Face에서 사전 학습된 BERT 모델
  • AutoTokenizer: 입력 텍스트를 BERT가 이해할 수 있는 토큰으로 변환
  • AutoModel: 텍스트에 대한 BERT 임베딩 추출
tokenizer = AutoTokenizer.from_pretrained("bert-base-uncased")
model = AutoModel.from_pretrained("bert-base-uncased")

BERT 임베딩 생성

  • tokenizer(...): 텍스트를 토큰화하고 PyTorch 텐서로 변환
  • model(**inputs): BERT 실행 → 각 토큰에 대한 임베딩 벡터 반환
  • last_hidden_state.mean(dim=1): 문장의 전체 임베딩을 mean pooling으로 하나의 벡터로 압축 (1×768 벡터)
  • squeeze(0).numpy(): 불필요한 batch 차원 제거 후 NumPy로 변환
  • tolist(): Elasticsearch에 저장 가능하게 리스트 형태로 변환
for doc in docs:
    text = doc["text"]
    inputs = tokenizer(text, return_tensors="pt", padding=True, truncation=True)
    with torch.no_grad():
        outputs = model(**inputs).last_hidden_state.mean(dim=1).squeeze(0).numpy() 
        doc["embedding"] = outputs.tolist()

Elasticsearch에 색인

  • 각 문서를 chapter-2 인덱스에 색인
  • Elasticsearch는 embedding 필드를 dense_vector로 저장하며, 향후 벡터 검색에도 사용 가능
for doc in docs:
    es_admin.index(index="chapter-2", body=doc)

확인

  • Kibana | Management | Dev Tools에서 색인된 문서 조회
GET chapter-2/_search

image.png

엘라스틱 클라우드에 데이터 추가하기 - 예제 (2025, 06)

CH03 - 데이터 추가

개요

  • Cloud에 데이터 추가

이전 예제 확인

파이썬 코드

# 필요한 라이브러리들을 가져옵니다
import time                    # 시간 지연을 위한 라이브러리
import requests               # HTTP 요청을 위한 라이브러리
from bs4 import BeautifulSoup # HTML 파싱을 위한 라이브러리
from elasticsearch import Elasticsearch  # Elasticsearch 클라이언트

# ✅ Elastic Cloud 연결 (API 키 인증 방식)
# Elastic Cloud의 클러스터에 API 키를 사용하여 연결합니다
# API 키는 사용자명/비밀번호 대신 더 안전한 인증 방식입니다
es = Elasticsearch(
    "your_cloud_url",  # Elastic Cloud 클러스터 URL
    api_key="your_api_key"  # API 키
)

# 저장할 인덱스 이름을 상수로 정의합니다
INDEX_NAME = "evan-elk-search"

# ✅ 인덱스 생성 (존재하지 않으면 새로 생성)
# Elasticsearch에서 데이터를 저장할 인덱스가 있는지 확인하고, 없으면 새로 생성합니다
if not es.indices.exists(index=INDEX_NAME):
    es.indices.create(index=INDEX_NAME)  # 새 인덱스 생성
    print(f"✅ Index '{INDEX_NAME}' created.")
else:
    print(f"✅ Index '{INDEX_NAME}' already exists.")

# ✅ 명언 수집 함수 정의
def get_quotes():
    """
    quotes.toscrape.com 웹사이트에서 명언들을 수집하는 함수
    
    Returns:
        list: 수집된 명언 요소들의 리스트 (BeautifulSoup 객체들)
    """
    res = requests.get("http://quotes.toscrape.com")  # 웹사이트에 GET 요청
    soup = BeautifulSoup(res.text, "html.parser")     # HTML을 파싱
    return soup.select(".quote")                       # .quote 클래스를 가진 요소들을 선택하여 반환

# ✅ 30초 간격으로 명언들을 하나씩 저장
# 수집된 명언들을 가져옵니다
quotes = get_quotes()

# 각 명언을 순회하면서 Elastic Cloud에 저장합니다
for i, q in enumerate(quotes):
    # 명언 데이터를 딕셔너리 형태로 구성합니다
    doc = {
        "text": q.select_one(".text").text.strip(),      # 명언 텍스트 추출 (공백 제거)
        "author": q.select_one(".author").text.strip(),  # 저자 이름 추출 (공백 제거)
        "tags": [tag.text for tag in q.select(".tag")]   # 태그들을 리스트로 추출
    }
    
    # Elastic Cloud에 문서를 저장합니다
    res = es.index(index=INDEX_NAME, document=doc)
    print(f"[{i+1}] ✅ Saved to Elastic Cloud: {res['_id']}")  # 저장된 문서의 ID 출력
    
    # 30초 대기 (다음 명언 저장 전)
    time.sleep(30)
  • 클라우드에서 확인

image.png

엘라스틱 서치 시작하기 - 예제 (2025, 06)

개요

  • 엘라스틱 클라우드 활용 예제 확인

회원가입

image.png

  • 가입 중간에 데이터 저장하는 공간이 있는데, 필자는 GCP를 선택하였다.

image.png

  • 다음 화면에서는 다음과 같이 지정하였다. General Purpose

image.png

  • 인덱스 명 : evan-elk-search

image.png

  • 인덱스 명을 확인하면 다음과 같다.
  • URL과 API 주소를 확인한다.
    • URL : your_url
    • your_api_key

image.png

설치 및 예제 확인

Windows 10

image.png

  • 압축 파일을 해제하고 C 드라이브쪽으로 폴더를 이동시킨다.

MSSQL Connect to Python (ver. 2025.04)

개요

  • SSMS에 계정 추가
  • 계정 추가 후 Python 라이브러리 활용해서 연동

계정 추가

  • 먼저 Security(보안) > Logins(로그인)에서 마우스 우클릭 진행
    • New Login 선택

image.png

  • 다음 화면에서 Loing Name은 evan-tester2 명명, Password는 1234로 지정함
    • Default Database는 BikeStores로 지정함
    • Enforce password policy 체크 박스 해제 (테스트용)

image.png

  • 왼쪽 메뉴에서 User Mapping 메뉴 선택
    • 하단 옵션에서 db_datawriter 옵션 선택

image.png

  • 왼쪽 메뉴에서 Server Roles 선택
    • dbcreator, public, sysadmin 선택
  • 선택이 완료되었다면 OK 버튼 클릭

image.png

Python 라이브러리 설치 확인

개요

  • requirements.txt 파일에 명시된 패키지들의 설치 여부와 버전을 확인하는 코드
  • 각 패키지에 대해 현재 환경에 설치된 버전을 출력하며, 설치되지 않은 경우 메시지 표시

예시

  • requirements.txt 파일에 다음과 같은 패키지가 있다고 가정한다.
  • 또한 가상 환경에 이미 아래 라이브러리가 설치가 되어 있다고 가정한다.
polars
pandas
numpy
matplotlib
seaborn
scikit-learn
graphviz
statsmodels
jupyterlab
pyarrow
deltalake
xlsx2csv
xlsxwriter
openpyxl
xlrd
  • 먼저 설치된 라이브러리 전체 개수를 확인한다.
import pkg_resources

# 현재 환경에 설치된 모든 패키지 목록과 버전 조회
installed_packages = [f"{dist.project_name}=={dist.version}" 
                     for dist in pkg_resources.working_set]
print(len(installed_packages))

[결과]
132
  • 이번에는 각 패키지에 대해 현재 환경에 설치된 버전을 출력하며, 설치되지 않은 경우 메시지 표시한다.
import pkg_resources

# requirements.txt 파일에 명시된 패키지들의 설치 여부와 버전을 확인하는 코드
# 각 패키지에 대해 현재 환경에 설치된 버전을 출력하며, 설치되지 않은 경우 메시지 표시
packages = [
    'polars', 'pandas', 'numpy', 'matplotlib', 'seaborn', 'scikit-learn', 'graphviz', 'statsmodels', 'jupyterlab', 'pyarrow', 'deltalake', 'xlsx2csv', 'xlsxwriter', 'openpyxl', 'xlrd'
]

# 각 패키지를 순회하면서 버전 정보 확인
for package in packages:
    try:
        # pkg_resources를 사용하여 설치된 패키지의 버전 정보 조회
        version = pkg_resources.get_distribution(package).version
        print(f"{package}: {version}")
    except pkg_resources.DistributionNotFound:
        # 패키지가 설치되지 않은 경우 예외 처리
        print(f"{package}: 설치되지 않음")
        
[결과]
polars: 1.22.0
pandas: 2.2.3
numpy: 2.0.2
matplotlib: 3.9.4
seaborn: 0.13.2
scikit-learn: 1.6.1
graphviz: 0.20.3
statsmodels: 0.14.4
jupyterlab: 4.3.5
pyarrow: 19.0.0
deltalake: 0.24.0
xlsx2csv: 0.8.4
xlsxwriter: 3.2.2
openpyxl: 3.1.5
xlrd: 2.0.1

Docker-Compose와 Dockerfile을 활용한 Flask-MySQL 연동 예제

개요

  • Docker-Compose와 Dockerfile의 주요 기능을 이해한다.
  • 각 파일의 위치와 주요 기능을 이해한다.

전체 프로젝트 파일 디렉터리

  • 본 프로젝트의 전체 코드는 다음과 같다.
  • 실제 코드 작성을 해야하는 곳은 다음과 같다.
    • app.py
    • requirements.txt
    • init.sql
    • docker-compose.yml
    • Dockerfile
docker_kubernetes_flask/
├── app/
│   ├── __init__.py
│   ├── app.py
│   └── requirements.txt
├── db/
│   ├── init.sql
│   └── data/ (This will be created by Docker)
├── docker-compose.yml
└── Dockerfile

사전준비

  • 사전에 Docker는 Desktop 설치가 되어 있다고 가정한다.
  • 코드 편집을 위해서는 Visual Studio Code를 활용한다.

Docker가 익숙하지 않은 사람들을 위한 1줄 요약

  • MySQL 설치하고, Python 설치하고, 두개 또 연동해야 하고, CLI 명령어 또 각각 입력하는거 다 자동화 해줄게요!!
  • 즉, 자동화에 익숙해지자!

docker-compose와 Dockerfile 간단 비교

  • docker-compose.yml : python 컨테이너와 mysql 컨테이너를 각각 한꺼번에 구성하도록 스크립트를 작성함
  • Dockerfile : 여기에서는 python 개발환경을 구성함
  • docker-compose.yml에서 Dockerfile을 호출하여 개발환경을 만들도록 지시할 수 있음

전체 코드 흐름 1줄 요약

  • From MySQL to Python Flask

init.sql과 app.py 간단 설명

  • 각 두개의 파일은 사전에 미리 작성을 해둔다.

MySQL : init.sql

  • SQL 코드는 데이터베이스와 테이블을 생성하고, 테이블에 데이터를 삽입하는 작업을 수행.
    • test_db 데이터베이스 생성
    • users 테이블 생성
    • 간단하게 이름 생성
CREATE DATABASE IF NOT EXISTS test_db;

USE test_db;

CREATE TABLE IF NOT EXISTS users (
    id INT AUTO_INCREMENT PRIMARY KEY,
    name VARCHAR(255) NOT NULL
);

INSERT INTO users (name) VALUES ('Evan');
INSERT INTO users (name) VALUES ('Sara');
INSERT INTO users (name) VALUES ('Lotto');

Python : app.py

  • Python 코드는 Flask 웹 애플리케이션을 설정하여 MySQL 데이터베이스에 연결하고, 사용자 데이터를 JSON 형식으로 반환하는 작업을 수행.
from flask import Flask, jsonify
import mysql.connector
import os

app = Flask(__name__)

def get_db_connection():
    connection = mysql.connector.connect(
        host='mysql',
        user='root',
        password='example',
        database='test_db'
    )
    return connection

@app.route('/')
def index():
    connection = get_db_connection()
    cursor = connection.cursor()
    cursor.execute('SELECT * FROM users')
    users = cursor.fetchall()
    cursor.close()
    connection.close()
    users_list = [{"id": user[0], "name": user[1]} for user in users]
    return jsonify(users_list)

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)
  • 좀더 구체적으로 살펴본다.

step 01 - 라이브러리 불러오기

  • Flask: Flask 웹 애플리케이션 프레임워크를 불러오기
  • jsonify: 데이터를 JSON 형식으로 변환하여 HTTP 응답으로 반환하는 데 사용
  • mysql.connector: MySQL 데이터베이스에 연결하기 위해 사용
from flask import Flask, jsonify
import mysql.connector
import os

step 02 - Flask Application Setup

  • Flask 애플리케이션 인스턴스를 생성. __name__은 현재 모듈의 이름을 전달하여 Flask 애플리케이션을 생성하는 데 사용.
app = Flask(__name__)

step 03 - Database Connection Function

  • get_db_connection 함수는 MySQL 데이터베이스에 연결하고, 연결 객체를 반환.
  • host, user, password, database 매개변수는 데이터베이스에 연결하기 위한 정보
def get_db_connection():
    connection = mysql.connector.connect(
        host='mysql',
        user='root',
        password='example',
        database='test_db'
    )
    return connection

step 04 - Index Route

  • @app.route('/'): 해당 Decorator는 URL (’/’)에 대한 요청을 처리하는 index 함수를 정의.
  • index 함수의 내용은 다음과 같이 구성됨
    • get_db_connection을 호출하여 데이터베이스에 연결.
    • 연결 객체에서 커서를 생성하고, SELECT * FROM users 쿼리를 실행하여 users 테이블의 모든 데이터를 가져오기
    • 데이터를 가져온 후 커서와 연결을 닫기
    • users 데이터를 List Comprehension을 사용하여 딕셔너리 형태로 변환합니다. 각 사용자에 대해 idname 키를 가지는 딕셔너리를 생성.
      • 이 부분은 별도의 HTML 소스코드를 넣지 않기 위해서 진행한 것이니, 해당 자세한 내용을 보기를 원한다면 Flask 웹개발로 더 공부할 것 권장
    • 변환된 리스트를 jsonify를 사용하여 JSON 형식으로 반환.
@app.route('/')
def index():
    connection = get_db_connection()
    cursor = connection.cursor()
    cursor.execute('SELECT * FROM users')
    users = cursor.fetchall()
    cursor.close()
    connection.close()
    users_list = [{"id": user[0], "name": user[1]} for user in users]
    return jsonify(users_list)

step 05 - Running the Application

  • 모듈이 직접 실행될 때만 Flask 애플리케이션을 실행
    • app.run 메소드를 호출하여 애플리케이션을 시작.
    • host='0.0.0.0': 애플리케이션이 모든 네트워크 인터페이스에서 접근 가능하도록 설정.
    • port=5000: 애플리케이션이 5000번 포트에서 실행되도록 설정.
if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

Python : requirements.txt

  • 주요 라이브러리 설치 위해 필요한 라이브러리 2개만 설치
  • 추후에 독자가 라이브러리 추가 가능
Flask
mysql-connector-python

Docker: Dockerfile

  • Dockerfile은 Python 애플리케이션을 컨테이너화하기 위한 스크립트
  • 다른 파일과 달리 확장자명이 없다는 것에 주의
  • 다양한 옵션에 대해 설명하도록 한다.
FROM python:3.10-slim

WORKDIR /app

COPY app/requirements.txt .

RUN pip install --no-cache-dir -r requirements.txt

COPY app/ .

EXPOSE 5000

CMD ["python", "app.py"]

step 01 - FROM

FROM python:3.10-slim
  • Base Image를 선택한다. 해당 이미지를 선택하려면 Docker Hub 검색창에서 확인 (Login 필수)
  • 각 Base Image를 선택하면 관련 Tag가 존재하며 여기에서 Tags 확인해서 입력하도록 한다.
  • Docker Official Image 를 선택한다.

Screenshot 2024-07-01 at 8.16.09 AM.png

Streamlit on Google Colab

개요

  • 개발환경설정이 어려운 환경에서 Google Colab 상에서 Streamlit 설치 및 실행을 익히고자 한다.
  • 주로 강의 목적으로 사용하기를 바란다.

Streamlit 라이브러리 설치

  • 아래 코드를 활용하여 streamlit 라이브러리 설치
!pip install -q streamlit

Untitled

Streamlit 코드 작성 샘플

%%writefile app.py

import streamlit as st
import plotly.graph_objs as go
from plotly.subplots import make_subplots
import seaborn as sns

@st.cache_data
def load_data():
    df = sns.load_dataset('tips')
    return df

def main():
    st.title("Streamlit with Plotly")   
    tips = load_data()

    # 데이터가공
    m_tips = tips.loc[tips['sex'] == 'Male', :]
    f_tips = tips.loc[tips['sex'] == 'Female', :]

    # 시각화 차트
    fig = make_subplots(rows = 1,
                        cols = 2,
                        subplot_titles=('Male', 'Female'),
                        shared_yaxes=True,
                        shared_xaxes=True,
                        x_title='Total Bill($)'
                        )
    fig.add_trace(go.Scatter(x = m_tips['total_bill'], y = m_tips['tip'], mode='markers'), row=1, col=1)
    fig.add_trace(go.Scatter(x = f_tips['total_bill'], y = f_tips['tip'], mode='markers'), row=1, col=2)
    fig.update_yaxes(title_text="Tip($)", row=1, col=1)
    fig.update_xaxes(range=[0, 60])
    fig.update_layout(showlegend=False)
    
    # 중요포인트
    # fig.show()
    st.plotly_chart(fig, use_container_width=True)

if __name__ == "__main__":
    main()

Untitled