Home | Print | Q/A | Guest | NewsLetter
Display context of search results Case-sensitive searching
FullText › SideBar인놈소개/2010-03-18 › 추잡한언어SQLSplit패턴 › T-SQL로표준정규분포표만들기
Database System
Data Warehouse
Data Analysis
Operating System
Open Source
Enterprise Architecture
Software Engineering
Process
Working Smart

SQL Server
PostgreSQL
Oracle
DB2
Teradata
MySQL
Performance Tuning
Programming

Link
Philosophy
Tools
Misc
주인놈
_
_
SideBar Edit

Contents

1 개고생
2 표준정규분포표 만드는 소스
3 결과


1 개고생 #

처음에 '그냥 만들어 볼까?'라는 생각으로 만들기를 시도했다. 공식이 잘 안 맞는거 같아서 개고생했다. float이라 그런지 정확도가 좀 떨어진다. 그래도 쓸만하다. 웹에 아주 많이 있는 표준정규분포표를 보면 3.0의 경우 0.4987 인데, 이 소스를 실행하면 0.500623가 나온다. ㅡㅡ;; 뭐.. 어차피 확률이니 이정도는 대충 넘어가도 되지 않을까?

2 표준정규분포표 만드는 소스 #

DECLARE 
	@x float	-- 변량
,	@mu float	-- 평균
,	@sigma float	-- 표준편차

SET @x = 0.35
SET @mu = 0
SET @sigma = 1;

--SELECT (1/(SQRT(2*PI())*@sigma)) * EXP(-(1/(2*POWER(@sigma,2))) * POWER((@x-@mu), 2))

WITH Dumy(x)
AS
(
        SELECT convert(float, 0) x
        UNION ALL
        SELECT x + 0.01 FROM Dumy
        WHERE x + 0.01 < 3.09
)
/*
SELECT
	ROUND(A.x, 2) x
,	B.Pr Pr
FROM Dumy A
	CROSS APPLY (
	SELECT 
		--여기가 조낸 씨발 적분하는 부분이다.
		SUM((1/(SQRT(2*PI())*@sigma)) * EXP(-(1/(2*POWER(@sigma,2))) * POWER((x-@mu), 2))) / 100 Pr
	FROM Dumy B
	WHERE x < A.x
) B
WHERE ROUND(A.x, 2) = @x
OPTION (MAXRECURSION 0);
*/
SELECT
	LEFT(x, 3) z
,	MIN(CASE WHEN RIGHT(x, 1) = 0 THEN Pr END) [0.00]
,	MIN(CASE WHEN RIGHT(x, 1) = 1 THEN Pr END) [0.01]
,	MIN(CASE WHEN RIGHT(x, 1) = 2 THEN Pr END) [0.02]
,	MIN(CASE WHEN RIGHT(x, 1) = 3 THEN Pr END) [0.03]
,	MIN(CASE WHEN RIGHT(x, 1) = 4 THEN Pr END) [0.04]
,	MIN(CASE WHEN RIGHT(x, 1) = 5 THEN Pr END) [0.05]
,	MIN(CASE WHEN RIGHT(x, 1) = 6 THEN Pr END) [0.06]
,	MIN(CASE WHEN RIGHT(x, 1) = 7 THEN Pr END) [0.07]
,	MIN(CASE WHEN RIGHT(x, 1) = 8 THEN Pr END) [0.08]
,	MIN(CASE WHEN RIGHT(x, 1) = 9 THEN Pr END) [0.09]
FROM (
	SELECT
		CONVERT(char(4), CONVERT(numeric(36, 2), A.x)) x
	,	CONVERT(numeric(36, 6), ISNULL(B.Pr, 0)) Pr
	FROM Dumy A
		CROSS APPLY (
		SELECT 
			SUM((1/(SQRT(2*PI())*@sigma)) * EXP(-(1/(2*POWER(@sigma,2))) * POWER((x-@mu), 2))) / 100 Pr
		FROM Dumy B
		WHERE x < A.x
	) B
) T
GROUP BY 
	LEFT(x, 3)
ORDER BY 
	LEFT(x, 3)
OPTION (MAXRECURSION 0);

3 결과 #

normal_dist.jpg

ㅎㅎ 뭐.. 이런 결과다. 처음에 언급한데로 z가 3이 되기도 전에 0.5를 넘어서 버렸다. numeric으로 어떻게든 해보려고 했으나, 사용하는 함수들이 float연산으로 하므로 그냥 포기했다. 결과는 참으로 사람지향적이다. 통계학 책이나 웹에 있는 정규분포표를 보면 z값이 6쯤되면 거의 0.5에 근사한다. 3도 거의 0.5에 근사하지만 말이다. 어쨌든 3이상은 0.5라고 보면 된다.

만약 여기서 뿌려주는 결괄를 써먹으려고 한다면 큰 잘못이다. 이미 정확한 값을 가지는 표준정규분포표는 많이 있다. 수동으로 입력하던지 웹에서 찾아서 다운로드 하여 테이블에 Import시킨 후 써먹는 것이 좋은 선택일 것이다.

EditText|Print|FindPage|DeletePage|LikePages|http://www.databaser.net|last modified 2010-03-08 17:39:56