성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
글쓰기
제목
이름
암호
전자우편
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# - 로지스틱 회귀를 이용한 분류</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;' > 기초 수학으로 이해하는 머신러닝 알고리즘 ; <a target='tab' href='https://wikibook.co.kr/math-for-ml/'>https://wikibook.co.kr/math-for-ml/</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;' > C# - 웨이트 벡터 갱신식을 이용한 퍼셉트론 분류 ; <a target='tab' href='http://www.sysnet.pe.kr/2/0/11938'>http://www.sysnet.pe.kr/2/0/11938</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;' > wikibook/math-for-ml ; <a target='tab' href='https://github.com/wikibook/math-for-ml/blob/master/classification2_logistic_regression.py'>https://github.com/wikibook/math-for-ml/blob/master/classification2_logistic_regression.py</a> </pre> <br /> C# 버전으로 포팅해 보겠습니다. ^^<br /> <br /> <hr style='width: 50%' /><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;' > <script type="math/tex"> f_\theta(x) = \frac {1} {1 + e^{-\theta^T x}} </script><br /> </pre> <br /> C#으로 이렇게 정의할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > Func<Vector<double>, Vector<double>, double> f = (x, t) => 1 / (1 + Math.Exp(-x * theta)); </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;' > <script type="math/tex"> L(\theta) = \prod_{i=1}^n P(y_i = 1|x_i)^{y_i} P(y_i = 0|x_i)^{1-y_i} </script><br /> </pre> <br /> 제곱 계산 때문에 0으로 빠르게 수렴하는 문제를 완화하기 위해 대수 우도 함수를 정의하는데,<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > <script type="math/tex"> logL(\theta) = log \prod_{i=1}^n P(y_i = 1|x_i)^{y_i} P(y_i = 0|x_i)^{1-y_i} </script><br /> </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;' > <script type="math/tex"> \theta_j := \theta_j + \eta \times \sum_{i=1}^n(y_i - f_\theta(x_i))x_j^i </script><br /> </pre> <br /> <a target='tab' href='http://www.sysnet.pe.kr/2/0/11938'>웨이트 벡터 갱신식</a>과 <a target='tab' href='https://www.sysnet.pe.kr/2/0/11924'>최소 자승법</a>의 경우와 유사하다는 점입니다. 정말이지 수학 분야는 너무나 신비롭습니다. ^^<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;' > <script type="math/tex"> \theta_j := \theta_j - \eta \times \sum_{i=1}^n(f_\theta(x_i) - y_i)x_j^i </script><br /> </pre> <br /> C# 코드로는 이 부분을 다음과 같이 바꿀 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > var fResult = imgList.ForEach((elem) => f(elem.AsVectorX(), theta) - elem.Y).ToVector(); theta = theta - ETA * fResult * X; </pre> <br /> 암튼, 이렇게 해서 <a target='tab' href='https://github.com/wikibook/math-for-ml/blob/master/classification2_logistic_regression.py'>classification2_logistic_regression.py</a> 소스 코드를 C#으로 변환하면 (각종 확장 함수의 도움을 이용해 ^^;) 대충 이렇게 정리할 수 있습니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; background-color: #fbedbb; overflow: auto; font-family: Consolas, Verdana;' > static void Main(string[] args) { MLContext ctx = new MLContext(); string inputFileName = "images2.csv"; IDataView data = ctx.Data.LoadFromTextFile<ImageRect>(inputFileName, separatorChar: ',', hasHeader: true); // 매개변수 초기화 Vector<double> theta = Vector<double>.Build.Dense(SystemRandomSource.Default.NextDoubles(3)); var dataList = ctx.Data.CreateEnumerable<ImageRect>(data, false); var statInfo = dataList.GetStatisticsInfo(); // 표준화 var imgList = dataList.NormalizeZscore(statInfo); Matrix<double> X = imgList.ToMatrix(); Console.WriteLine(X); // 시그모이드 함수 Func<Vector<double>, Vector<double>, double> f = (x, t) => 1 / (1 + Math.Exp(-x * theta)); // 학습률 double ETA = 1e-3; // 반복 횟수 int epoch = 5000; // 갱신 횟수 for (int i = 0; i < epoch; i ++) { var fResult = imgList.ForEach((elem) => f(elem.AsVectorX(), theta) - elem.Y).ToVector(); theta = theta - ETA * fResult * X; // Console.WriteLine(theta); } Console.WriteLine($"theta = {theta}"); OutputChart(imgList, theta); } </pre> <br /> 그런대로 좀 비슷하죠?!!! ^^;<br /> <br /> (<a target='tab' href='https://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=1475&boardid=331301885'>첨부 파일은 이 글의 소스 코드를 포함</a>합니다.)<br /> <br /> <hr style='width: 50%' /><br /> <br /> 참고로, 분류 함수의 출력 그래프는 다음과 같고,<br /> <br /> <img onclick='toggle_img(this)' class='imgView' alt='logistic_regression_1.png' src='/SysWebRes/bbs/logistic_regression_1.png' /><br /> <br /> 지난 <a target='tab' href='http://www.sysnet.pe.kr/2/0/11938'>퍼셉트론 글</a>에서 분류하지 못했던 "x2의 값이 300 이상인 경우 -1, 미만인 경우 1의 데이터"에 대해서도 다음과 같이 잘 분류를 하는 것을 볼 수 있습니다. ^^<br /> <br /> <img onclick='toggle_img(this)' class='imgView' alt='logistic_regression_2.png' src='/SysWebRes/bbs/logistic_regression_2.png' /><br /> <br /> <hr style='width: 50%' /><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;' > Sigmoid function (시그모이드 함수) ; <a target='tab' href='https://m.blog.naver.com/2feelus/220363930362'>https://m.blog.naver.com/2feelus/220363930362</a> Mathpresso 머신 러닝 스터디 - 3. 오차를 다루는 방법_1 ; <a target='tab' href='https://medium.com/qandastudy/mathpresso-%EB%A8%B8%EC%8B%A0-%EB%9F%AC%EB%8B%9D-%EC%8A%A4%ED%84%B0%EB%94%94-3-%EC%98%A4%EC%B0%A8%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95-7d1fb64ea0cf'>https://medium.com/qandastudy/mathpresso-%EB%A8%B8%EC%8B%A0-%EB%9F%AC%EB%8B%9D-%EC%8A%A4%ED%84%B0%EB%94%94-3-%EC%98%A4%EC%B0%A8%EB%A5%BC-%EB%8B%A4%EB%A3%A8%EB%8A%94-%EB%B0%A9%EB%B2%95-7d1fb64ea0cf</a> R을 이용한 회귀분석 (이부일 | 인사이트마이닝) ; <a target='tab' href='https://www.youtube.com/watch?v=fCF1SXix10Y'>https://www.youtube.com/watch?v=fCF1SXix10Y</a> </pre> </p><br /> <br /> <br /><hr /><span style='color: Maroon'>[이 글에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
3246
(왼쪽의 숫자를 입력해야 합니다.)