성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] How can I tell whether two programs...
[정성태] The case of the fail-fast crashes c...
[정성태] Creating Docker multi-arch images f...
[정성태] BinaryFormatter removed from .NET 9...
[정성태] Extending the Windows Shell Progres...
[우광현] 와..... 범위를 잡았으니 클라이언트가 해당 범위를 확인해본다...
[정성태] 딱히, 그것 이상으로 더 설명할 내용이 없습니다. 동적 포...
[정성태] If Windows 3.11 required a 32-bit p...
[정성태] What is a hard error, and what make...
[괴물신인] 질문작성자인데 이 글을 이제봤네요 ㄷㄷ 이 글처럼 타입별로 인...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <h1 style='font-family: Malgun Gothic, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>C# - 다항식을 위한 최소 자승법(Least Squares Method)</h1> <p> 지난 글에서,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - 행렬식을 이용한 최소 자승법(LSM: Least Square Method) ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11918'>http://www.sysnet.pe.kr/2/0/11918</a> </pre> <br /> 최소 자승법(최소 제곱법)을 이용해 1차 함수로 근사하는 것을 봤는데요, 이를 2차, 3차,...로 확장하는 것은 다음과 같이 매우 쉽습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > 다항식(Polynomial): aX<sup>n</sup> 형식의 항들의 합으로 구성된 식 a: 계수(Coefficient) X: 변수(Variable) n: 지수(Exponent) θ<sub>0</sub> + θ<sub>1</sub>x<sub>1</sub> + θ<sub>2</sub>x<sub>1</sub><sup>2</sup> = y<sub>1</sub> θ<sub>0</sub> + θ<sub>1</sub>x<sub>2</sub> + θ<sub>2</sub>x<sub>2</sub><sup>2</sup> = y<sub>2</sub> ... θ<sub>0</sub> + θ<sub>1</sub>x<sub>n</sub> + θ<sub>2</sub>x<sub>n</sub><sup>2</sup> = y<sub>n</sub> </pre> <br /> <script type="math/tex"> \begin{pmatrix} x_1^2 & x_1 & 1\\ \vdots & \vdots & \vdots \\ x_n^2 & x_n & 1 \end{pmatrix} \begin{pmatrix} \theta_2 \\ \theta_1 \\ \theta_0 \end{pmatrix} = \begin{pmatrix} y_1 \\ \vdots \\ y_n \end{pmatrix} </script><br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > θ<sub>0</sub> + θ<sub>1</sub>x<sub>1</sub> + θ<sub>2</sub>x<sub>1</sub><sup>2</sup> + θ<sub>3</sub>x<sub>1</sub><sup>3</sup> = y<sub>1</sub> θ<sub>0</sub> + θ<sub>1</sub>x<sub>2</sub> + θ<sub>2</sub>x<sub>2</sub><sup>2</sup> + θ<sub>3</sub>x<sub>1</sub><sup>3</sup> = y<sub>2</sub> ... θ<sub>0</sub> + θ<sub>1</sub>x<sub>n</sub> + θ<sub>2</sub>x<sub>n</sub><sup>2</sup> + θ<sub>3</sub>x<sub>1</sub><sup>3</sup> = y<sub>n</sub> </pre> <br /> <script type="math/tex"> \begin{pmatrix} x_1^3 & x_1^2 & x_1 & 1\\ \vdots & \vdots & \vdots & \vdots \\ x_n^3 & x_n^2 & x_n & 1 \end{pmatrix} \begin{pmatrix} \theta_3 \\ \theta_2 \\ \theta_1 \\ \theta_0 \end{pmatrix} = \begin{pmatrix} y_1 \\ \vdots \\ y_n \end{pmatrix} </script><br /> <br /> 따라서 행렬을 사용하는 경우 그냥 늘어나는 방정식의 계수만큼 행을 추가해 의사역행렬을 구한 후 연산하면 매개변수를 구할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > private static double[] GetPolynomial(double[] xData, double[] yData, int numberOfEfficient) { Matrix<double> matA = CreateMatrix.DenseOfColumnMajor(xData.Count(), 1, xData); Vector<double> add1 = Vector<double>.Build.DenseOfArray(Enumerable.Repeat(1.0, xData.Count()).ToArray()); matA = matA.InsertColumn(1, add1); <span style='color: blue; font-weight: bold'>for (int i = 1; i < numberOfEfficient; i++) { double[] newColumnData = xData.Select((elem) => Math.Pow(elem, i + 1)).ToArray(); Vector<double> addX = Vector<double>.Build.DenseOfArray(newColumnData); matA = matA.InsertColumn(0, addX); }</span> Console.WriteLine(matA); Matrix<double> matB = CreateMatrix.DenseOfColumnMajor(yData.Count(), 1, yData); Matrix<double> pinvMatA = matA.PseudoInverse(); Console.WriteLine(pinvMatA); Matrix<double> matX = pinvMatA * matB; return matX.AsColumnMajorArray(); } </pre> <br /> [파란색 - 1차 함수, 빨간색 - 2차 함수, 노란색 3차 함수]<br /> <img onclick='toggle_img(this)' class='imgView' alt='lsm_polynomial_1.png' src='/SysWebRes/bbs/lsm_polynomial_1.png' /><br /> <br /> 일반적으로 차수가 올라갈수록 (과적합의 문제가 발생할 수 있지만) 오류는 더 적어집니다. 확인을 위해 간단하게 다음과 같이 작성해 보면,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > private static void ReportError(double[] xData, double[] yData, Func<double, double> func) { double error = 0.0; for (int i = 0; i < xData.Length; i ++) { double diff = yData[i] - func(xData[i]); error += (diff * diff); } Console.WriteLine("Error: " + error); } /* 1차: Error: 19086.9489618992 2차: Error: 6555.72459287144 3차: Error: 5038.32058563331 */ </pre> <br /> 1차에 비해 2차에서 두드러지게 오류가 낮아지는 것을 볼 수 있습니다. 따라서 이런 경우 효율을 고려한다면 2차 함수를 사용하는 것이 좋은 선택일 수 있습니다.<br /> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1462&boardid=331301885'>첨부 파일은 이 글의 예제 코드를 포함</a>합니다.)<br /> <br /> <hr style='width: 50%' /><br /> <br /> 지난 글에서 행렬 라이브러리를 직접 사용하지 않고 1차 근사식에 대한 매개 변수를 구하는 방법을 알아봤는데요,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > C# - 최소 자승법의 1차 함수에 대한 매개변수를 단순 for 문으로 구하는 방법 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11919'>http://www.sysnet.pe.kr/2/0/11919</a> </pre> <br /> 말 그대로 연립 방정식이므로 가우스 소거법을 이용해 매개 변수를 구하는 것도 가능합니다. 코드가 눈에 잘 안 들어오지만 어차피 복붙으로 써야 하는 것이라 큰 문제는 안 될 것입니다. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Linear Equation Solver - Gaussian Elimination (C#) ; <a target='tab' href='https://www.codeproject.com/Tips/388179/Linear-Equation-Solver-Gaussian-Elimination-Csharp'>https://www.codeproject.com/Tips/388179/Linear-Equation-Solver-Gaussian-Elimination-Csharp</a> Gaussian elimination ; <a target='tab' href='https://rosettacode.org/wiki/Gaussian_elimination#C.23'>https://rosettacode.org/wiki/Gaussian_elimination#C.23</a> Solve a system of equations with Gaussian elimination in C# ; <a target='tab' href='http://csharphelper.com/blog/2014/10/solve-a-system-of-equations-with-gaussian-elimination-in-c/'>http://csharphelper.com/blog/2014/10/solve-a-system-of-equations-with-gaussian-elimination-in-c/</a> [C#/WINFORM] 다항식 최소 제곱법(Polynomial Least Squares Method) 사용하기 ; <a target='tab' href='https://icodebroker.tistory.com/5580'>https://icodebroker.tistory.com/5580</a> </pre> </p><br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
1775
(왼쪽의 숫자를 입력해야 합니다.)