614 lines
54 KiB
HTML
614 lines
54 KiB
HTML
<!--
|
|
HTML file automatically generated from DocOnce source
|
|
(https://github.com/doconce/doconce/)
|
|
doconce format html week39.do.txt --html_style=bootstrap --pygments_html_style=default --html_admon=bootstrap_panel --html_output=week39-bs --no_mako
|
|
-->
|
|
<html>
|
|
<head>
|
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
|
<meta name="generator" content="DocOnce: https://github.com/doconce/doconce/" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
<meta name="description" content="Week 39: Resampling methods and logistic regression">
|
|
<title>Week 39: Resampling methods and logistic regression</title>
|
|
<!-- Bootstrap style: bootstrap -->
|
|
<!-- doconce format html week39.do.txt --html_style=bootstrap --pygments_html_style=default --html_admon=bootstrap_panel --html_output=week39-bs --no_mako -->
|
|
<link href="https://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
|
|
<!-- not necessary
|
|
<link href="https://netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
|
|
-->
|
|
<style type="text/css">
|
|
/* Add scrollbar to dropdown menus in bootstrap navigation bar */
|
|
.dropdown-menu {
|
|
height: auto;
|
|
max-height: 400px;
|
|
overflow-x: hidden;
|
|
}
|
|
/* Adds an invisible element before each target to offset for the navigation
|
|
bar */
|
|
.anchor::before {
|
|
content:"";
|
|
display:block;
|
|
height:50px; /* fixed header height for style bootstrap */
|
|
margin:-50px 0 0; /* negative fixed header height */
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<!-- tocinfo
|
|
{'highest level': 2,
|
|
'sections': [('Plan for week 39, September 22-26, 2025',
|
|
2,
|
|
None,
|
|
'plan-for-week-39-september-22-26-2025'),
|
|
('Readings and Videos, resampling methods',
|
|
2,
|
|
None,
|
|
'readings-and-videos-resampling-methods'),
|
|
('Readings and Videos, logistic regression',
|
|
2,
|
|
None,
|
|
'readings-and-videos-logistic-regression'),
|
|
('Lab sessions week 39', 2, None, 'lab-sessions-week-39'),
|
|
('Lecture material', 2, None, 'lecture-material'),
|
|
('Resampling methods', 2, None, 'resampling-methods'),
|
|
('Resampling approaches can be computationally expensive',
|
|
2,
|
|
None,
|
|
'resampling-approaches-can-be-computationally-expensive'),
|
|
('Why resampling methods ?', 2, None, 'why-resampling-methods'),
|
|
('Statistical analysis', 2, None, 'statistical-analysis'),
|
|
('Resampling methods', 2, None, 'resampling-methods'),
|
|
('Resampling methods: Bootstrap',
|
|
2,
|
|
None,
|
|
'resampling-methods-bootstrap'),
|
|
('The bias-variance tradeoff',
|
|
2,
|
|
None,
|
|
'the-bias-variance-tradeoff'),
|
|
('A way to Read the Bias-Variance Tradeoff',
|
|
2,
|
|
None,
|
|
'a-way-to-read-the-bias-variance-tradeoff'),
|
|
('Understanding what happens',
|
|
2,
|
|
None,
|
|
'understanding-what-happens'),
|
|
('Summing up', 2, None, 'summing-up'),
|
|
("Another Example from Scikit-Learn's Repository",
|
|
2,
|
|
None,
|
|
'another-example-from-scikit-learn-s-repository'),
|
|
('Various steps in cross-validation',
|
|
2,
|
|
None,
|
|
'various-steps-in-cross-validation'),
|
|
('Cross-validation in brief',
|
|
2,
|
|
None,
|
|
'cross-validation-in-brief'),
|
|
('Code Example for Cross-validation and $k$-fold '
|
|
'Cross-validation',
|
|
2,
|
|
None,
|
|
'code-example-for-cross-validation-and-k-fold-cross-validation'),
|
|
('More examples on bootstrap and cross-validation and errors',
|
|
2,
|
|
None,
|
|
'more-examples-on-bootstrap-and-cross-validation-and-errors'),
|
|
('The same example but now with cross-validation',
|
|
2,
|
|
None,
|
|
'the-same-example-but-now-with-cross-validation'),
|
|
('Logistic Regression', 2, None, 'logistic-regression'),
|
|
('Classification problems', 2, None, 'classification-problems'),
|
|
('Optimization and Deep learning',
|
|
2,
|
|
None,
|
|
'optimization-and-deep-learning'),
|
|
('Basics', 2, None, 'basics'),
|
|
('Linear classifier', 2, None, 'linear-classifier'),
|
|
('Some selected properties', 2, None, 'some-selected-properties'),
|
|
('Simple example', 2, None, 'simple-example'),
|
|
('Plotting the mean value for each group',
|
|
2,
|
|
None,
|
|
'plotting-the-mean-value-for-each-group'),
|
|
('The logistic function', 2, None, 'the-logistic-function'),
|
|
('Examples of likelihood functions used in logistic regression '
|
|
'and nueral networks',
|
|
2,
|
|
None,
|
|
'examples-of-likelihood-functions-used-in-logistic-regression-and-nueral-networks'),
|
|
('Two parameters', 2, None, 'two-parameters'),
|
|
('Maximum likelihood', 2, None, 'maximum-likelihood'),
|
|
('The cost function rewritten',
|
|
2,
|
|
None,
|
|
'the-cost-function-rewritten'),
|
|
('Minimizing the cross entropy',
|
|
2,
|
|
None,
|
|
'minimizing-the-cross-entropy'),
|
|
('A more compact expression',
|
|
2,
|
|
None,
|
|
'a-more-compact-expression'),
|
|
('Extending to more predictors',
|
|
2,
|
|
None,
|
|
'extending-to-more-predictors'),
|
|
('Including more classes', 2, None, 'including-more-classes'),
|
|
('More classes', 2, None, 'more-classes'),
|
|
('Optimization, the central part of any Machine Learning '
|
|
'algortithm',
|
|
2,
|
|
None,
|
|
'optimization-the-central-part-of-any-machine-learning-algortithm'),
|
|
('Revisiting our Logistic Regression case',
|
|
2,
|
|
None,
|
|
'revisiting-our-logistic-regression-case'),
|
|
('The equations to solve', 2, None, 'the-equations-to-solve'),
|
|
("Solving using Newton-Raphson's method",
|
|
2,
|
|
None,
|
|
'solving-using-newton-raphson-s-method'),
|
|
('Example code for Logistic Regression',
|
|
2,
|
|
None,
|
|
'example-code-for-logistic-regression'),
|
|
('Synthetic data generation',
|
|
3,
|
|
None,
|
|
'synthetic-data-generation')]}
|
|
end of tocinfo -->
|
|
|
|
<body>
|
|
|
|
|
|
|
|
<script type="text/x-mathjax-config">
|
|
MathJax.Hub.Config({
|
|
TeX: {
|
|
equationNumbers: { autoNumber: "none" },
|
|
extensions: ["AMSmath.js", "AMSsymbols.js", "autobold.js", "color.js"]
|
|
}
|
|
});
|
|
</script>
|
|
<script type="text/javascript" async
|
|
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
|
|
</script>
|
|
|
|
|
|
<!-- Bootstrap navigation bar -->
|
|
<div class="navbar navbar-default navbar-fixed-top">
|
|
<div class="navbar-header">
|
|
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse">
|
|
<span class="icon-bar"></span>
|
|
<span class="icon-bar"></span>
|
|
<span class="icon-bar"></span>
|
|
</button>
|
|
<a class="navbar-brand" href="week39-bs.html">Week 39: Resampling methods and logistic regression</a>
|
|
</div>
|
|
<div class="navbar-collapse collapse navbar-responsive-collapse">
|
|
<ul class="nav navbar-nav navbar-right">
|
|
<li class="dropdown">
|
|
<a href="#" class="dropdown-toggle" data-toggle="dropdown">Contents <b class="caret"></b></a>
|
|
<ul class="dropdown-menu">
|
|
<!-- navigation toc: --> <li><a href="._week39-bs001.html#plan-for-week-39-september-22-26-2025" style="font-size: 80%;"><b>Plan for week 39, September 22-26, 2025</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs002.html#readings-and-videos-resampling-methods" style="font-size: 80%;"><b>Readings and Videos, resampling methods</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs003.html#readings-and-videos-logistic-regression" style="font-size: 80%;"><b>Readings and Videos, logistic regression</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs004.html#lab-sessions-week-39" style="font-size: 80%;"><b>Lab sessions week 39</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs005.html#lecture-material" style="font-size: 80%;"><b>Lecture material</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs010.html#resampling-methods" style="font-size: 80%;"><b>Resampling methods</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs007.html#resampling-approaches-can-be-computationally-expensive" style="font-size: 80%;"><b>Resampling approaches can be computationally expensive</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs008.html#why-resampling-methods" style="font-size: 80%;"><b>Why resampling methods ?</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs009.html#statistical-analysis" style="font-size: 80%;"><b>Statistical analysis</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs010.html#resampling-methods" style="font-size: 80%;"><b>Resampling methods</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs011.html#resampling-methods-bootstrap" style="font-size: 80%;"><b>Resampling methods: Bootstrap</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs012.html#the-bias-variance-tradeoff" style="font-size: 80%;"><b>The bias-variance tradeoff</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs013.html#a-way-to-read-the-bias-variance-tradeoff" style="font-size: 80%;"><b>A way to Read the Bias-Variance Tradeoff</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs014.html#understanding-what-happens" style="font-size: 80%;"><b>Understanding what happens</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs015.html#summing-up" style="font-size: 80%;"><b>Summing up</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs016.html#another-example-from-scikit-learn-s-repository" style="font-size: 80%;"><b>Another Example from Scikit-Learn's Repository</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs017.html#various-steps-in-cross-validation" style="font-size: 80%;"><b>Various steps in cross-validation</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs018.html#cross-validation-in-brief" style="font-size: 80%;"><b>Cross-validation in brief</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs019.html#code-example-for-cross-validation-and-k-fold-cross-validation" style="font-size: 80%;"><b>Code Example for Cross-validation and \( k \)-fold Cross-validation</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs020.html#more-examples-on-bootstrap-and-cross-validation-and-errors" style="font-size: 80%;"><b>More examples on bootstrap and cross-validation and errors</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs021.html#the-same-example-but-now-with-cross-validation" style="font-size: 80%;"><b>The same example but now with cross-validation</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs022.html#logistic-regression" style="font-size: 80%;"><b>Logistic Regression</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs023.html#classification-problems" style="font-size: 80%;"><b>Classification problems</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs024.html#optimization-and-deep-learning" style="font-size: 80%;"><b>Optimization and Deep learning</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs025.html#basics" style="font-size: 80%;"><b>Basics</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs026.html#linear-classifier" style="font-size: 80%;"><b>Linear classifier</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs027.html#some-selected-properties" style="font-size: 80%;"><b>Some selected properties</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs028.html#simple-example" style="font-size: 80%;"><b>Simple example</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs029.html#plotting-the-mean-value-for-each-group" style="font-size: 80%;"><b>Plotting the mean value for each group</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs030.html#the-logistic-function" style="font-size: 80%;"><b>The logistic function</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs031.html#examples-of-likelihood-functions-used-in-logistic-regression-and-nueral-networks" style="font-size: 80%;"><b>Examples of likelihood functions used in logistic regression and nueral networks</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs032.html#two-parameters" style="font-size: 80%;"><b>Two parameters</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs033.html#maximum-likelihood" style="font-size: 80%;"><b>Maximum likelihood</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs034.html#the-cost-function-rewritten" style="font-size: 80%;"><b>The cost function rewritten</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs035.html#minimizing-the-cross-entropy" style="font-size: 80%;"><b>Minimizing the cross entropy</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs036.html#a-more-compact-expression" style="font-size: 80%;"><b>A more compact expression</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs037.html#extending-to-more-predictors" style="font-size: 80%;"><b>Extending to more predictors</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs038.html#including-more-classes" style="font-size: 80%;"><b>Including more classes</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs039.html#more-classes" style="font-size: 80%;"><b>More classes</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs040.html#optimization-the-central-part-of-any-machine-learning-algortithm" style="font-size: 80%;"><b>Optimization, the central part of any Machine Learning algortithm</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs041.html#revisiting-our-logistic-regression-case" style="font-size: 80%;"><b>Revisiting our Logistic Regression case</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs042.html#the-equations-to-solve" style="font-size: 80%;"><b>The equations to solve</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="._week39-bs043.html#solving-using-newton-raphson-s-method" style="font-size: 80%;"><b>Solving using Newton-Raphson's method</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="#example-code-for-logistic-regression" style="font-size: 80%;"><b>Example code for Logistic Regression</b></a></li>
|
|
<!-- navigation toc: --> <li><a href="#synthetic-data-generation" style="font-size: 80%;"> Synthetic data generation</a></li>
|
|
|
|
</ul>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</div> <!-- end of navigation bar -->
|
|
<div class="container">
|
|
<p> </p><p> </p><p> </p> <!-- add vertical space -->
|
|
<a name="part0044"></a>
|
|
<!-- !split -->
|
|
<h2 id="example-code-for-logistic-regression" class="anchor">Example code for Logistic Regression </h2>
|
|
|
|
<p>Here we make a class for Logistic regression. The code uses a simple data set and includes both a binary case and a multiclass case.</p>
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="cell border-box-sizing code_cell rendered">
|
|
<div class="input">
|
|
<div class="inner_cell">
|
|
<div class="input_area">
|
|
<div class="highlight" style="background: #f8f8f8">
|
|
<pre style="line-height: 125%;"><span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">numpy</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">np</span>
|
|
|
|
<span style="color: #008000; font-weight: bold">class</span> <span style="color: #0000FF; font-weight: bold">LogisticRegression</span>:
|
|
<span style="color: #BA2121; font-style: italic">"""</span>
|
|
<span style="color: #BA2121; font-style: italic"> Logistic Regression for binary and multiclass classification.</span>
|
|
<span style="color: #BA2121; font-style: italic"> """</span>
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">__init__</span>(<span style="color: #008000">self</span>, lr<span style="color: #666666">=0.01</span>, epochs<span style="color: #666666">=1000</span>, fit_intercept<span style="color: #666666">=</span><span style="color: #008000; font-weight: bold">True</span>, verbose<span style="color: #666666">=</span><span style="color: #008000; font-weight: bold">False</span>):
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>lr <span style="color: #666666">=</span> lr <span style="color: #408080; font-style: italic"># Learning rate for gradient descent</span>
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>epochs <span style="color: #666666">=</span> epochs <span style="color: #408080; font-style: italic"># Number of iterations</span>
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>fit_intercept <span style="color: #666666">=</span> fit_intercept <span style="color: #408080; font-style: italic"># Whether to add intercept (bias)</span>
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>verbose <span style="color: #666666">=</span> verbose <span style="color: #408080; font-style: italic"># Print loss during training if True</span>
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>weights <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">None</span>
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>multi_class <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">False</span> <span style="color: #408080; font-style: italic"># Will be determined at fit time</span>
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">_add_intercept</span>(<span style="color: #008000">self</span>, X):
|
|
<span style="color: #BA2121; font-style: italic">"""Add intercept term (column of ones) to feature matrix."""</span>
|
|
intercept <span style="color: #666666">=</span> np<span style="color: #666666">.</span>ones((X<span style="color: #666666">.</span>shape[<span style="color: #666666">0</span>], <span style="color: #666666">1</span>))
|
|
<span style="color: #008000; font-weight: bold">return</span> np<span style="color: #666666">.</span>concatenate((intercept, X), axis<span style="color: #666666">=1</span>)
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">_sigmoid</span>(<span style="color: #008000">self</span>, z):
|
|
<span style="color: #BA2121; font-style: italic">"""Sigmoid function for binary logistic."""</span>
|
|
<span style="color: #008000; font-weight: bold">return</span> <span style="color: #666666">1</span> <span style="color: #666666">/</span> (<span style="color: #666666">1</span> <span style="color: #666666">+</span> np<span style="color: #666666">.</span>exp(<span style="color: #666666">-</span>z))
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">_softmax</span>(<span style="color: #008000">self</span>, Z):
|
|
<span style="color: #BA2121; font-style: italic">"""Softmax function for multiclass logistic."""</span>
|
|
exp_Z <span style="color: #666666">=</span> np<span style="color: #666666">.</span>exp(Z <span style="color: #666666">-</span> np<span style="color: #666666">.</span>max(Z, axis<span style="color: #666666">=1</span>, keepdims<span style="color: #666666">=</span><span style="color: #008000; font-weight: bold">True</span>))
|
|
<span style="color: #008000; font-weight: bold">return</span> exp_Z <span style="color: #666666">/</span> np<span style="color: #666666">.</span>sum(exp_Z, axis<span style="color: #666666">=1</span>, keepdims<span style="color: #666666">=</span><span style="color: #008000; font-weight: bold">True</span>)
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">fit</span>(<span style="color: #008000">self</span>, X, y):
|
|
<span style="color: #BA2121; font-style: italic">"""</span>
|
|
<span style="color: #BA2121; font-style: italic"> Train the logistic regression model using gradient descent.</span>
|
|
<span style="color: #BA2121; font-style: italic"> Supports binary (sigmoid) and multiclass (softmax) based on y.</span>
|
|
<span style="color: #BA2121; font-style: italic"> """</span>
|
|
X <span style="color: #666666">=</span> np<span style="color: #666666">.</span>array(X)
|
|
y <span style="color: #666666">=</span> np<span style="color: #666666">.</span>array(y)
|
|
n_samples, n_features <span style="color: #666666">=</span> X<span style="color: #666666">.</span>shape
|
|
|
|
<span style="color: #408080; font-style: italic"># Add intercept if needed</span>
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>fit_intercept:
|
|
X <span style="color: #666666">=</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>_add_intercept(X)
|
|
n_features <span style="color: #666666">+=</span> <span style="color: #666666">1</span>
|
|
|
|
<span style="color: #408080; font-style: italic"># Determine classes and mode (binary vs multiclass)</span>
|
|
unique_classes <span style="color: #666666">=</span> np<span style="color: #666666">.</span>unique(y)
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #008000">len</span>(unique_classes) <span style="color: #666666">></span> <span style="color: #666666">2</span>:
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>multi_class <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">True</span>
|
|
<span style="color: #008000; font-weight: bold">else</span>:
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>multi_class <span style="color: #666666">=</span> <span style="color: #008000; font-weight: bold">False</span>
|
|
|
|
<span style="color: #408080; font-style: italic"># ----- Multiclass case -----</span>
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>multi_class:
|
|
n_classes <span style="color: #666666">=</span> <span style="color: #008000">len</span>(unique_classes)
|
|
<span style="color: #408080; font-style: italic"># Map original labels to 0...n_classes-1</span>
|
|
class_to_index <span style="color: #666666">=</span> {c: idx <span style="color: #008000; font-weight: bold">for</span> idx, c <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #008000">enumerate</span>(unique_classes)}
|
|
y_indices <span style="color: #666666">=</span> np<span style="color: #666666">.</span>array([class_to_index[c] <span style="color: #008000; font-weight: bold">for</span> c <span style="color: #AA22FF; font-weight: bold">in</span> y])
|
|
<span style="color: #408080; font-style: italic"># Initialize weight matrix (features x classes)</span>
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>weights <span style="color: #666666">=</span> np<span style="color: #666666">.</span>zeros((n_features, n_classes))
|
|
|
|
<span style="color: #408080; font-style: italic"># One-hot encode y</span>
|
|
Y_onehot <span style="color: #666666">=</span> np<span style="color: #666666">.</span>zeros((n_samples, n_classes))
|
|
Y_onehot[np<span style="color: #666666">.</span>arange(n_samples), y_indices] <span style="color: #666666">=</span> <span style="color: #666666">1</span>
|
|
|
|
<span style="color: #408080; font-style: italic"># Gradient descent</span>
|
|
<span style="color: #008000; font-weight: bold">for</span> epoch <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #008000">range</span>(<span style="color: #008000">self</span><span style="color: #666666">.</span>epochs):
|
|
scores <span style="color: #666666">=</span> X<span style="color: #666666">.</span>dot(<span style="color: #008000">self</span><span style="color: #666666">.</span>weights) <span style="color: #408080; font-style: italic"># Linear scores (n_samples x n_classes)</span>
|
|
probs <span style="color: #666666">=</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>_softmax(scores) <span style="color: #408080; font-style: italic"># Probabilities (n_samples x n_classes)</span>
|
|
<span style="color: #408080; font-style: italic"># Compute gradient (features x classes)</span>
|
|
gradient <span style="color: #666666">=</span> (<span style="color: #666666">1</span> <span style="color: #666666">/</span> n_samples) <span style="color: #666666">*</span> X<span style="color: #666666">.</span>T<span style="color: #666666">.</span>dot(probs <span style="color: #666666">-</span> Y_onehot)
|
|
<span style="color: #408080; font-style: italic"># Update weights</span>
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>weights <span style="color: #666666">-=</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>lr <span style="color: #666666">*</span> gradient
|
|
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>verbose <span style="color: #AA22FF; font-weight: bold">and</span> epoch <span style="color: #666666">%</span> <span style="color: #666666">100</span> <span style="color: #666666">==</span> <span style="color: #666666">0</span>:
|
|
<span style="color: #408080; font-style: italic"># Compute current loss (categorical cross-entropy)</span>
|
|
loss <span style="color: #666666">=</span> <span style="color: #666666">-</span>np<span style="color: #666666">.</span>sum(Y_onehot <span style="color: #666666">*</span> np<span style="color: #666666">.</span>log(probs <span style="color: #666666">+</span> <span style="color: #666666">1e-15</span>)) <span style="color: #666666">/</span> n_samples
|
|
<span style="color: #008000">print</span>(<span style="color: #BA2121">f"[Epoch </span><span style="color: #BB6688; font-weight: bold">{</span>epoch<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">] Multiclass loss: </span><span style="color: #BB6688; font-weight: bold">{</span>loss<span style="color: #BB6688; font-weight: bold">:</span><span style="color: #BA2121">.4f</span><span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">"</span>)
|
|
|
|
<span style="color: #408080; font-style: italic"># ----- Binary case -----</span>
|
|
<span style="color: #008000; font-weight: bold">else</span>:
|
|
<span style="color: #408080; font-style: italic"># Convert y to 0/1 if not already</span>
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #AA22FF; font-weight: bold">not</span> np<span style="color: #666666">.</span>array_equal(unique_classes, [<span style="color: #666666">0</span>, <span style="color: #666666">1</span>]):
|
|
<span style="color: #408080; font-style: italic"># Map the two classes to 0 and 1</span>
|
|
class0, class1 <span style="color: #666666">=</span> unique_classes
|
|
y_binary <span style="color: #666666">=</span> np<span style="color: #666666">.</span>where(y <span style="color: #666666">==</span> class1, <span style="color: #666666">1</span>, <span style="color: #666666">0</span>)
|
|
<span style="color: #008000; font-weight: bold">else</span>:
|
|
y_binary <span style="color: #666666">=</span> y<span style="color: #666666">.</span>copy()<span style="color: #666666">.</span>astype(<span style="color: #008000">int</span>)
|
|
|
|
<span style="color: #408080; font-style: italic"># Initialize weights vector (features,)</span>
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>weights <span style="color: #666666">=</span> np<span style="color: #666666">.</span>zeros(n_features)
|
|
|
|
<span style="color: #408080; font-style: italic"># Gradient descent</span>
|
|
<span style="color: #008000; font-weight: bold">for</span> epoch <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #008000">range</span>(<span style="color: #008000">self</span><span style="color: #666666">.</span>epochs):
|
|
linear_model <span style="color: #666666">=</span> X<span style="color: #666666">.</span>dot(<span style="color: #008000">self</span><span style="color: #666666">.</span>weights) <span style="color: #408080; font-style: italic"># (n_samples,)</span>
|
|
probs <span style="color: #666666">=</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>_sigmoid(linear_model) <span style="color: #408080; font-style: italic"># (n_samples,)</span>
|
|
<span style="color: #408080; font-style: italic"># Gradient for binary cross-entropy</span>
|
|
gradient <span style="color: #666666">=</span> (<span style="color: #666666">1</span> <span style="color: #666666">/</span> n_samples) <span style="color: #666666">*</span> X<span style="color: #666666">.</span>T<span style="color: #666666">.</span>dot(probs <span style="color: #666666">-</span> y_binary)
|
|
<span style="color: #008000">self</span><span style="color: #666666">.</span>weights <span style="color: #666666">-=</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>lr <span style="color: #666666">*</span> gradient
|
|
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>verbose <span style="color: #AA22FF; font-weight: bold">and</span> epoch <span style="color: #666666">%</span> <span style="color: #666666">100</span> <span style="color: #666666">==</span> <span style="color: #666666">0</span>:
|
|
<span style="color: #408080; font-style: italic"># Compute binary cross-entropy loss</span>
|
|
loss <span style="color: #666666">=</span> <span style="color: #666666">-</span>np<span style="color: #666666">.</span>mean(
|
|
y_binary <span style="color: #666666">*</span> np<span style="color: #666666">.</span>log(probs <span style="color: #666666">+</span> <span style="color: #666666">1e-15</span>) <span style="color: #666666">+</span>
|
|
(<span style="color: #666666">1</span> <span style="color: #666666">-</span> y_binary) <span style="color: #666666">*</span> np<span style="color: #666666">.</span>log(<span style="color: #666666">1</span> <span style="color: #666666">-</span> probs <span style="color: #666666">+</span> <span style="color: #666666">1e-15</span>)
|
|
)
|
|
<span style="color: #008000">print</span>(<span style="color: #BA2121">f"[Epoch </span><span style="color: #BB6688; font-weight: bold">{</span>epoch<span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">] Binary loss: </span><span style="color: #BB6688; font-weight: bold">{</span>loss<span style="color: #BB6688; font-weight: bold">:</span><span style="color: #BA2121">.4f</span><span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">"</span>)
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">predict_prob</span>(<span style="color: #008000">self</span>, X):
|
|
<span style="color: #BA2121; font-style: italic">"""</span>
|
|
<span style="color: #BA2121; font-style: italic"> Compute probability estimates. Returns a 1D array for binary or</span>
|
|
<span style="color: #BA2121; font-style: italic"> a 2D array (n_samples x n_classes) for multiclass.</span>
|
|
<span style="color: #BA2121; font-style: italic"> """</span>
|
|
X <span style="color: #666666">=</span> np<span style="color: #666666">.</span>array(X)
|
|
<span style="color: #408080; font-style: italic"># Add intercept if the model used it</span>
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>fit_intercept:
|
|
X <span style="color: #666666">=</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>_add_intercept(X)
|
|
scores <span style="color: #666666">=</span> X<span style="color: #666666">.</span>dot(<span style="color: #008000">self</span><span style="color: #666666">.</span>weights)
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>multi_class:
|
|
<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>_softmax(scores)
|
|
<span style="color: #008000; font-weight: bold">else</span>:
|
|
<span style="color: #008000; font-weight: bold">return</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>_sigmoid(scores)
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">predict</span>(<span style="color: #008000">self</span>, X):
|
|
<span style="color: #BA2121; font-style: italic">"""</span>
|
|
<span style="color: #BA2121; font-style: italic"> Predict class labels for samples in X.</span>
|
|
<span style="color: #BA2121; font-style: italic"> Returns integer class labels (0,1 for binary, or 0...C-1 for multiclass).</span>
|
|
<span style="color: #BA2121; font-style: italic"> """</span>
|
|
probs <span style="color: #666666">=</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>predict_prob(X)
|
|
<span style="color: #008000; font-weight: bold">if</span> <span style="color: #008000">self</span><span style="color: #666666">.</span>multi_class:
|
|
<span style="color: #408080; font-style: italic"># Choose class with highest probability</span>
|
|
<span style="color: #008000; font-weight: bold">return</span> np<span style="color: #666666">.</span>argmax(probs, axis<span style="color: #666666">=1</span>)
|
|
<span style="color: #008000; font-weight: bold">else</span>:
|
|
<span style="color: #408080; font-style: italic"># Threshold at 0.5 for binary</span>
|
|
<span style="color: #008000; font-weight: bold">return</span> (probs <span style="color: #666666">>=</span> <span style="color: #666666">0.5</span>)<span style="color: #666666">.</span>astype(<span style="color: #008000">int</span>)
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="output_wrapper">
|
|
<div class="output">
|
|
<div class="output_area">
|
|
<div class="output_subarea output_stream output_stdout output_text">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<p>The class implements the sigmoid and softmax internally. During fit(),
|
|
we check the number of classes: if more than 2, we set
|
|
self.multi_class=True and perform multinomial logistic regression. We
|
|
one-hot encode the target vector and update a weight matrix with
|
|
softmax probabilities. Otherwise, we do standard binary logistic
|
|
regression, converting labels to 0/1 if needed and updating a weight
|
|
vector. In both cases we use batch gradient descent on the
|
|
cross-entropy loss (we add a small epsilon 1e-15 to logs for numerical
|
|
stability). Progress (loss) can be printed if verbose=True.
|
|
</p>
|
|
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="cell border-box-sizing code_cell rendered">
|
|
<div class="input">
|
|
<div class="inner_cell">
|
|
<div class="input_area">
|
|
<div class="highlight" style="background: #f8f8f8">
|
|
<pre style="line-height: 125%;"><span style="color: #408080; font-style: italic"># Evaluation Metrics</span>
|
|
<span style="color: #408080; font-style: italic">#We define helper functions for accuracy and cross-entropy loss. Accuracy is the fraction of correct predictions . For loss, we compute the appropriate cross-entropy:</span>
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">accuracy_score</span>(y_true, y_pred):
|
|
<span style="color: #BA2121; font-style: italic">"""Accuracy = (# correct predictions) / (total samples)."""</span>
|
|
y_true <span style="color: #666666">=</span> np<span style="color: #666666">.</span>array(y_true)
|
|
y_pred <span style="color: #666666">=</span> np<span style="color: #666666">.</span>array(y_pred)
|
|
<span style="color: #008000; font-weight: bold">return</span> np<span style="color: #666666">.</span>mean(y_true <span style="color: #666666">==</span> y_pred)
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">binary_cross_entropy</span>(y_true, y_prob):
|
|
<span style="color: #BA2121; font-style: italic">"""</span>
|
|
<span style="color: #BA2121; font-style: italic"> Binary cross-entropy loss.</span>
|
|
<span style="color: #BA2121; font-style: italic"> y_true: true binary labels (0 or 1), y_prob: predicted probabilities for class 1.</span>
|
|
<span style="color: #BA2121; font-style: italic"> """</span>
|
|
y_true <span style="color: #666666">=</span> np<span style="color: #666666">.</span>array(y_true)
|
|
y_prob <span style="color: #666666">=</span> np<span style="color: #666666">.</span>clip(np<span style="color: #666666">.</span>array(y_prob), <span style="color: #666666">1e-15</span>, <span style="color: #666666">1-1e-15</span>)
|
|
<span style="color: #008000; font-weight: bold">return</span> <span style="color: #666666">-</span>np<span style="color: #666666">.</span>mean(y_true <span style="color: #666666">*</span> np<span style="color: #666666">.</span>log(y_prob) <span style="color: #666666">+</span> (<span style="color: #666666">1</span> <span style="color: #666666">-</span> y_true) <span style="color: #666666">*</span> np<span style="color: #666666">.</span>log(<span style="color: #666666">1</span> <span style="color: #666666">-</span> y_prob))
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">categorical_cross_entropy</span>(y_true, y_prob):
|
|
<span style="color: #BA2121; font-style: italic">"""</span>
|
|
<span style="color: #BA2121; font-style: italic"> Categorical cross-entropy loss for multiclass.</span>
|
|
<span style="color: #BA2121; font-style: italic"> y_true: true labels (0...C-1), y_prob: array of predicted probabilities (n_samples x C).</span>
|
|
<span style="color: #BA2121; font-style: italic"> """</span>
|
|
y_true <span style="color: #666666">=</span> np<span style="color: #666666">.</span>array(y_true, dtype<span style="color: #666666">=</span><span style="color: #008000">int</span>)
|
|
y_prob <span style="color: #666666">=</span> np<span style="color: #666666">.</span>clip(np<span style="color: #666666">.</span>array(y_prob), <span style="color: #666666">1e-15</span>, <span style="color: #666666">1-1e-15</span>)
|
|
<span style="color: #408080; font-style: italic"># One-hot encode true labels</span>
|
|
n_samples, n_classes <span style="color: #666666">=</span> y_prob<span style="color: #666666">.</span>shape
|
|
one_hot <span style="color: #666666">=</span> np<span style="color: #666666">.</span>zeros_like(y_prob)
|
|
one_hot[np<span style="color: #666666">.</span>arange(n_samples), y_true] <span style="color: #666666">=</span> <span style="color: #666666">1</span>
|
|
<span style="color: #408080; font-style: italic"># Compute cross-entropy</span>
|
|
loss_vec <span style="color: #666666">=</span> <span style="color: #666666">-</span>np<span style="color: #666666">.</span>sum(one_hot <span style="color: #666666">*</span> np<span style="color: #666666">.</span>log(y_prob), axis<span style="color: #666666">=1</span>)
|
|
<span style="color: #008000; font-weight: bold">return</span> np<span style="color: #666666">.</span>mean(loss_vec)
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="output_wrapper">
|
|
<div class="output">
|
|
<div class="output_area">
|
|
<div class="output_subarea output_stream output_stdout output_text">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<h3 id="synthetic-data-generation" class="anchor">Synthetic data generation </h3>
|
|
|
|
<p>Binary classification data: Create two Gaussian clusters in 2D. For example, class 0 around mean [-2,-2] and class 1 around [2,2].
|
|
Multiclass data: Create several Gaussian clusters (one per class) spread out in feature space.
|
|
</p>
|
|
|
|
|
|
<!-- code=python (!bc pycod) typeset with pygments style "default" -->
|
|
<div class="cell border-box-sizing code_cell rendered">
|
|
<div class="input">
|
|
<div class="inner_cell">
|
|
<div class="input_area">
|
|
<div class="highlight" style="background: #f8f8f8">
|
|
<pre style="line-height: 125%;"><span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">numpy</span> <span style="color: #008000; font-weight: bold">as</span> <span style="color: #0000FF; font-weight: bold">np</span>
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">generate_binary_data</span>(n_samples<span style="color: #666666">=100</span>, n_features<span style="color: #666666">=2</span>, random_state<span style="color: #666666">=</span><span style="color: #008000; font-weight: bold">None</span>):
|
|
<span style="color: #BA2121; font-style: italic">"""</span>
|
|
<span style="color: #BA2121; font-style: italic"> Generate synthetic binary classification data.</span>
|
|
<span style="color: #BA2121; font-style: italic"> Returns (X, y) where X is (n_samples x n_features), y in {0,1}.</span>
|
|
<span style="color: #BA2121; font-style: italic"> """</span>
|
|
rng <span style="color: #666666">=</span> np<span style="color: #666666">.</span>random<span style="color: #666666">.</span>RandomState(random_state)
|
|
<span style="color: #408080; font-style: italic"># Half samples for class 0, half for class 1</span>
|
|
n0 <span style="color: #666666">=</span> n_samples <span style="color: #666666">//</span> <span style="color: #666666">2</span>
|
|
n1 <span style="color: #666666">=</span> n_samples <span style="color: #666666">-</span> n0
|
|
<span style="color: #408080; font-style: italic"># Class 0 around mean -2, class 1 around +2</span>
|
|
mean0 <span style="color: #666666">=</span> <span style="color: #666666">-2</span> <span style="color: #666666">*</span> np<span style="color: #666666">.</span>ones(n_features)
|
|
mean1 <span style="color: #666666">=</span> <span style="color: #666666">2</span> <span style="color: #666666">*</span> np<span style="color: #666666">.</span>ones(n_features)
|
|
X0 <span style="color: #666666">=</span> rng<span style="color: #666666">.</span>randn(n0, n_features) <span style="color: #666666">+</span> mean0
|
|
X1 <span style="color: #666666">=</span> rng<span style="color: #666666">.</span>randn(n1, n_features) <span style="color: #666666">+</span> mean1
|
|
X <span style="color: #666666">=</span> np<span style="color: #666666">.</span>vstack((X0, X1))
|
|
y <span style="color: #666666">=</span> np<span style="color: #666666">.</span>array([<span style="color: #666666">0</span>]<span style="color: #666666">*</span>n0 <span style="color: #666666">+</span> [<span style="color: #666666">1</span>]<span style="color: #666666">*</span>n1)
|
|
<span style="color: #008000; font-weight: bold">return</span> X, y
|
|
|
|
<span style="color: #008000; font-weight: bold">def</span> <span style="color: #0000FF">generate_multiclass_data</span>(n_samples<span style="color: #666666">=150</span>, n_features<span style="color: #666666">=2</span>, n_classes<span style="color: #666666">=3</span>, random_state<span style="color: #666666">=</span><span style="color: #008000; font-weight: bold">None</span>):
|
|
<span style="color: #BA2121; font-style: italic">"""</span>
|
|
<span style="color: #BA2121; font-style: italic"> Generate synthetic multiclass data with n_classes Gaussian clusters.</span>
|
|
<span style="color: #BA2121; font-style: italic"> """</span>
|
|
rng <span style="color: #666666">=</span> np<span style="color: #666666">.</span>random<span style="color: #666666">.</span>RandomState(random_state)
|
|
X <span style="color: #666666">=</span> []
|
|
y <span style="color: #666666">=</span> []
|
|
samples_per_class <span style="color: #666666">=</span> n_samples <span style="color: #666666">//</span> n_classes
|
|
<span style="color: #008000; font-weight: bold">for</span> <span style="color: #008000">cls</span> <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #008000">range</span>(n_classes):
|
|
<span style="color: #408080; font-style: italic"># Random cluster center for each class</span>
|
|
center <span style="color: #666666">=</span> rng<span style="color: #666666">.</span>uniform(<span style="color: #666666">-5</span>, <span style="color: #666666">5</span>, size<span style="color: #666666">=</span>n_features)
|
|
Xi <span style="color: #666666">=</span> rng<span style="color: #666666">.</span>randn(samples_per_class, n_features) <span style="color: #666666">+</span> center
|
|
yi <span style="color: #666666">=</span> [<span style="color: #008000">cls</span>] <span style="color: #666666">*</span> samples_per_class
|
|
X<span style="color: #666666">.</span>append(Xi)
|
|
y<span style="color: #666666">.</span>extend(yi)
|
|
X <span style="color: #666666">=</span> np<span style="color: #666666">.</span>vstack(X)
|
|
y <span style="color: #666666">=</span> np<span style="color: #666666">.</span>array(y)
|
|
<span style="color: #008000; font-weight: bold">return</span> X, y
|
|
|
|
|
|
<span style="color: #408080; font-style: italic"># Generate and test on binary data</span>
|
|
X_bin, y_bin <span style="color: #666666">=</span> generate_binary_data(n_samples<span style="color: #666666">=200</span>, n_features<span style="color: #666666">=2</span>, random_state<span style="color: #666666">=42</span>)
|
|
model_bin <span style="color: #666666">=</span> LogisticRegression(lr<span style="color: #666666">=0.1</span>, epochs<span style="color: #666666">=1000</span>)
|
|
model_bin<span style="color: #666666">.</span>fit(X_bin, y_bin)
|
|
y_prob_bin <span style="color: #666666">=</span> model_bin<span style="color: #666666">.</span>predict_prob(X_bin) <span style="color: #408080; font-style: italic"># probabilities for class 1</span>
|
|
y_pred_bin <span style="color: #666666">=</span> model_bin<span style="color: #666666">.</span>predict(X_bin) <span style="color: #408080; font-style: italic"># predicted classes 0 or 1</span>
|
|
|
|
acc_bin <span style="color: #666666">=</span> accuracy_score(y_bin, y_pred_bin)
|
|
loss_bin <span style="color: #666666">=</span> binary_cross_entropy(y_bin, y_prob_bin)
|
|
<span style="color: #008000">print</span>(<span style="color: #BA2121">f"Binary Classification - Accuracy: </span><span style="color: #BB6688; font-weight: bold">{</span>acc_bin<span style="color: #BB6688; font-weight: bold">:</span><span style="color: #BA2121">.2f</span><span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">, Cross-Entropy Loss: </span><span style="color: #BB6688; font-weight: bold">{</span>loss_bin<span style="color: #BB6688; font-weight: bold">:</span><span style="color: #BA2121">.2f</span><span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">"</span>)
|
|
<span style="color: #408080; font-style: italic">#For multiclass:</span>
|
|
<span style="color: #408080; font-style: italic"># Generate and test on multiclass data</span>
|
|
X_multi, y_multi <span style="color: #666666">=</span> generate_multiclass_data(n_samples<span style="color: #666666">=300</span>, n_features<span style="color: #666666">=2</span>, n_classes<span style="color: #666666">=3</span>, random_state<span style="color: #666666">=1</span>)
|
|
model_multi <span style="color: #666666">=</span> LogisticRegression(lr<span style="color: #666666">=0.1</span>, epochs<span style="color: #666666">=1000</span>)
|
|
model_multi<span style="color: #666666">.</span>fit(X_multi, y_multi)
|
|
y_prob_multi <span style="color: #666666">=</span> model_multi<span style="color: #666666">.</span>predict_prob(X_multi) <span style="color: #408080; font-style: italic"># (n_samples x 3) probabilities</span>
|
|
y_pred_multi <span style="color: #666666">=</span> model_multi<span style="color: #666666">.</span>predict(X_multi) <span style="color: #408080; font-style: italic"># predicted labels 0,1,2</span>
|
|
|
|
acc_multi <span style="color: #666666">=</span> accuracy_score(y_multi, y_pred_multi)
|
|
loss_multi <span style="color: #666666">=</span> categorical_cross_entropy(y_multi, y_prob_multi)
|
|
<span style="color: #008000">print</span>(<span style="color: #BA2121">f"Multiclass Classification - Accuracy: </span><span style="color: #BB6688; font-weight: bold">{</span>acc_multi<span style="color: #BB6688; font-weight: bold">:</span><span style="color: #BA2121">.2f</span><span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">, Cross-Entropy Loss: </span><span style="color: #BB6688; font-weight: bold">{</span>loss_multi<span style="color: #BB6688; font-weight: bold">:</span><span style="color: #BA2121">.2f</span><span style="color: #BB6688; font-weight: bold">}</span><span style="color: #BA2121">"</span>)
|
|
|
|
<span style="color: #408080; font-style: italic"># CSV Export</span>
|
|
<span style="color: #008000; font-weight: bold">import</span> <span style="color: #0000FF; font-weight: bold">csv</span>
|
|
|
|
<span style="color: #408080; font-style: italic"># Export binary results</span>
|
|
<span style="color: #008000; font-weight: bold">with</span> <span style="color: #008000">open</span>(<span style="color: #BA2121">'binary_results.csv'</span>, mode<span style="color: #666666">=</span><span style="color: #BA2121">'w'</span>, newline<span style="color: #666666">=</span><span style="color: #BA2121">''</span>) <span style="color: #008000; font-weight: bold">as</span> f:
|
|
writer <span style="color: #666666">=</span> csv<span style="color: #666666">.</span>writer(f)
|
|
writer<span style="color: #666666">.</span>writerow([<span style="color: #BA2121">"TrueLabel"</span>, <span style="color: #BA2121">"PredictedLabel"</span>])
|
|
<span style="color: #008000; font-weight: bold">for</span> true, pred <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #008000">zip</span>(y_bin, y_pred_bin):
|
|
writer<span style="color: #666666">.</span>writerow([true, pred])
|
|
|
|
<span style="color: #408080; font-style: italic"># Export multiclass results</span>
|
|
<span style="color: #008000; font-weight: bold">with</span> <span style="color: #008000">open</span>(<span style="color: #BA2121">'multiclass_results.csv'</span>, mode<span style="color: #666666">=</span><span style="color: #BA2121">'w'</span>, newline<span style="color: #666666">=</span><span style="color: #BA2121">''</span>) <span style="color: #008000; font-weight: bold">as</span> f:
|
|
writer <span style="color: #666666">=</span> csv<span style="color: #666666">.</span>writer(f)
|
|
writer<span style="color: #666666">.</span>writerow([<span style="color: #BA2121">"TrueLabel"</span>, <span style="color: #BA2121">"PredictedLabel"</span>])
|
|
<span style="color: #008000; font-weight: bold">for</span> true, pred <span style="color: #AA22FF; font-weight: bold">in</span> <span style="color: #008000">zip</span>(y_multi, y_pred_multi):
|
|
writer<span style="color: #666666">.</span>writerow([true, pred])
|
|
</pre>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="output_wrapper">
|
|
<div class="output">
|
|
<div class="output_area">
|
|
<div class="output_subarea output_stream output_stdout output_text">
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<p>
|
|
<!-- navigation buttons at the bottom of the page -->
|
|
<ul class="pagination">
|
|
<li><a href="._week39-bs043.html">«</a></li>
|
|
<li><a href="._week39-bs000.html">1</a></li>
|
|
<li><a href="">...</a></li>
|
|
<li><a href="._week39-bs036.html">37</a></li>
|
|
<li><a href="._week39-bs037.html">38</a></li>
|
|
<li><a href="._week39-bs038.html">39</a></li>
|
|
<li><a href="._week39-bs039.html">40</a></li>
|
|
<li><a href="._week39-bs040.html">41</a></li>
|
|
<li><a href="._week39-bs041.html">42</a></li>
|
|
<li><a href="._week39-bs042.html">43</a></li>
|
|
<li><a href="._week39-bs043.html">44</a></li>
|
|
<li class="active"><a href="._week39-bs044.html">45</a></li>
|
|
</ul>
|
|
<!-- ------------------- end of main content --------------- -->
|
|
</div> <!-- end container -->
|
|
<!-- include javascript, jQuery *first* -->
|
|
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
|
|
<script src="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
|
|
<!-- Bootstrap footer
|
|
<footer>
|
|
<a href="https://..."><img width="250" align=right src="https://..."></a>
|
|
</footer>
|
|
-->
|
|
<center style="font-size:80%">
|
|
<!-- copyright only on the titlepage -->
|
|
</center>
|
|
</body>
|
|
</html>
|
|
|