[AI SCHOOL 5기] SQL 프로그래밍 실습 - Merge

INNER JOIN #

sql
SELECT 
    l.Title,
    r.Name
FROM 
    albums AS l
INNER JOIN
    artists AS r
ON 
    r.ArtistId = l.ArtistId;
sql
SELECT
   Title, 
   Name
FROM
   albums
INNER JOIN artists USING(ArtistId);

LEFT JOIN #

sql
SELECT
    Name, 
    Title
FROM
    artists
LEFT JOIN albums ON artists.ArtistId = albums.ArtistId
ORDER BY 
    Name;

SELF JOIN #

sql
SELECT m.firstname || ' ' || m.lastname AS 'Manager',
       e.firstname || ' ' || e.lastname AS 'Receives reports from'
FROM
    employees e
INNER JOIN 
    employees m 
ON 
    m.employeeid = e.reportsto
ORDER BY 
    manager;
  • ‘A 테이블’과 A 테이블의 복사본인 ‘B 테이블’을 합치기

Grouping Data #

agg-func

[AI SCHOOL 5기] SQL 프로그래밍 실습 - SQL CRUD

SELECT #

sql
SELECT 10 / 5, 2 * 4;
sql
SELECT trackid, name FROM tracks;
sql
SELECT * FROM tracks;

INSERT #

sql
INSERT INTO artists (name) VALUES('Bud Powell');
python
script = """
INSERT INTO artists (name) VALUES ("?");
"""

data = [
    ("Buddy Rich"),
    ("Candido"),
    ("Charlie Byrd")
]

cur.executemany(script, data)
sql
SELECT
    ArtistId,
    Name
FROM
    Artists
ORDER BY
    ArtistId DESC;

UPDATE #

sql
UPDATE employees SET lastname = 'Smith' WHERE employeeid = 3;
sql
UPDATE employees
SET city = 'Toronto', 
    state = 'ON',
    postalcode = 'M5P 2N7'
WHERE
    employeeid = 4;
sql
UPDATE employees
SET email = UPPER(firstname || "." || lastname || "@corp.co.kr");

Sorting #

sql
SELECT 
    TrackId, 
    Name, 
    Composer 
FROM 
   tracks
ORDER BY 
   Composer;
  • NULL Data인 None은 SQLite3에서 가장 작은 값으로 인식

Filtering #

filter

[AI SCHOOL 5기] SQL 프로그래밍

DBMS #

  • DataBase Management System
  • 하드웨어에 저장된 데이터베이스를 관리해주는 소프트웨어
  • 관계형 데이터베이스(RDBMS)가 주로 사용
  • Oracle, MySQL(MariaDB), SQLite, MS SQL, PstgreSQL

데이터 모델링 #

  1. 현실 세계
  2. E-R 다이어그램 (개념 스키마)
  3. Relation 모델 (논리적 스키마)
  4. 물리적인 SQL 코드 (데이터베이스 스키마)

개념적 데이터 모델링 #

  • 현실 세계로부터 개체를 추출, 개체들의 관계를 정의, E-R 다이어그램 생성
  • 개체(Entity): 회원, 제품 등 저장할 가치가 있는 데이터를 포함한 개체
  • 속성(Attribute): 이름, 이메일 등 의미 있는 데이터의 가장 작은 논리적 단위
  • 관계(Relationship): 구매 등 개체와 개체 사이의 연관성 및 개체 집합 간 대응 관계

논리적 데이터 모델링 #

  • E-R 다이어그램을 바탕으로 논리적인 구조를 Relation 모델로 표현
  • 릴레이션(Relation): 개체에 대한 데이터를 2차원 테이블 구조로 표현한 것
  • 속성(Attribute): 열, 필드
  • 튜플(Tuble): 행, 레코드, 인스턴스
  • 차수(Degree): 릴레이션 내 속성(Column)의 총 개수
  • 카디널리티(Cardinality): 릴레이션 내 튜플(Row)의 총 개수

물리적 데이터 모델링 #

  • Relation 모델을 물리 저장 장치에 저장할 수 있는 물리적 구조로 구현

SQL #

  • Structured Query Language
  • RDBMS에서 데이터를 관리 및 처리하기 위해 만들어진 언어
  • DDL(Data Definition Language): CREATE, ALTER, DROP
  • DML(Data Manipulation Language): SELECT, INSERT, UPDATE, DELETE
  • DCL(Data Control Language): GRANT, REVOKE

NoSQL #

  • 관계형 모델을 사용하지 않음, 명시적인 스키마가 없음
  • 대용량 데이터 분산 저장에 특화
  • Kye-Value, Document, Wide Column, Graph 등

[AI SCHOOL 5기] SQL 프로그래밍 실습 - SQLite3

Connect SQLite3 #

python
import sqlite3

dbpath = "maindb.db"
conn = sqlite3.connect(dbpath)
cur = conn.cursor()
  • connnect(): DBMS와 연결
  • conn.commit(): 현재 변경사항 저장
  • conn.rollback(): 마지막 commit 시점으로 되돌리기
  • cursor(): DB에서 SQL문을 실행하는 객체

Execute Scripts #

Datatypes #

  • NULL: 결측치
  • INTEGER (or INT): 정수 (양수 또는 음수), int 값
  • REAL: 실수, float 값
  • TEXT (or VARCHAR): 텍스트, string 값
  • BLOB: 모든 종류의 파일을 저장하는 바이너리 객체

Scripts #

  • DROP TABLE IF EXISTS: 테이블이 이미 있으면 제거
  • CREATE TABLE: 테이블 생성
  • AUTOINCREMENT: 값을 따로 입력하지 않으면 자동 증가 숫자 부여
  • NOT NULL: 빈 값이 저장되는 것을 허용하지 않음
  • INSERT INTO TABLE(FIELD, …) VALUES(VALUE, …):
    테이블에 데이터 추가, 전체 필드에 값 추가 시 필드명 생략 가능
  • --: 한 줄 주석, /* ... */: 여러 줄 주석

Excecute #

  • conn.executescript(): 스크립트 구문 실행
  • cur.executemany(): 많은 데이터를 한번에 INSERT/UPDATE/DELETE
    ("INSERT INTO ... VALUES(?, ?, ?, ?, ?);", date)
  • cur.execute(): 하나의 SQL문 실행
  • cur.fetchall(): SQL문 실행 결과를 모두 반환 (튜플 형태)
  • cur.description: 테이블 정보
  • conn.close(): DB 연결 해제

To Dataframe #

  • pd.read_sql_query(query, conn)

CREATE Table #

sql
CREATE TABLE devices (
   name TEXT NOT NULL,
   model TEXT NOT NULL,
   Serial INTEGER NOT NULL UNIQUE
sql
CREATE TABLE contact_groups(
   contact_id INTEGER,
   group_id INTEGER,
   PRIMARY KEY (contact_id, group_id), 
   FOREIGN KEY (contact_id) 
      REFERENCES contacts(contact_id)
         ON DELETE CASCADE,
   FOREIGN KEY (group_id) 
      REFERENCES groups(group_id)
         ON DELETE CASCADE
);
  • CASCADE: css cascade와 동일

ALTER Table #

sql
ALTER TABLE devices RENAME TO equipment;
sql
ALTER TABLE equipment 
ADD COLUMN location text;
sql
ALTER TABLE equipment 
RENAME COLUMN location TO loc;

DROP Table #

sql
DROP TABLE equipment ;
  • Pandas로 삭제된 테이블 요청 시 no such table 에러 발생

DB 내 테이블 목록/구조 확인 #

sql
SELECT 
    name
FROM 
    sqlite_master 
WHERE
    type ='table' AND 
    name NOT LIKE 'sqlite_%'; 
  • sqlite_master는 기본적으로 생성되는 테이블
  • sqlite_master 테이블에서 생성된 모든 테이블 목록/구조 확인 가능

sqllite-master

[AI SCHOOL 5기] 통계분석 실습 - A/B Test

마케팅 비용 분석 #

  • 매월 유튜브에 광고 비용을 지출하여 신규 유저(구매 고객 or 회원가입 고객)를 획득
  • 월별로 10,000원 단위의 유튜브 광고 비용과 해당 월에 신규로 획득된 유저 수가 측정되었다고 가정

비교 데이터 #

youtube

단순 CAC 계산 #

python
cac = ad_df['Marketing_Costs'].sum() / ad_df['User_Acquired'].sum()
print(cac * 10000)

# Output
446

위의 금액에 추가로 획득하기를 원하는 유저 수를 곱한 금액을
유튜브 광고 비용으로 쓰면 그만큼 유저가 늘어날까?
== 위의 금액 만큼 유튜브 광고에 쓰면 정말로 유저가 1명 늘어날까?

[AI SCHOOL 5기] 통계분석 실습 - T-Test & 상관관계 분석

Import Libraries #

python
import pandas as pd
import seaborn as sns

import scipy as sp
from scipy import stats

import warnings
warnings.filterwarnings("ignore")

교차분석 #

교차표 (Cross-Table) #

python
crosstab = pd.crosstab(df.propensity, df.skin, margins=True)

crosstab.columns=[]
crosstab.index=[]
  • margins: 합계(All) 추가 여부
  • normalize: Normalization 여부

cross-table

Chi-square 검정 #

  • 두 범주형 변수 사이의 관계가 있는지 없는지를 검정 (독립성 검정)
  • 귀무가설: Indepedent (vice versa)
  • 대립가설: Not Independent
python
stats.chisquare(df.column1, df.column2)

# Output
Power_divergenceResult(statistic=291.8166666666667, pvalue=0.023890557260065975)

p-value #

  • 관찰 데이터의 검정 통계량이 귀무가설을 지지하는 정도
  • 귀무가설이 참이라는 전제 하에, 관찰이 완료된 값이 표본을 통해 나타날 확률
  • p-value가 0.05(5%) 미만일 경우, 관측치가 나타날 확률이 매우 낮다고 판단하여 귀무가설 기각
  • p-value가 0.05(5%) 이상일 경우, 관측치가 나타날 확률이 충분하다고 판단하여 귀무가설 지지
  • p-value가 0.05 이하라는 것이 항상 대립가설을 의미하는 것은 아님 (5%만큼 귀무가설이 참일 가능성)
python
crosstab.plot.bar(stacked=True)

cross-plot

[AI SCHOOL 5기] 통계분석 실습 - 빈도 분석 & 기술통계량 분석

Chart #

Pie Chart #

python
df['column'].value_counts().plot(kind = 'pie')

pie-chart

Bar Chart #

python
df['column'].value_counts().plot(kind = 'bar')

bar-chart


Descriptive Statistics #

  • df['column'].max(): 최댓값 (행방향 기준: axis=1)
  • df['column'].min(): 최솟값
  • df['column'].sum(): 합계
  • df['column'].mean(): 평균
  • df['column'].variance(): 분산
  • df['column'].std(): 표준편차
  • df['column'].describe(): 기술통계량

분포의 왜도와 첨도 #

  • df['column'].hist(): 히스토그램

job-histogram

  • df['column'].skew(): 왜도 (분포가 좌우로 치우쳐진 정도)
  • 왜도(Skewness): 0에 가까울수록 정규분포 (절대값 기준 3 미초과)
    우측으로 치우치면 음(negative)의 왜도, 좌측으로 치우치면 양(positive)의 왜도
  • df['column'].kurtosis(): 첨도 (분포가 뾰족한 정도)
  • 첨도(Kurtosis): 1에 가까울수록 정규분포 (절대값 기준 8 또는 10 미초과)
  • 왜도가 0, 정도가 1일 때 완전한 정규분포로 가정
  • sns.distplot(df['column'], rug=True): distribution plot
    rug: 막대 그래프를 표시할지 여부

sns-plot

[AI SCHOOL 5기] 통계분석 실습 - Numpy & Pandas

Numpy #

  • Numpy Array 내부의 데이터는 하나의 자료형으로 통일
  • Numpy Array에 값을 곱하면 전체 데이터 그대로 복사되는 리스트와 달리 데이터에 각각 곱해짐
  • np.array([]): Numpy Array 생성
  • np.dtype: Numpy Array의 Data Type
  • np.shape: Numpy Array 모양(차원)
  • np.arange(): range를 바탕으로 Numpy Array 생성
  • np.reshape(): Numpy Array 모양을 변경, 열에 -1을 입력하면 자동 계산
  • np.dot(): 행렬곱

Pandas #

  • pd.Series([], index=[]): Key가 있는 리스트(Series) 생성
  • Series.values: Series의 값
  • Series.index: Series의 키 값
  • df.ammount: 띄어쓰기 없이 영단어로 구성된 열은 변수처럼 꺼내 쓸 수 있음
  • df.insert(column, 'key', 'value'): index 기준으로 특정 위치에 새로운 열 삽입
  • df[(con1) & (con2)]: 여러 개의 조건을 사용할 땐 각각의 조건을 괄호 안에 묶어야 함
  • df['key'].value_counts(): 값의 출현 빈도 합계 (sort=False로 정렬 해제)
  • df['key'].value_counts().plot(kind='pie'): 빈도수를 기준으로 원형차트 생성
  • df['key'].apply(): 조건에 따라 변환된 값을 가진 열 반환
  • df['key'].replace(): 변환값이 1대1 대응 시 apply() 대신 replace() 사용 가능
    df['gender'].replace([1, 2], ['male', 'female'])

[AI SCHOOL 5기] 웹 크롤링 실습 - 웹 크롤링

Wadis 마감 상품 재고 체크 #

Google 메일 설정 #

python
import smtplib
from email.mime.text import MIMEText

def sendMail(sender, receiver, msg):
    smtp = smtplib.SMTP_SSL('smtp.gmail.com', 465)
    smtp.login(sender, 'your google app password')
    
    msg = MIMEText(msg)
    msg['Subject'] = 'Product is available!'
    
    smtp.sendmail(sender, receiver, msg.as_string())
    smtp.quit()

Wadis 상품 재고 체크 #

python
# 라이브러리 선언

check_status = 1
url = 'https://www.wadiz.kr/web/campaign/detail/{item_number}'

# 상품 재고가 확인되어 메일이 발송되면 종료
while check_status:

    webpage = urlopen(url)
    source = BeautifulSoup(webpage, 'html.parser')
    target = source.find_all('button', {'class':'rightinfo-reward-list'})

    for item in target:
        # 가격이 '179,000'원 상품 중
        if '179,000' in item.find('dt').get_text().strip():
            # '블루' 색상인 상품에 대하여
            if '블루' in item.find('p').get_text().strip():
                # 판매 중인 상태가 되면 (마감된 상품엔 "soldout" 클래스가 추가)
                if len(item.attrs['class']) == 2:
                        sendMail(sender, receiver, msg)
                        check_status = 0

서울상권분석서비스 #

웹 스크래핑 시도 #

python
url = 'https://golmok.seoul.go.kr/regionAreaAnalysis.do'

response = requests.get(url).content
web_page = BeautifulSoup(response, 'html.parser')
  • 해당 웹 페이지는 POST 요청으로 데이터를 주고 받기 때문에 GET 방식으로는 접근 불가
  • 개발자 도구의 Network 탭을 확인하면 JSON 데이터 확인 가능
  • POST 요청할 때 Payload를 변경하여 JSON 파일 종류 변경 가능

POST 요청 #

python
# Payload 설정
data = {'stdrYyCd': '2021', 'stdrQuCd': '4', 'stdrSlctQu': 'sameQu', 'svcIndutyCdL': 'CS000000', 'svcIndutyCdM': 'all'}

response = requests.post('https://golmok.seoul.go.kr/region/selectRentalPrice.json', data=data).content

result = json.loads(response)

Output

[AI SCHOOL 5기] 웹 크롤링 실습 - 셀레니움

Selenium #

  • 브라우저의 기능을 체크할 때 사용하는 도구
  • 브라우저를 조종해야할 때도 사용

Import Libraries #

python
# 크롬 드라이버 파일 자동 다운로드
from webdriver_manager.chrome import ChromeDriverManager
# 크롬 드라이버를 파일에 연결
from selenium.webdriver.chrome.service import Service

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys

from bs4 import BeautifulSoup 
import time
import pandas as pd

import warnings
warnings.filterwarnings("ignore") # 불필요한 Warning 메시지 무시

Virtual Browser #

python
# 크롬 드라이버 파일을 다운로드 후 세팅
service = Service(executable_path=ChromeDriverManager().install()) 

# 세팅된 크롬 드라이버를 연결해 가상 브라우저 실행
driver = webdriver.Chrome(service=service)
  • driver.maximize_window(): 가상 브라우저 크기 최대화
  • 올바른 실행을 위해 가상 브라우저의 내부는 건들지 않아야 함

Google Translation #

Google 번역 페이지 접속 #

python
translate_url = 'https://translate.google.co.kr/?sl=auto&tl=en&op=translate&hl=ko'

driver.get(translate_url)
  • driver.current_url: 가상 브라우저가 접속한 페이지의 URL 주소 반환
  • driver.page_source: 가상 브라우저가 접속한 페이지의 소스코드 반환
  • driver.find_element: BeautifulSoupfind와 같음
  • driver.find_elements: BeautifulSoupfind_all과 같음

원본 텍스트 입력 #

  • 클래스나 ID를 통한 접근이 어려울 경우 XPath를 통해 접근
  • 개발자 도구에서 full XPath를 복사
python
origin_xpath = '원본 텍스트 부분에 해당하는 XPath'

driver.find_element_by_xpath(origin_xpath).clear()
driver.find_element_by_xpath(origin_xpath).send_keys('원본 텍스트')
  • .click(): 특정 부분 클릭
  • .clear(): 특정 부분에 입력된 값 지우기
  • .send_keys(): 특정 부분에 값 입력

번역된 텍스트 가져오기 #

python
translation_xpath = '번역된 텍스트 부분에 해당하는 XPath'

translated_contents = driver.find_element_by_xpath(translation_xpath).text
  • .text: 번역된 텍스트

가상 브라우저 종료 #

python
driver.close()
driver.quit()

Translated Word Cloud #

Translated Word Cloud 생성 방법 #

  1. 기사글 전체를 번역하고 단어를 빈도수 순으로 정렬
  2. 빈도수를 기반으로 단어를 선정하고 해당 단어들만을 번역 *

선정된 단어들을 번역 #

python
for key in translation_target:
    
    # key를 원본 텍스트 부분에 입력
    time.sleep(3)

    # translated_contents 변수에 번역된 텍스트를 가져와서 저장
    
    translation_result[translated_contents] = translation_target[key]

driver.close()
driver.quit()

Translated Word Cloud #

translated-word-cloud