100 Exercises / column / 100 Exercises in the Line

Learning Manufacturing Quality Forecasting with Python | Introduction to Ridge, Logistic Regression, and Attention

Predict quality risks from processing conditions and determine conditions for improvement

Learning Manufacturing Matrix Analysis with Optimization, Regression, and Attention: 100 Exercises No.051–No.060

In manufacturing sites, factors such as processing speed, feed rate, temperature, vibration, and tool wear all simultaneously affect quality. This article uses a fictional precision parts line as the subject and addresses Predict quality errors, quantify defect risks, stabilize calculations, and narrow down key processes to be checked. from the perspective of a queue.

[!NOTE] This material is a notebook previously used by Surikoubo (or personally by the representative, Kazuyama), and has been reconstructed, edited, and published with the company’s permission.
All data listed is fictional and has no relation whatsoever to real companies, factories, or figures.

Introduction: Practical Challenges in Manufacturing Covered in This Article

In a fictional factory, precision shafts are machined by lots, recording dimensional errors and final inspection pass/fail. Manufacturing engineers aim to predict dimensional errors based on processing conditions and equipment conditions, prioritize lots with a high probability of defects for inspection, and establish a basis for reviewing conditions.

The important thing is not just to create predictive values. It can explain up to Which calculation method is stable, can it capture nonlinear quality changes, and which process points should be focused on. and can only be used for on-site decision-making for the first time.

Common situations on site

  • Machining speed and feed rate are linked, and explanatory variables show strong correlation
  • Continuous values like dimensional errors and binary judgments like defective or good products are mixed together.
  • Even if coefficients are obtained in spreadsheet software, it is difficult to see the convergence of iterative calculations and numerical stability.
  • There are relationships that are difficult to express with linear models, such as quality deterioration only when temperature and vibration are simultaneously high
  • The time series sensor is long, making it difficult for the person in charge to check all points at the same density

Why is this issue so difficult to judge?

Quality models depend not only on prediction accuracy but also on the overlap of explanatory variables, curvature of loss functions, convergence of iterative methods, and trade-offs between missed and overpositive thresholds. Furthermore, the more high-precision the nonlinear model, the more it is necessary to design to explain the scope of application and the basis for judgment to the field.

Therefore, in this article, we apply multiple matrix calculation methods to the same hypothetical data. Rather than simply listing methods, compare them as part of the Linear prediction, failure probability, stable large-scale computation, nonlinear correction, and process time series focusing. judgment process.

Overview of Exercise covered this time

No.ThemeJudgment in the manufacturing industry
051gradient descent methodRepeatedly learning coefficients to reduce quality errors
052Least squares methodFinding a quality prediction formula that minimizes observational error
053normal equationCalculate the regression coefficient directly from the determinant and confirm the assumptions
054Ridge ReturnStabilizing coefficients even under highly correlated machining conditions
055Logistic regressionEstimating the defect probability per lot
056Newton ActEfficiently update defective models using curvature.
057Hessian matrixDiagnosing unstable learning directions and difficult conditions to distinguish
058conjugate gradient methodSolving large-scale simultaneous equations without inverse matrix
059Kernel methodCapturing the nonlinear quality relationship between temperature and vibration
060AttentionVisualize key points to check from the process timeline

Preparing the Python environment

NumPy performs matrix calculations, pandas checks tables, and Matplotlib visualizes. Only the logistic regression evaluation metric uses scikit-learn. It does not depend on external data and fixes the random number generator at np.random.default_rng(42).

import sys
import numpy as np
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import japanize_matplotlib
from sklearn.metrics import confusion_matrix, roc_auc_score
from IPython.display import display

np.set_printoptions(precision=4, suppress=True)
pd.set_option("display.precision", 4)

print("Python     :", sys.version.split()[0])
print("NumPy      :", np.__version__)
print("pandas     :", pd.__version__)
print("Matplotlib :", matplotlib.__version__)
Python     : 3.13.1
NumPy      : 2.5.1
pandas     : 3.0.3
Matplotlib : 3.11.0

Creation of Fictional Data

For 240 lots, it generates machining speed, feed rate, machining temperature, vibration, hydraulic pressure, and tool wear degree. Dimensional errors, surface roughness, and defect flags are considered quality results, and surface roughness includes nonlinear effects of temperature and vibration. Defective flags are generated based on probabilities determined by the condition of the equipment.

The first 180 lots are used for study, and the remaining 60 lots are used for evaluation. In practice, segmentation by chronological order, external verification by equipment, and separation before and after maintenance are necessary, but here we use fixed segmentation to make the differences between matrix methods easier to read.

rng = np.random.default_rng(42)
n = 240

speed = rng.normal(1800, 120, n)
feed = 0.18 + 0.00028 * (speed - 1800) + rng.normal(0, 0.018, n)
temperature = 61 + 0.006 * (speed - 1800) + 16 * (feed - 0.18) + rng.normal(0, 1.4, n)
vibration = 1.5 + 0.0018 * (speed - 1800) + 2.2 * (feed - 0.18) + rng.normal(0, 0.22, n)
pressure = 5.1 - 0.9 * (feed - 0.18) + rng.normal(0, 0.13, n)
tool_wear = rng.uniform(0, 1, n)

dim_error = (
    0.4 + 0.0015 * (speed - 1800) + 4.0 * (feed - 0.18)
    + 0.12 * (temperature - 61) + 0.55 * (vibration - 1.5)
    + 1.25 * tool_wear**2
    + 0.10 * np.maximum(temperature - 62, 0) * np.maximum(vibration - 1.55, 0)
    + rng.normal(0, 0.38, n)
)

z_temp = (temperature - temperature.mean()) / temperature.std()
z_vib = (vibration - vibration.mean()) / vibration.std()
logit_true = -2.5 + 0.65 * z_temp + 0.95 * z_vib + 1.55 * tool_wear + 0.45 * z_temp * z_vib
defect_prob_true = 1 / (1 + np.exp(-logit_true))
defect = rng.binomial(1, defect_prob_true)
surface_roughness = (
    0.75 + 0.28 * z_temp**2 + 0.35 * z_vib**2
    + 0.25 * np.maximum(z_temp, 0) * np.maximum(z_vib, 0)
    + rng.normal(0, 0.12, n)
)

df = pd.DataFrame({
    "lot": [f"L{i:03d}" for i in range(1, n + 1)],
    "processing speed_rpm": speed, "Delivery volume_mm_rev": feed, "processing temperature_C": temperature,
    "vibration_mm_s": vibration, "hydraulic pressure_MPa": pressure, "tool wear": tool_wear,
    "dimensional error_um": dim_error, "surface roughness_Ra": surface_roughness, "bad": defect,
})
display(df.head().round(3))
print(f"Overall defect rate: {df['bad'].mean():.1%}")
lot processing speed_rpm Delivery volume_mm_rev processing temperature_C vibration_mm_s hydraulic pressure_MPa tool wear dimensional error_um surface roughness_Ra bad
0 L001 1836.566 0.174 61.443 1.532 5.315 0.207 0.390 0.873 0
1 L002 1675.202 0.143 61.671 1.443 5.150 0.423 -0.784 0.475 0
2 L003 1890.054 0.174 61.566 1.146 4.975 0.176 -0.053 1.287 0
3 L004 1912.868 0.185 62.573 1.385 5.081 0.135 1.164 0.700 0
4 L005 1565.876 0.153 59.080 0.816 5.120 0.860 0.006 2.269 0
Overall defect rate: 20.4%
feature_cols = ["processing speed_rpm", "Delivery volume_mm_rev", "processing temperature_C", "vibration_mm_s", "hydraulic pressure_MPa", "tool wear"]
train_idx = np.arange(180)
test_idx = np.arange(180, 240)

X_raw = df[feature_cols].to_numpy()
y = df["dimensional error_um"].to_numpy()
y_cls = df["bad"].to_numpy()
mean_x = X_raw[train_idx].mean(axis=0)
std_x = X_raw[train_idx].std(axis=0)
X_std = (X_raw - mean_x) / std_x
X = np.column_stack([np.ones(n), X_std])
X_train, X_test = X[train_idx], X[test_idx]
y_train, y_test = y[train_idx], y[test_idx]

summary = df.loc[train_idx, feature_cols + ["dimensional error_um", "surface roughness_Ra", "bad"]].describe().T[["mean", "std", "min", "max"]]
display(summary.round(3))
mean std min max
processing speed_rpm 1793.188 104.082 1544.154 2149.663
Delivery volume_mm_rev 0.179 0.033 0.080 0.276
processing temperature_C 60.848 1.788 56.053 66.787
vibration_mm_s 1.475 0.343 0.470 2.594
hydraulic pressure_MPa 5.109 0.113 4.805 5.460
tool wear 0.504 0.301 0.005 0.997
dimensional error_um 0.738 0.873 -1.438 3.218
surface roughness_Ra 1.454 1.002 0.475 8.842
bad 0.189 0.393 0.000 1.000

No.051: Slope Descent Method

Meaning in Practice

The gradient descent method gradually updates the coefficient in a direction that reduces the prediction error. It forms the foundation for quality prediction and machine learning, which involve large data volumes and variables, making it difficult to directly calculate all data at once.

Approach to Analysis and Modeling

y^=Xβ\hat{\boldsymbol{y}}=X\boldsymbol{\beta} predicting dimensional errors, half of the mean square error

J(β)=12nXβy22J(\boldsymbol{\beta})=\frac{1}{2n}\lVert X\boldsymbol{\beta}-\boldsymbol{y}\rVert_2^2

If so, the gradient is J=XT(Xβy)/n\nabla J=X^\mathsf{T}(X\boldsymbol{\beta}-\boldsymbol{y})/n. Renewal formula ββηJ\boldsymbol{\beta}\leftarrow\boldsymbol{\beta}-\eta\nabla J is repeated. If the learning rate η\eta is too high, it diverges; if too low, convergence slows down. Standardizing variables is also important for aligning convergence rates.

Check with Python

beta_gd = np.zeros(X_train.shape[1])
learning_rate = 0.08
loss_history = []

for _ in range(600):
    residual = X_train @ beta_gd - y_train
    loss_history.append(np.mean(residual**2) / 2)
    gradient = X_train.T @ residual / len(y_train)
    beta_gd -= learning_rate * gradient

pred_gd = X_test @ beta_gd
rmse_gd = np.sqrt(np.mean((y_test - pred_gd) ** 2))
print(f"Final loss: {loss_history[-1]:.5f}")
print(f"Evaluation DataRMSE: {rmse_gd:.3f} μm")

plt.figure(figsize=(7, 4))
plt.plot(loss_history)
plt.title("Convergence of gradient descent methods")
plt.xlabel("Number of repetitions")
plt.ylabel("Loss (MSE / 2)")
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Final loss: 0.08004
Evaluation data RMSE: 0.414 μm


png

Reading the results

Losses decrease with iterations and converge to a certain level. When deploying on-site, not only final accuracy but also logs are made to ensure the loss curve does not oscillate or diverge, and whether improvements stopped before reaching the upper limit of iterations. If the convergence behavior changes after adding a line, it raises suspicions of changes in units, outliers, or data distribution.


No.052: Least Squares Method

Meaning in Practice

The least squares method finds a coefficient that minimizes the sum of squares between the measured and predicted values. This is a basic method for explaining and forecasting continuous KPIs such as dimensions, cycle time, and power consumption based on machining conditions.

Approach to Analysis and Modeling

The purpose is

minβXβy22\min_{\boldsymbol{\beta}}\lVert X\boldsymbol{\beta}-\boldsymbol{y}\rVert_2^2

That’s right. np.linalg.lstsq is solved using SVD, making it a numerically easier method than explicitly creating inverse matrices. RMSE can be read as the same unit as dimensional error, but it is also important to understand that it is a metric that strongly punishes large errors.

Check with Python

beta_ls, residuals, rank, singular_values = np.linalg.lstsq(X_train, y_train, rcond=None)
pred_ls = X_test @ beta_ls
rmse_ls = np.sqrt(np.mean((y_test - pred_ls) ** 2))

coef_table = pd.DataFrame({
    "item": ["slice"] + feature_cols,
    "Normalization coefficient": beta_ls,
})
display(coef_table.round(4))
print(f"Matrix rank: {rank} / {X_train.shape[1]}")
print(f"Evaluation DataRMSE: {rmse_ls:.3f} μm")
item Normalization coefficient
0 slice 0.7377
1 processing speed_rpm 0.1792
2 Delivery volume_mm_rev 0.1658
3 processing temperature_C 0.2595
4 vibration_mm_s 0.1257
5 hydraulic pressure_MPa -0.0331
6 tool wear 0.3758
Queue rank: 7 / 7
Evaluation data RMSE: 0.414 μm

Reading the results

The absolute value of the coefficient serves as a guideline for comparing how much each standardized condition correlates with dimensional errors. However, these are correlations based on observational data and do not guarantee causal effects when processing conditions are changed. Evaluation RMSE is used to compare the resolution and tolerance range of the measuring instrument to determine whether the error is sufficient for omission of inspection or adjustment of conditions, rather than “high accuracy.”


No.053: Normal Equation

Meaning in Practice

A normal equation shows that the least squares method can be solved as a system of matrices. It is important to understand the basis for calculating coefficients and to grasp why solutions become unstable due to variables being duplicated.

Approach to Analysis and Modeling

If we set the loss gradient to 0,

XTXβ=XTyX^\mathsf{T}X\boldsymbol{\beta}=X^\mathsf{T}\boldsymbol{y}

You will get it. If XTXX^\mathsf{T}X is regular, you can write β=(XTX)1XTy\boldsymbol{\beta}=(X^\mathsf{T}X)^{-1}X^\mathsf{T}\boldsymbol{y}, but in implementation, the inverse matrix is not explicitly displayed and solve is used. Normal equations worsen the number of conditions, so SVD and QR decomposition are prioritized for large-scale, poor-condition problems.

Check with Python

gram = X_train.T @ X_train
rhs = X_train.T @ y_train
beta_normal = np.linalg.solve(gram, rhs)

comparison = pd.DataFrame({
    "item": ["slice"] + feature_cols,
    "lstsq": beta_ls,
    "normal equation": beta_normal,
    "poor": beta_normal - beta_ls,
})
display(comparison.round(8))
print(f"X Conditional number: {np.linalg.cond(X_train):.1f}")
print(f"X^T X Conditional number: {np.linalg.cond(gram):.1f}")
item lstsq normal equation poor
0 slice 0.7377 0.7377 0.0
1 processing speed_rpm 0.1792 0.1792 0.0
2 Delivery volume_mm_rev 0.1658 0.1658 0.0
3 processing temperature_C 0.2595 0.2595 -0.0
4 vibration_mm_s 0.1257 0.1257 -0.0
5 hydraulic pressure_MPa -0.0331 -0.0331 0.0
6 tool wear 0.3758 0.3758 0.0
Number of X conditions: 4.4
Number of X^T X conditions: 19.1

Reading the results

In this data, the coefficients for both methods are almost identical. On the other hand, the number of conditions for XTXX^\mathsf{T}X is greater than XX. In practice, formulas are only theoretically correct and not adopted; instead, the number of variables, correlations, and accuracy requirements are checked. If the number of conditions surges after adding an explanatory variable, review whether the KPI contains new information.


No.054: Ridge Returns

Meaning in Practice

If you include similar variables such as equipment settings and actual measurements, or the original sensor and derived KPIs at the same time, the regression coefficient can fluctuate significantly. Ridge regression reduces coefficients and stabilizes forecasting and operations.

Approach to Analysis and Modeling

Ridge’s return

minβ{Xβy22+λβ22}\min_{\boldsymbol{\beta}}\left\{\lVert X\boldsymbol{\beta}-\boldsymbol{y}\rVert_2^2+\lambda\lVert\boldsymbol{\beta}\rVert_2^2\right\}

Solve the problem and it becomes β^=(XTX+λI)1XTy\hat{\boldsymbol{\beta}}=(X^\mathsf{T}X+\lambda I)^{-1}X^\mathsf{T}\boldsymbol{y}. Here, we add almost the same derivative metrics to the feed volume, intentionally strengthening the correlation. Intercepts are not regularized. λ\lambda is selected based on evaluation data or cross-validation.

Check with Python

feed_proxy = X_std[:, 1] + np.random.default_rng(0).normal(0, 0.001, n)
X_col = np.column_stack([X, feed_proxy])
Xc_train, Xc_test = X_col[train_idx], X_col[test_idx]
penalty = np.eye(Xc_train.shape[1])
penalty[0, 0] = 0

ridge_rows = []
ridge_models = {}
for lam in [0, 0.01, 0.1, 1, 10, 100]:
    beta = np.linalg.solve(Xc_train.T @ Xc_train + lam * penalty, Xc_train.T @ y_train)
    ridge_models[lam] = beta
    ridge_rows.append({
        "lambda": lam,
        "ReceptionRMSE": np.sqrt(np.mean((y_test - Xc_test @ beta) ** 2)),
        "coefficient norm": np.linalg.norm(beta[1:]),
        "feed rate coefficient": beta[2],
        "Derived feeding coefficient": beta[-1],
    })

ridge_result = pd.DataFrame(ridge_rows)
display(ridge_result.round(4))

plt.figure(figsize=(7, 4))
plt.semilogx(ridge_result.loc[1:, "lambda"], ridge_result.loc[1:, "ReceptionRMSE"], marker="o")
plt.title("RidgeStrength of Regularization and Evaluation Error")
plt.xlabel("lambda")
plt.ylabel("ReceptionRMSE(μm)")
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
lambda ReceptionRMSE coefficient norm feed rate coefficient Derived feeding coefficient
0 0.00 0.4139 10.4952 -7.3286 7.4956
1 0.01 0.4140 0.5279 0.0223 0.1436
2 0.10 0.4140 0.5207 0.0769 0.0891
3 1.00 0.4144 0.5186 0.0833 0.0845
4 10.00 0.4182 0.5000 0.0906 0.0907
5 100.00 0.4624 0.3881 0.1064 0.1064

png

Reading the results

Without regularization, coefficients are unstably distributed to almost the same two feed indicators. A moderate ridge maintains evaluation error while suppressing the coefficient norm. λ\lambda that is too large will shrink to the required signal. When explaining coefficients as causal contributions, even with Ridge, you can organize the meaning of duplicate variables and record the selected λ\lambda and evaluation methods.


No.055: Logistic Regression

Meaning in Practice

Not only can it directly predict the binary values of defective and good products, but by outputting it as defect probability, multiple operational thresholds such as full inspection, additional inspection, and normal shipment can be designed.

Approach to Analysis and Modeling

Logistic regression is

pi=σ(xiTβ)=11+exp(xiTβ)p_i=\sigma(\boldsymbol{x}_i^\mathsf{T}\boldsymbol{\beta}) =\frac{1}{1+\exp(-\boldsymbol{x}_i^\mathsf{T}\boldsymbol{\beta})}

represents the defect probability. We minimize cross-entropy loss and learn here using gradient descent. The probability threshold is not fixed at 0.5, but is determined by missed costs, additional inspection capacity, and defect rates.

Check with Python

def sigmoid(z):
    z = np.clip(z, -30, 30)
    return 1 / (1 + np.exp(-z))

beta_logit = np.zeros(X_train.shape[1])
logloss_history = []
for _ in range(1500):
    p = sigmoid(X_train @ beta_logit)
    logloss = -np.mean(y_cls[train_idx] * np.log(p + 1e-12) + (1 - y_cls[train_idx]) * np.log(1 - p + 1e-12))
    logloss_history.append(logloss)
    beta_logit -= 0.08 * (X_train.T @ (p - y_cls[train_idx]) / len(train_idx))

p_test = sigmoid(X_test @ beta_logit)
threshold = 0.35
pred_cls = (p_test >= threshold).astype(int)
cm = confusion_matrix(y_cls[test_idx], pred_cls)
tn, fp, fn, tp = cm.ravel()

metrics = pd.Series({
    "AUC": roc_auc_score(y_cls[test_idx], p_test),
    "Recall (Poor Capture Rate)": tp / (tp + fn),
    "Compatibility rate": tp / (tp + fp),
    "Additional testing rate": pred_cls.mean(),
})
display(metrics.to_frame("value").round(3))
display(pd.DataFrame(cm, index=["In fact,_good product", "In fact,_bad"], columns=["Prediction_good product", "Prediction_bad"]))
value
AUC 0.776
Recall (Poor Capture Rate) 0.533
Compatibility rate 0.615
Additional testing rate 0.217
Prediction_good product Prediction_bad
In fact,_good product 40 5
In fact,_bad 7 8

Reading the results

AUC represents the lot’s risk ranking ability, recall rate indicates how many actual defects were picked up, and accuracy rate represents the efficiency of additional inspections. The threshold of 0.35 is designed to cover a wider range of inspection targets and minimize missed opportunities. In practice, indicators fluctuate during periods with fewer defects, so confidence intervals, product type evaluation, probability calibration, and inspection load after threshold changes are checked together.


No.056: Newton Method

Meaning in Practice

The Newton method adjusts the update width not only by gradient but also by using the curvature of the loss function. While reducing the number of iterations, each update solves simultaneous equations, so when there are many variables, it is necessary to design computational load and stability.

Approach to Analysis and Modeling

Using gradient g\boldsymbol{g} and Hessian matrix HH,

βk+1=βkH1g\boldsymbol{\beta}_{k+1}=\boldsymbol{\beta}_k-H^{-1}\boldsymbol{g}

I will update you. In logistic regression, H=XTWXH=X^\mathsf{T}WX and W=diag(pi(1pi))W=\mathrm{diag}(p_i(1-p_i)) are used. In the implementation, instead of creating an inverse matrix, solve is used, and small diagonal terms are added for numerical stability.

Check with Python

beta_newton = np.zeros(X_train.shape[1])
newton_history = []

for iteration in range(10):
    p = sigmoid(X_train @ beta_newton)
    loss = -np.mean(y_cls[train_idx] * np.log(p + 1e-12) + (1 - y_cls[train_idx]) * np.log(1 - p + 1e-12))
    newton_history.append(loss)
    gradient = X_train.T @ (p - y_cls[train_idx])
    weights = p * (1 - p)
    hessian = X_train.T @ (weights[:, None] * X_train) + 1e-6 * np.eye(X_train.shape[1])
    beta_newton -= np.linalg.solve(hessian, gradient)

display(pd.DataFrame({
    "Repeatedly": np.arange(1, len(newton_history) + 1),
    "Newtonloss of law": newton_history,
}).round(6))
print(f"Final Loss of the Slope Descent Method: {logloss_history[-1]:.6f}")
print(f"NewtonFinal loss of law: {newton_history[-1]:.6f}")
Repeatedly Newtonloss of law
0 1 0.6931
1 2 0.3831
2 3 0.3437
3 4 0.3378
4 5 0.3376
5 6 0.3376
6 7 0.3376
7 8 0.3376
8 9 0.3376
9 10 0.3376
Final loss by gradient descent: 0.337600
Newton Act final loss: 0.337592

Reading the results

The Newton method reduces losses with fewer iterations. However, having “fewer iterations” does not mean “shorter computation times.” In models with many variables, creating and solving Hessian matrices becomes dominant. If data is nearly completely separated or explanatory variables overlap, it becomes unstable, so regularization and stepwidth control are combined.


No.057: Hessian Matrix

Meaning in Practice

The Hessian matrix represents how much the loss bends in each direction of each parameter. Small eigenvalue directions are where it is difficult to identify coefficients from the data, and estimates can easily fluctuate with slight data changes.

Approach to Analysis and Modeling

A Hessian matrix is a matrix arranged with second-order partial derivatives

Hjk=2JβjβkH_{jk}=\frac{\partial^2 J}{\partial\beta_j\partial\beta_k}

That’s right. If all eigenvalues are positive, it is locally convex. If the ratio of maximum eigenvalues to minimum eigenvalues is large, the curvature difference in each direction becomes larger, making optimization more difficult. The diagonal term of Ridge pushes up small eigenvalues.

Check with Python

p_col = sigmoid(Xc_train @ np.pad(beta_newton, (0, 1)))
W_col = p_col * (1 - p_col)
H_col = Xc_train.T @ (W_col[:, None] * Xc_train)
H_ridge = H_col + 1.0 * penalty

eig_plain = np.linalg.eigvalsh(H_col)
eig_ridge = np.linalg.eigvalsh(H_ridge)
hessian_table = pd.DataFrame({
    "indicator": ["Minimum eigenvalue", "maximum eigenvalue", "Conditional number"],
    "No regularization": [eig_plain.min(), eig_plain.max(), np.linalg.cond(H_col)],
    "RidgeAvailable": [eig_ridge.min(), eig_ridge.max(), np.linalg.cond(H_ridge)],
})
display(hessian_table.round(4))

plt.figure(figsize=(7, 4))
plt.semilogy(np.arange(1, len(eig_plain) + 1), eig_plain, marker="o", label="No regularization")
plt.semilogy(np.arange(1, len(eig_ridge) + 1), eig_ridge, marker="s", label="RidgeAvailable")
plt.title("eigenvalues of Hessian matrices")
plt.xlabel("Ranking of eigenvalues (ascending)")
plt.ylabel("eigenvalue (logarithmic line)")
plt.grid(True, alpha=0.3)
plt.legend()
plt.tight_layout()
plt.show()
indicator No regularization RidgeAvailable
0 Minimum eigenvalue 0.0000e+00 1.0000
1 maximum eigenvalue 7.6713e+01 77.5857
2 Conditional number 8.1267e+06 77.5850

png

Reading the results

Including a nearly overlapping stroke indicator reduces the minimum eigenvalue and creates a flat direction on the loss plane. Ridge adds curvature in that direction to improve the number of conditions. In practice, deterioration in the number of conditions is not treated merely as a calculation problem, but as a data design issue involving “whether KPIs with almost the same meaning are being managed redundantly” or “whether independent test conditions are lacking.”


No.058: Conjugate Gradient Method

Meaning in Practice

As the number of devices, varieties, and features increases, the cost of directly decomposing the matrix of simultaneous equations rises. The conjugate gradient method finds the solution for symmetric positive definite matrices by iterating the matrix vector product without creating an inverse matrix.

Approach to Analysis and Modeling

Normal Equations of Ridge Regression

Aβ=b,A=XTX+λIA\boldsymbol{\beta}=\boldsymbol{b},\quad A=X^\mathsf{T}X+\lambda I

becomes a symmetric positive definite value through regularization. The conjugate gradient method uses AA conjugate search directions to efficiently minimize quadratic forms. Residual bAβ2\lVert\boldsymbol{b}-A\boldsymbol{\beta}\rVert_2 is used for convergence determination.

Check with Python

def conjugate_gradient(A, b, tol=1e-10, max_iter=100):
    x = np.zeros_like(b)
    r = b - A @ x
    p = r.copy()
    residual_norms = [np.linalg.norm(r)]
    for _ in range(max_iter):
        Ap = A @ p
        alpha = (r @ r) / (p @ Ap)
        x = x + alpha * p
        r_new = r - alpha * Ap
        residual_norms.append(np.linalg.norm(r_new))
        if residual_norms[-1] < tol:
            break
        beta = (r_new @ r_new) / (r @ r)
        p = r_new + beta * p
        r = r_new
    return x, residual_norms

lam = 1.0
A_cg = Xc_train.T @ Xc_train + lam * penalty
b_cg = Xc_train.T @ y_train
beta_cg, cg_residuals = conjugate_gradient(A_cg, b_cg)
beta_direct = np.linalg.solve(A_cg, b_cg)

print(f"Number of repetitions: {len(cg_residuals) - 1}")
print(f"Difference from the direct method: {np.linalg.norm(beta_cg - beta_direct):.3e}")

plt.figure(figsize=(7, 4))
plt.semilogy(cg_residuals, marker="o")
plt.title("Residual Convergence of Conjugate Gradient Method")
plt.xlabel("Number of repetitions")
plt.ylabel("residual norm")
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
Number of repetitions: 9
Difference from direct method: 1.491e-14


png

Reading the results

The residual decreases with fewer iterations, yielding a solution close to the direct method. For this small matrix, the direct method is sufficient, but the conjugate gradient method is effective for large-scale problems where it is difficult to explicitly hold the matrix. In practice, we manage positive statability, tolerance of error, maximum iteration, and whether preprocessing is used, and design operations that do not deliver old coefficients before convergence.


No.059: Kernel Method

Meaning in Practice

Surface roughness can suddenly deteriorate in areas where temperature or vibration deviate from the standard, or where both are high. The kernel method does not explicitly create numerous nonlinear features from the original variable, but instead makes nonlinear predictions based on relationships between similar operating conditions.

Approach to Analysis and Modeling

RBF Kernel

k(x,x)=exp(γxx22)k(\boldsymbol{x},\boldsymbol{x}')=\exp\left(-\gamma\lVert\boldsymbol{x}-\boldsymbol{x}'\rVert_2^2\right)

Create a similarity matrix KK between learning points. At Kernel Ridge,

(K+λI)α=y(K+\lambda I)\boldsymbol{\alpha}=\boldsymbol{y}

and predict from the kernel value with the new point. γ\gamma controls the scope of influence, λ\lambda controls smoothness, and extrapolation outside the learning area is handled with care.

Check with Python

kernel_cols = [2, 3]  # Processing temperature and vibration after standardization
Z_train = X_std[train_idx][:, kernel_cols]
Z_test = X_std[test_idx][:, kernel_cols]

def rbf_kernel(A, B, gamma=0.7):
    sq_dist = ((A[:, None, :] - B[None, :, :]) ** 2).sum(axis=2)
    return np.exp(-gamma * sq_dist)

rough_train = df.loc[train_idx, "surface roughness_Ra"].to_numpy()
rough_test = df.loc[test_idx, "surface roughness_Ra"].to_numpy()
K_train = rbf_kernel(Z_train, Z_train, gamma=0.1)
alpha = np.linalg.solve(K_train + 0.01 * np.eye(len(train_idx)), rough_train)
pred_kernel = rbf_kernel(Z_test, Z_train, gamma=0.1) @ alpha

Z_linear = np.column_stack([np.ones(len(train_idx)), Z_train])
coef_linear = np.linalg.lstsq(Z_linear, rough_train, rcond=None)[0]
pred_linear_2d = np.column_stack([np.ones(len(test_idx)), Z_test]) @ coef_linear

kernel_compare = pd.DataFrame({
    "Model": ["Linear Regression of Temperature and Vibration", "RBF Kernel Ridge"],
    "ReceptionRMSE": [
        np.sqrt(np.mean((rough_test - pred_linear_2d) ** 2)),
        np.sqrt(np.mean((rough_test - pred_kernel) ** 2)),
    ],
})
display(kernel_compare.round(4))

plt.figure(figsize=(6, 5))
plt.scatter(rough_test, pred_kernel, c=df.loc[test_idx, "tool wear"], cmap="viridis", alpha=0.8)
limits = [min(rough_test.min(), pred_kernel.min()), max(rough_test.max(), pred_kernel.max())]
plt.plot(limits, limits, "--", color="gray", label="Measured=Prediction")
plt.title("Surface roughness prediction using the kernel method")
plt.xlabel("Measured surface roughness (Ra)")
plt.ylabel("Predicted surface roughness (Ra)")
plt.grid(True, alpha=0.3)
plt.colorbar(label="tool wear")
plt.legend()
plt.tight_layout()
plt.show()
Model ReceptionRMSE
0 Linear Regression of Temperature and Vibration 0.8336
1 RBF Kernel Ridge 0.1498

png

Reading the results

The kernel method captures the curved relationship between temperature and vibration, reducing surface roughness evaluation error compared to linear regression with the same two variables. However, these two variables alone can still affect factors like tool wear. If you notice uneven wear in color, this is an additional candidate. It is necessary to detect conditions outside the training data without increasing variables solely by improving accuracy, and to hold forecasts outside the applicable scope.


No.060:Attention

Meaning in Practice

If there is a large amount of time series data during a single batch of processing, simply averaging all points with the same weight can dilute the short time with strong abnormal signs. Attention assigns significant weight to points relevant to the current decision-making purpose.

Approach to Analysis and Modeling

Scaled Dot-Product Attention

Attention(Q,K,V)=softmax(QKTdk)V\mathrm{Attention}(Q,K,V)=\mathrm{softmax}\left(\frac{QK^\mathsf{T}}{\sqrt{d_k}}\right)V

That’s right. QQ indicates the state you want to find, KK shows the characteristics at each point in time, and VV represents the information you want to consolidate. Here, instead of using a trained Transformer, we use a simplified example querying high temperature, vibration, and load to confirm the meaning of weight. Weight does not prove a causal cause of failure.

Check with Python

stages = np.arange(1, 13)
stage_temp = np.array([59.8, 60.2, 60.7, 61.0, 61.4, 62.0, 62.6, 63.7, 64.2, 63.4, 62.8, 62.1])
stage_vib = np.array([1.20, 1.24, 1.28, 1.31, 1.35, 1.42, 1.51, 1.82, 2.05, 1.72, 1.55, 1.44])
stage_load = np.array([0.40, 0.43, 0.48, 0.52, 0.56, 0.61, 0.67, 0.91, 1.00, 0.78, 0.65, 0.55])

stage_matrix = np.column_stack([stage_temp, stage_vib, stage_load])
keys = (stage_matrix - stage_matrix.mean(axis=0)) / stage_matrix.std(axis=0)
query = np.array([0.7, 1.0, 0.6])
scores = keys @ query / np.sqrt(keys.shape[1])
weights = np.exp(scores - scores.max())
weights /= weights.sum()
values = 0.4 * keys[:, 0] + 0.8 * keys[:, 1] + 0.5 * keys[:, 2]
attention_summary = weights @ values

attention_table = pd.DataFrame({
    "Project Timing": stages, "temperature_C": stage_temp, "vibration_mm_s": stage_vib,
    "load index": stage_load, "Attentionweight": weights,
}).sort_values("Attentionweight", ascending=False)
display(attention_table.head(5).round(4))
print(f"AttentionRisk expressions summarized in: {attention_summary:.3f}")

plt.figure(figsize=(8, 4))
plt.bar(stages, weights, color=np.where(weights >= np.quantile(weights, 0.75), "tomato", "steelblue"))
plt.title("At each process point in time,Attentionweight")
plt.xlabel("Project Timing")
plt.ylabel("Attentionweight")
plt.xticks(stages)
plt.grid(True, axis="y", alpha=0.3)
plt.tight_layout()
plt.show()
Project Timing temperature_C vibration_mm_s load index Attentionweight
8 9 64.2 2.05 1.00 0.4829
7 8 63.7 1.82 0.91 0.2036
9 10 63.4 1.72 0.78 0.1143
10 11 62.8 1.55 0.65 0.0498
6 7 62.6 1.51 0.67 0.0444
Risk expression summarized by Attention: 2.309


png

Reading the results

At process points where temperature, vibration, and load rise simultaneously, significant weight is added, allowing staff to narrow down candidates for waveform inspection. However, this weight depends on the query you set. The practical Attention model examines biases, masking, sensor defects, process lengths by product type, and differences in weight and prediction contributions, then reviews them alongside the original waveform.


Practical Implications Seen Through Target Exercise

  1. Classifying methods by objective variables: For dimensional errors, select the least square; for defect probability, select the loss function from the on-site decision-making format, such as the least square; for defect probability, Logistic regression.
  2. Quality control for convergence and stability: Record gradients, losses, residuals, number of conditions, and eigenvalues of the Hessian matrix; simply obtaining a value does not count as a normal termination.
  3. strongly correlatedKPIOrganize: Ridge is effective for stabilization, but it is not a reason to leave duplicate metric business definitions unaddressed.
  4. Scope management is necessary for non-linearization.: While kernel methods capture complex quality relationships, they pay attention to extrapolation and explainability beyond the learning scope.
  5. Attentionis a guide line that narrows down the points of confirmation.: Instead of using weight to determine the cause, it connects to the original sensor, maintenance history, and actual item verification.

What is necessary for practical implementation

1. Define the purpose of the judgment and the loss

Dimensional forecasting, additional inspections, condition recommendations, and equipment shutdowns all contribute to the cost of errors. Missed cases, over-detections, inspection man-hours, and downtime losses are organized, and success is determined not only by RMSE and AUC but also by operational KPIs.

2. Managing Data Lineage and Segmentation

It links equipment, varieties, tools, material lots, workers, maintenance history, and instrument calibration. To avoid mixing in future information, we conduct verification across chronological sequences, equipment, and product types.

3. Monitor numerical calculations

Standardization criteria, missing processing, regularization factors, convergence conditions, and library versions are fixed. Include the number of conditions, number of iterations, residuals, and flags outside the prediction range as monitoring items in the model.

4. Connect to the site flow

Determine the number of test targets, responsible departments, confirmation deadlines, and lifting conditions for each probability threshold. Attention Weights and coefficients are displayed along with the source data, allowing personnel to track the basis.

5. Define the division of responsibility after the PoC

Clarify who is responsible for data quality, model updates, threshold approvals, equipment shutdown decisions, and audit logs. We also prepare for degenerate driving when model performance declines and for reverting to old rules.

Conclusion

From No.051 to No.060, starting with gradient descent and least squares methods, we examined normal equations, Ridge regression, logistic regression, Newton’s method, Hessian matrix, conjugate gradient method, kernel method, and attention as one of the manufacturing quality decision stories.

Matrix calculation is not just a technique for creating predicted values. By visualizing convergence, curvature, correlation, regularization, similarity, and weighting at point in time, it becomes a tool for sharing What results to trust under what conditions, and what to check next? within the organization.

Consultations for Corporations

At Suri Kobo, we support quality forecasting, defect factor analysis, machining condition optimization, equipment data utilization, model numerical stability evaluation, and the transition from PoC to on-site operations in manufacturing. Even at a stage where the location and purpose of data are not yet organized, you can consult with us starting from inventory of business challenges.

📩 Contact Us: surikobo.co.jp/contact
Please feel free to consult us first.