<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hirotaka Niitsuma</title>
    <description>The latest articles on DEV Community by Hirotaka Niitsuma (@niitsuma).</description>
    <link>https://dev.to/niitsuma</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2280644%2F2e0458d1-5155-4083-bdee-cd733aa3ef0c.png</url>
      <title>DEV Community: Hirotaka Niitsuma</title>
      <link>https://dev.to/niitsuma</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/niitsuma"/>
    <language>en</language>
    <item>
      <title>scm2cpp-learn: 44 scikit-learn estimators, same results, up to ~1000x faster</title>
      <dc:creator>Hirotaka Niitsuma</dc:creator>
      <pubDate>Mon, 02 Nov 2026 13:13:58 +0000</pubDate>
      <link>https://dev.to/niitsuma/scm2cpp-learn-44-scikit-learn-estimators-same-results-up-to-1000x-faster-243l</link>
      <guid>https://dev.to/niitsuma/scm2cpp-learn-44-scikit-learn-estimators-same-results-up-to-1000x-faster-243l</guid>
      <description>&lt;p&gt;I'd like to share an open source (MIT) project I've been working on: &lt;strong&gt;scm2cpp-learn&lt;/strong&gt;, drop-in replacements for scikit-learn estimators.&lt;/p&gt;

&lt;h2&gt;
  
  
  What it is
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;44 scikit-learn estimators (Lasso, LogisticRegression, RFE, PCA, SVM, ...) implementing &lt;strong&gt;the same algorithms with the same results&lt;/strong&gt; — coefficients agree to rounding error&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;1.5x to ~1000x faster&lt;/strong&gt; (e.g. RFE 1,047x; MultiTaskElasticNetCV ~100x on a single core)&lt;/li&gt;
&lt;li&gt;scikit-learn API compatible: works in &lt;code&gt;Pipeline&lt;/code&gt; and &lt;code&gt;GridSearchCV&lt;/code&gt;, passes &lt;code&gt;check_estimator&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Prebuilt wheels for Linux, macOS and Windows; optional GPU (CUDA)
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;scm2cpp-learn
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Swap the import and keep the rest of your code:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;scm2cpp_learn&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;LBFGSLogisticRegression&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;LogisticRegression&lt;/span&gt;

&lt;span class="n"&gt;clf&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LogisticRegression&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;C&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mf"&gt;1.0&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fit&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;   &lt;span class="c1"&gt;# same iterations and coefficients as scikit-learn
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Benchmarks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdkcu98du6iaw5x1guhqs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fdkcu98du6iaw5x1guhqs.png" alt="Bar chart of speed-ups over scikit-learn, from 1.8x (NMF) to 1,047x (RFE)" width="800" height="720"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Speed-up over scikit-learn 1.9 on one core (i9-10900X); GPU rows on an RTX 4090. Full conditions for everymachinelearning row are in the README.&lt;/p&gt;
&lt;h2&gt;
  
  
  Why is it faster?
&lt;/h2&gt;

&lt;p&gt;The algorithms are unchanged — the computation is reorganized:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Lasso cross-validation&lt;/strong&gt;: the Gram matrix (X'X) is computed once, and each fold's matrix is obtained by subtraction, so the original data is never scanned again.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RFE&lt;/strong&gt;: instead of refitting the model every round, a Cholesky factor is downdated as each feature is removed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GPU&lt;/strong&gt;: many penalties are solved in parallel, one CUDA block each.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  The twist
&lt;/h2&gt;

&lt;p&gt;The algorithms are written in Scheme and translated into readable C++ by my compiler, scm2cpp, which derives these optimizations automatically from the naive version.&lt;/p&gt;
&lt;h2&gt;
  
  
  Limitations
&lt;/h2&gt;

&lt;p&gt;Not everything is faster: PCA with many features, for example, can be slower, and the kernels are single-threaded, so Intel's sklearnex with many cores wins on some estimators. All of this is documented in the README, including a comparison with sklearnex.&lt;/p&gt;
&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/niitsuma" rel="noopener noreferrer"&gt;
        niitsuma
      &lt;/a&gt; / &lt;a href="https://github.com/niitsuma/scm2cpp" rel="noopener noreferrer"&gt;
        scm2cpp
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Scheme to readable C++. scikit-learn's algorithms written plainly in Scheme come out fast: the translator derives Gram and loop-invariant products, hands them to BLAS/cuBLAS and turns loops into CUDA kernels. pip install scm2cpp-learn (wheels for Linux, macOS, Windows).
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Scm2Cpp&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;&lt;a href="https://github.com/niitsuma/scm2cpp/actions/workflows/tests.yml" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/niitsuma/scm2cpp/actions/workflows/tests.yml/badge.svg" alt="tests"&gt;&lt;/a&gt; &lt;a href="https://colab.research.google.com/github/niitsuma/scm2cpp/blob/master/notebooks/compare-sklearn.ipynb" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/eff96fda6b2e0fff8cdf2978f89d61aa434bb98c00453ae23dd0aab8d1451633/68747470733a2f2f636f6c61622e72657365617263682e676f6f676c652e636f6d2f6173736574732f636f6c61622d62616467652e737667" alt="Open In Colab"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href="https://github.com/niitsuma/scm2cpp/blob/master/README.ja.md" rel="noopener noreferrer"&gt;Japanese (README.ja.md)&lt;/a&gt; · &lt;a href="https://github.com/niitsuma/scm2cpp/blob/master/README.zh.md" rel="noopener noreferrer"&gt;中文 (README.zh.md)&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Scm2Cpp translates a subset of Scheme into C++ that a person can read
and edit, and scikit-learn's machine-learning algorithms, written in it
plainly, come out fast. The translator derives the fast form of an
algorithm from the naive one (the Gram matrix hoisted out of a
coordinate descent, a loop-invariant product formed once), hands the
products to BLAS or cuBLAS, and turns parallel loops into CUDA kernels
The estimators ship on PyPI as &lt;code&gt;scm2cpp-learn&lt;/code&gt; (&lt;code&gt;scm2cpp-lasso&lt;/code&gt; up to
0.17.0; that name still installs it), with compiled wheels for Linux
macOS and Windows (no compiler, no Racket).&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Machine-learning algorithms it speeds up&lt;/h2&gt;

&lt;/div&gt;
&lt;p&gt;Each is scikit-learn's own algorithm written in the subset, checked
against scikit-learn's iterations and results. Times against
scikit-learn on one core (i9-10900X, an RTX 4090 for the device rows,
scikit-learn 1.9); the conditions are in the section named on the right.&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;algorithm, n&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/niitsuma/scm2cpp" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;PyPI: &lt;a href="https://pypi.org/project/scm2cpp-learn/" rel="noopener noreferrer"&gt;https://pypi.org/project/scm2cpp-learn/&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Feedback is very welcome!&lt;/p&gt;

</description>
      <category>python</category>
      <category>opensource</category>
      <category>performance</category>
      <category>machinelearning</category>
    </item>
  </channel>
</rss>
