[선택] 간단히 사이킷런을 사용하여 알고리즘 학습을 진행해 보았고, 책에 나온 문제 내용을 정리
1. 머신 러닝 알고리즘의 한종류. 샘플 입력과 타깃을 알고 있을 때 사용할 수 있는 학습 방법 - 지도학습
- 지도학습 : 훈련하기 위한 데이터와 정답이 필요. 정답(타깃)이 있으니 알고리즘 정답을 맞히는 것을 학습
- 비지도학습 : 타깃 없이 입력 ㅔ이터만 사용. 정답을 사요하지 않으므로 무언가를 맞힐 순 없으나 데이터를 잘 파악하거나 변형하는 데 도움을 줌
- 차원축소 : 비지도 학습의 큰 축. 고차원의 원본 데이터를 저 차원의 부분공간으로 투영하여 데이터를 축소하는 기법. 예) 10차원 이상의 데이터가 주어졌을 때 2~3차원의 데이터로 부분공간으로 투영하여 데이터를 축소. 차원이 증가할수록 데이터 포인트 간 거리가 기하급수적으로 멀어져 희소한 구조를 가지게 됨. 피처가 많아지게 되면 개별 피처 간 상관관계가 높아 다중공선성의 문제 과적합이나 예측 성능이 저하될 우려가 있음.
- 강화학습 : 현재의 상태(state)에서 어떤 행동(action)을 취하는 것이 최적인지를 학습하는 것. 행동을 취할 때마다 외부 환경에서 보상(reward)이 주어지고, 보상을 최대화하는 방향으로 학습이 진행
2. 훈련 세트와 테스트 세트가 잘못 만들어져 전체 데이터를 대표하지 못하는 현상 - 샘플링 편향
- 샘플링 오류 : sampling error는 랜덤 표본의 통계와 실제 모집단 값 사이의 불일치를 의미. 자연적인 우연인자를 말하는 것이지, 설계가 부실하고 실행이 잘 안되어 있는 실험에 의한 측정 오류는 아니다.
- 샘플링 실수 : 아직 답을 찾는 중입니다. 향후 업데이트
- 샘플링 편차 : 아직 답을 찾는 중입니다. 향후 업데이트
- 샘플링 편향 : 일반적으로 훈련 세트와 테스트 세트에 샘플이 골고루 섞여 있지 않으면 샘플링 한쪽으로 치우쳤다는 의미
서브쿼리는 SELECT 명령에 의한 데이터 질의로, 상부가 아닌 하부의 부수적 질의를 의미합니다.
서브쿼리를 지정하는 방법은 간단하게 SELECT 쿼리를 괄호로 묶어서 SELECT / FROM / WHERE 구 등에서 사용할 수 있습니다.
스칼라 값
서브쿼리를 다른 구에서 사용하는 것을 설명하기전에 스칼라 값이라는 것에 대해 설명해 보겠습니다.
서브쿼리를 사용할 때는 그 쿼리가 어떤 값을 반환하는지 주의할 필요가 있습니다. SELECT 쿼리를 실행 시 여러가지 패턴들이 나올수 있지만 일반적인 패턴에 대해 아래 표에 설명하겠습니다.
#
쿼리
설명
1
SELECT MIN(컬럼) FROM 테이블명
하나의 값을 반환
2
SELECT 컬럼 FROM 테이블명
하나의 컬럼에 복수의 레코드
3
SELECT MIN(컬럼1), MAX(컬럼2) FROM 테이블명
하나의 레코드 복수의 컬럼
4
SELECT 컬럼1, 컬럼2 FROM 테이블명
복수의 레코드 복수의 컬럼
[표 11. SELECT 쿼리 실행 시 반환되는 일반적인 패턴]
[표 11]에서 보면 다른 패턴과 다르게 1번 패턴은 하나의 값만을 반환합니다. 이렇게 SELECT 쿼리가 하나의 값만 반환하는 것을 단일값 또는 스칼라 값 이라고 합니다.
WHERE 구에서 사용
WHERE 구에서 서브쿼리는 조건식에서 변수와 같이 사용이 가능합니다.
예를 들어 하나의 테이블에서 특정 컬럼의 최소 값을 찾아서 해당 레코드를 삭제해야 하는 경우를 생각해 보겠습니다. 이때 테이블에 데이터가 적고 한눈에 확인이 가능한 정도라면 눈으로 찾을 수 있겠지만 보통은 그렇게 찾을 수 없습니다. 이때 서브쿼리를 활용한다면 보다 쉽게 쿼리 작성이 됩니다.
먼저 서브쿼리는 해당 컬럼의 최소값을 찾을 것입니다.
1
SELECT MIN(컬럼) FROM 테이블;
[표 12. 최소값을 찾는 서브쿼리]
[표 12]와 같이 서브쿼리 작성이 되었다면 실제 레코드 삭제 부분에 적용해 보겠습니다.
1
DELETE FROM 테이블 WHERE 컬럼 = (SELECT MIN(컬럼) FROM 테이블);
[표 13. 최소값을 가진 레코드를 삭제하는 쿼리]
생각보다 간단하죠? 서브쿼리의 스칼라값을 조건식의 변수로 지정하여 사용하는 방법입니다. 하지만 데이터베이스별로 해당 쿼리가 실행이 되지 않을 수 있습니다.
동일한 테이블 내에서 추가나 갱신할 경우 서브쿼리가 제한될 수 있으니 사용하시는 데이터베이스 메뉴얼을 확인하길 바랍니다.
SELECT 구에서 사용
SELECT 구에서 서브쿼리를 지정할 때는 스칼라 서브쿼리가 필요합니다.
1
SELECT
(SELECT COUNT(*) FROM 테이블명) AS sq;
[표 14. SELECT 구에서 서브쿼리 사용 방법]
[표 14]에서는 주의할 점이 있습니다. 서브쿼리가 아닌 상부의 SELECT 구에 FROM 구가 없다는 것입니다. 이것이 MySQL에서는 실행이 되지만 ORACLE과 같이 데이터 베이스에 따라 실행이 되지 않을 수 있습니다. 그럴때는 FROM 구를 정의해 줘야 합니다. 예를 들어 Oracle을 보면 FROM DUAL로 지정하면 실행할 수 있습니다. 다른 데이터베이스를 사용하신다면 메뉴얼을 확인하길 바랍니다.
SET 구에서 사용
UPDATE의 SET구에서도 서브쿼리를 사용할 수 있습니다. SET 구에서도 서브쿼리를 사용할 때 스칼라 서브쿼리를 지정할 필요가 있습니다.
1
UPDATE 테이블 SET 컬럼 = (SELECT MAX(컬럼) FROM 테이블);
[표 15. SET구에서 서브쿼리 사용 방법]
FROM 구에서 사용
지금까지는 FROM 구에서 테이블명을 지정하였습니다. 하지만 FROM 구에도 서브쿼리를 지정할 수 있습니다. 위에서는 서브쿼리를 사용할 때 스칼라 서브쿼리를 사용하라고 했었지만 FROM 구에서 사용되는 서브쿼리는 스칼라 값을 반환하지 않아도 됩니다.
1
SELECT * FROM (SELECT * FROM 테이블2);
[표 16. FROM 구에서 서브쿼리 사용 방법]
구조가 조금 특이하게 SELECT 쿼리 안에 SELECT 쿼리가 들어 있는 것처럼 보입니다. 이런것은 ‘네스티드 구조' 또는 ‘중첩구조', ‘내표 구조'라고 합니다.
[표 16]은 2단계 중첩 구조입니다. 중첩 구조는 몇단계를 구성해도 상관은 없습니다. 하지만 3단계 이상은 추천하지 않습니다.
INSERT에서 사용
INSERT 쿼리에서도 VALUES 구의 일부로 서브쿼리를 사용할 수 있고, VALUE 구 대신 SELECT 쿼리를 사용하는 두가지 방법이 있습니다.
첫째, VALUES 구의 일부로 사용될 때
이때는 서브쿼리는 스칼라 서브쿼리를 사용해야 하고 자료형도 일치해야 합니다.
1
INSERT INTO 테이블 VALUES (
(SELECT COUNT(*) FROM 테이블2), ...
);
[표 17. VALUES 구의 일부로 서브쿼리 사용 방법]
둘째, VALUES 구 대신 서브쿼리가 사용될 때
흔히 ‘INSERT SELECT’라 불리는 쿼리입니다. INSERT SELECT 쿼리는 SELECT 쿼리의 결과를 INSERT INTO로 지정된 테이블에 전부 추가합니다. 여기서 주의할 것은 SELECT 쿼리에서 반환하는 컬럼의 수와 자료형이 INSERT할 테이블과 일치해야 합니다. 그래서 INSERT SELECT는 테이터의 복사나 이동을 할 때 자주 사용됩니다.
이번에는 대표적인 집계 함수 COUNT, SUM, AVG, MIN, MAX와 GROUP BY를 사용하여 그룹화하는 방법을 알아보겠습니다.
SQL은 집합을 다루는 집계함수를 제공합니다. 일반적으로 함수는 파라미터로 하나의 값을 지정합니다. 하지만 집계함수의 경우는 파라미터로 집합을 지정합니다.
여기서 얘기하는 집계함수의 파라미터로 집합을 지정한다는 말이 쉽게 이해하기 어려울 수 있습니다. 이것에 대해서는 COUNT에서 한번 설명해 보겠습니다.
COUNT
COUNT 함수는 파라미터로 주어진 집합의 개수를 반환합니다.
1
SELECT COUNT(컬럼명) FROM 테이블명 WHERE 조건식;
[표 1. COUNT 함수의 사용 방법]
간단합니다. 뭘 어떻게 더 설명하기 어려울 정도로 간단합니다.
추가로 설명을 하면 COUNT 집계를 사용할때 컬럼의 값 중 NULL이 있을 경우 NULL은 포함하지 않습니다. 또한 중복 데이터의 경우는 별도로 중복제거를 하지 않는다면 포함하여 집계합니다.
그러면 중복을 제외하고 집계해야하는 상황에서는 어떻게 해야할까요?
DISTINCT를 지정한 컬럼은 중복값을 제외하고 결과를 반환하는 함수입니다.
그래서 DISTINCT를 사용한 결과를 집계 함수에 적용하면 중복값을 제거한 집계 결과를 확인할 수 있습니다.
1
SELECT COUNT(DISTINCT 컬럼명) FROM 테이블명 WHERE 조건식;
[표 2. DISTINCT 를 이용한 COUNT 함수 사용 방법]
SUM
집합 연산 중에서 합계를 구하기 위해 자주 사용하는 것이 SUM 함수입니다.
SUM 함수를 사용하면 지정한 컬럼의 합계를 구할 수 있습니다. 집계 가능한 범위는 수치형 데이터만 가능합니다. 문자열이나 날짜형의 데이터를 지정할 수 없습니다.
SUM도 COUNT와 마찬가지로 NULL 값을 제거한 뒤에 합계를 반환합니다.
1
SELECT SUM(컬럼명) FROM 테이블명 WHERE 조건식;
[표 3. SUM 함수 사용 방법]
AVG
평균값을 구하기 위해서는 SUM / COUNT 와 같이 지정하면 구할 수 있지만 굳이 저렇게 사용하지 않아도 간단히 평균값을 구할 수 있습니다. 바로 AVG 함수를 이용하면 됩니다. AVG 함수는 지정한 컬럼의 평균값을 구하는 함수로서 SUM과 마찬가지로 수치형만 가능합니다.
AVG 함수도 NULL값은 제거한 뒤에 계산을 합니다. 하지만 NULL을 0으로 간주해서 평균을 내고 싶다면 CASE를 이용해서 NULL을 0으로 변환한뒤 AVG를 사용하면 됩니다.
1
SELECT AVG(컬럼명) FROM 테이블명 WHERE 조건식;
[표 4. AVG 함수 사용 방법]
MIN / MAX
MIN, MAX 함수는 컬럼에서 최소값과 최대값을 구할 수 있습니다.
위의 다른 함수와 달리 문자열과 날짜형에도 사용할 수 있고 NULL 값은 무시합니다.
1
SELECT MIN(컬럼명), MAX(컬럼명) FROM 테이블명;
[표 5. MIN, MAX 함수 사용 방법]
GROUP BY
GROUP BY 에 컬럼을 지정하여 그룹화하면 지정된 컬럼의 값이 같은 레코드들이 하나의 그룹으로 묶입니다.
각 그룹에 묶인 값들은 동일합니다. 그래서 GROUP BY를 사용하면 DISTINCT와 같이 중복을 제거하는 효과가 있습니다.
그렇다면 DISTINCT와 GROUP BY는 무슨 차이가 있을까요?
두가지 함수 모두 중복값을 제거 한다는것은 동일하지만 GROUP BY는 집계 함수와 쓰이지 않으면 별 의미가 없습니다. GROUP BY로 그룹화하고 각각의 그룹을 집계 함수에서 파라미터로 사용해야 GROUP BY가 의미가 있습니다.
1
SELECT SUM(컬럼명) FROM 테이블명 GROUP BY 컬럼명;
[표 6. GROUP BY 사용 방법]
HAVING
그러면 그룹화를 시키고 집계 함수를 사용할 때 WHERE 구의 조건식에는 집계 함수를 사용할 수는 없을까요? 네 없습니다. 그룹화가 필요한 집계 함수는 WHERE 구에서 지정할 수 없습니다.
이게 무슨 말일까요 아래 표를 보고 설명 드리겠습니다.
1
SELECT SUM(컬럼명) FROM 테이블명 WHERE COUNT(컬럼명) = 1 GROUP BY 컬럼명;
[표 7. WHERE 구에서 집계 함수 사용]
[표 7]에서 사용한 문법 사용대로 한다면 에러가 발생합니다.
그 이유는 GROUP BY와 WHERE 구의 처리 순서 때문입니다. WHERE 구의 처리는 GROUP BY 보다 빠릅니다. 그래서 그룹화가 되기전에 조건절에서 컬럼을 집계하려고 하면 에러가 발생하는 것입니다.
쿼리의 내부처리 순서를 다시 한번 살펴 보겠습니다.
순위
구
1
WHERE
2
GROUP BY
3
SELECT
4
ORDER BY
[표 8. 쿼리의 내부 처리 순서]
지금까지 HAVING을 설명하기전 다른것은 왜 안되는지에 대해 먼저 살펴 보았습니다.
우리가 원하는대로 집계한 결과에서 조건에 맞는 값을 가져오기 위해서는 HAVING을 사용하면 됩니다.
HAVING은 GROUP BY 구 뒤에 기술하고 WHERE와 동일하게 조건식 지정이 가능합니다. 즉, 그룹화된 컬럼을 이용하여 조건식에서 집계 함수를 사용할 수 있다는 것입니다.
[표 8]에서 설명한 쿼리의 내부처리 순서에 HAVING이 들어간다면 2번째인 GROUP BY 다음에 들어가게 됩니다.
순위
구
1
WHERE
2
GROUP BY
3
HAVING
4
SELECT
5
ORDER BY
[표 9. HAVING을 추가한 쿼리의 내부 처리 순서]
1
SELECT SUM(컬럼명) FROM 테이블명 GROUP BY 컬럼명 HAVING COUNT(컬럼명) = 식;
레코드를 추가할 때 NULL을 지정하고 싶을 경우에는 VALUES에서 NULL로 값을 지정할 수 있습니다.
1
INSERT INTO 테이블명 VALUES (NULL, NULL, NULL ...);
[표 3. NULL값을 지정]
[그림 3. NULL 값을 지정하여 실행한 결과]
지금 샘플 테이블에는 모든 컬럼이 NULL을 허용하고 있습니다. 그런데 만약 컬럼 중 NOT NULL 제약이 걸려있는 것이 있다고 하면 샘플로 실행한 쿼리는 에러가 발생합니다. 그 이유는 NOT NULL 제약이 걸려 있는 컬럼은 NULL 값을 허용안되기 때문입니다.
DEFAULT
DEFAULT는 명시적으로 값을 지정하지 않았을 경우 사용하는 초기값을 말합니다. 이것은 테이블을 정의할 때 지정할 수 있습니다.
DEFAULT는 두가지 방법으로 사용할 수 있습니다.
DEFAULT를 명시하는 방법과 암묵적으로 디폴트를 사용하는 방법이 있습니다.
보통 INSERT 사용 시 디폴트가 지정되어 있는 컬럼을 제외하고 쿼리를 실행 합니다. 그렇게 실행을 하더라도 컬럼의 값이 디폴트로 저장이 되기 때문입니다.
DELETE
서비스를 하다보면 데이터를 삭제해야 하는 경우가 있습니다.
예를 들어 게시판의 글 중에 글을 하나 삭제한다고 했을 때 ‘삭제' 또는 ‘지우기'같은 버튼을 클릭 했을 때 데이터 삭제 기능을 사용할 것입니다.
DELETE로 레코드 삭제하기
RDBMS에서 데이터를 삭제할 경우에는 DELETE 쿼리를 실행합니다.
1
DELETE FROM 테이블명 WHERE 조건식;
[표 4. DELECT를 사용하는 방법]
[표 4]에서 WHERE 조건식이 없다면 테이블의 모든 레코드를 삭제하게 됩니다. 그래서 조건에 부합하는 레코드만 삭제되도록 조건식을 넣어줘야 합니다.
아마 컬럼의 데이터만 삭제할 수 있지 않을까? 라고 생각하시는 분들이 있습니다. 결론은 안된다. 입니다. 컬럼 단위로 삭제가 아닌 레코드 단위이고 조건에 일치하는 모든행을 삭제하므로 사용시 주의해야 합니다.
[그림 4. DELETE 쿼리를 실행한 결과]
UPDATE
데이터 갱신 작업은 시스템에서 자주 발생합니다.
예를 들어 게시판에서 게시글을 수정할 때 ‘수정' 또는 ‘갱신'과 같은 버튼을 클릭 시 내부적으로 데이터 갱신 기능을 사용할 것입니다.
UPDATE로 데이터 갱신하기
RDBMS에서는 UPDATE 쿼리로 데이터를 갱신할 수 있습니다. 이것은 테이블의 셀 값을 갱신하는 명령입니다.
1
UPDATE 테이블명 SET 컬럼명 = 값 WHERE 조건식;
[표 5. UPDATE의 사용 방법]
DELETE와 달리 셀 단위로 데이터를 갱신할 수 있습니다. WHERE 조건식을 일치하는 모든 레코드를 갱신할 수 있습니다. 만약 WHERE 조건식을 제외한다면 테이블의 모든 레코드가 갱신됩니다.
[그림 5. UPDATE 쿼리를 실행한 결과]
복수의 컬럼 갱신
위에서는 컬럼 하나에 대한것만 갱신을 하였습니다. 이번에는 복수의 컬럼을 갱신할 때 UPDATE를 어떻게 사용해야하는지 보겠습니다.
1
UPDATE 테이블명 SET 컬럼명1 = 값1, 컬럼명 2 = 값2, … WHERE 조건식;
[표 6. 복수의 컬럼을 지정한 UPDATE 사용 방법]
[그림 6. 복수의 컬럼을 지정한 UPDATE 쿼리 실행 결과]
만약 NULL로 데이터를 초기화하려고 한다면 컬럼명 = NULL 로 지정하면 됩니다. 이런것을 NULL 초기화라고 합니다. 대신 갱신하려는 컬럼이 NOT NULL 제약 조건이 걸려있는것은 아닌지 확인하고 실행하면 됩니다.
물리 삭제, 논리 삭제
실제 서비스를 진행하면서 데이터를 삭제할 때 데이터를 삭제해 버리는 경우와 별도 삭제 플래그를 넣어서 실제 레코드는 삭제되지 않지만 플래그 값을 기준으로 삭제를 판단하는 경우가 있습니다. 여기서 말하는 삭제하는 것을 물리삭제, 삭제 플래그를 지정하는 것을 논리 삭제라고합니다.
왜 이렇게 사용한다라고 말을 하기보다는 데이터 특성이나 서비스 운영 정책에 따라 달라지기 때문에 뭐라 단정지어서 말하기 어렵습니다.
어느 테이블의 경우는 데이터를 삭제를 해야하고 어느 테이블은 삭제 플래그를 넣고 데이터는 유지하는 것처럼 섞여서 사용되기 때문에 내부 서비스 정책 및 용도에 맞게 선택하여 사용하면 될 것 같습니다.