news 2026/10/3 19:12:38

python的先进制造技术工业场景模拟第三十七篇:读取车削工艺试验数据集,建立回归模型,由进给,转速预测零件表面粗糙度。

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
python的先进制造技术工业场景模拟第三十七篇:读取车削工艺试验数据集,建立回归模型,由进给,转速预测零件表面粗糙度。

周三下午,精加工工段试切间。

"这批 45# 钢轴,要求 Ra1.6,"工艺员小郑把一沓试切记录摊在桌角,"每次调完转速和进给,就车几件去测粗糙度,测完再手调。前天 S1200 F0.1 出来 Ra1.4,昨天 S1000 F0.15 出来 Ra2.1,今天想试 S1500 F0.08,又得再车一轮。"

我点开他们导出的试切表。

"这表里有什么?"小郑问。

"每条是一次试切:转速、进给、切深、实测 Ra,"我指着屏幕,"但它就是个记录本,没建模型。想预测'某个转速+进给组合下 Ra 大概多少',现在只能靠老师傅经验拍,或者硬试。试一次就是半小时机床占用 + 一件毛坯。"

"我就想干一件事,"小郑说,"拿历史试切数据训个模型,输入转速和进给,直接吐出预测 Ra,顺便告诉我哪个参数影响大,还能画个曲面看'好参数区'在哪。以后工艺卡不用试切堆出来,按模型反推就行。"

"比如 S1200 F0.1 预测 Ra1.42,实测 1.39;S1000 F0.15 预测 Ra2.08,实测 2.11,"我接话,"误差压到 0.05 以内,模型就够排工艺卡用了。再算特征重要性,进给对 Ra 的影响比转速还大,这跟理论公式对得上。"

"对,"小郑点头,"还想看残差,怕模型在高速区瞎猜;也想看不同材料是不是要分开建模型。"

"用 pandas 读试切数据,numpy 做特征工程,scikit-learn 建线性回归+多项式回归+随机森林做对照,scipy 做显著性检验和置信区间,matplotlib 画散点拟合线+预测曲面+残差图+重要性柱状图,networkx 建'参数-响应'关系网,"我开工程,"数据自包含,合成一批车削试切数据,下载就能跑。"

敲了行原型:

X = df[["spindle_rpm", "feed_mm_rev"]]

model = LinearRegression().fit(X, df["ra"])

# 理论: Ra ∝ f^2 / (8*r*N) 的简化经验映射

"完整版 OOP 封好,"我说,"加载器、特征工程器、回归建模器、显著性分析器、残差诊断器、关系网、出图器,输出预测模型 + 5图 + 报告,存 results/。"

小郑凑近看:"那以后看报告:线性模型 R²=0.93,进给系数显著为正,转速系数显著为负;预测曲面里 Ra≤1.6 的区域是'高转速+低进给'那块绿区;残差在高速区无系统偏置;随机森林特征重要性进给占 0.61;工艺卡直接挂'推荐 S1300~1500 / F0.08~0.10'。"

"对,"我接话,"表面粗糙度不是测出来再调,是模型算出来先定工艺。数字孪生里建切削质量模型,这套回归就是标定底座。"

一、实际应用场景(真实痛点)

场景设定:车削精加工试切阶段,工艺组通过反复调转速/进给/切深验证表面粗糙度,试切成本高、周期长,且经验难以沉淀。需要把历史试切数据转成"参数→Ra"的可解释预测模型,支撑工艺卡编制与参数窗口推荐。

现场原话(叙事化):

"不是我们不会调参数,"小郑说,"是会调但说不清。老师傅说'转速高点进给低点就光',可高到多少、低到多少,全靠试。每次试切都是占机床,客户催货的时候最头疼。"

"还有材料的事,"小郑补充,"45# 和 40Cr 放一起训,模型就糊了,40Cr 黏刀,同参数 Ra 偏高。想按材料分模型,也想知道理论公式和模型是不是对得上。"

核心矛盾:"试切记录流水" 与 "可解释回归模型 + 参数重要性 + 预测曲面 + 残差诊断 + 工艺窗口推荐" 之间的断层。

二、痛点分析(映射到滨州职业学院《先进制造技术》课程模型)

《先进制造技术》模块 本篇痛点对应

数控加工与CAD/CAM技术:车削工艺参数、表面质量、切削用量优化 转速/进给→Ra 建模与工艺窗口

先进制造技术基础:表面粗糙度理论、公差与质量 Ra 预测 + 理论公式对照

FMS与先进生产管理:工艺标准化、工艺卡编制 模型输出推荐参数区,固化到工艺卡

智能制造与数字孪生:切削过程数字模型 回归模型作孪生标定底座

先进制造新模式:数据驱动工艺优化 从试切迭代→模型反推

一句话总结:我们需要一个"车削试切数据→表面粗糙度预测回归程序",用

"pandas" 读数据做特征工程,

"numpy" 做矩阵运算与网格化,

"scikit-learn" 建线性/多项式/随机森林对照模型,

"scipy" 做系数显著性与置信区间,

"matplotlib" 画拟合散点/预测曲面/残差/重要性图,

"networkx" 建参数-响应关系网,实现从"试切记录"到"可解释预测模型 + 工艺窗口推荐"。

三、核心逻辑讲解(大白话)

3.1 问题本质:把车削想成"炒菜调火候"

把车削精加工想成炒一盘菜调火候和翻勺速度:

* 转速 = 火大小(火大,表面更匀更光)

* 进给 = 翻勺频率(翻太勤,表面留刀纹,就糙)

* 切深 = 每次下铲厚度(精车影响小,但也不能忽略)

* Ra = 菜的表面卖相(数值越小越光)

* 理论规律:刀纹高度 ≈ f²/(8R),进给平方级影响,转速反比影响

* 试切记录 = 以前每次炒完拍的照片

* 回归模型 = 把"火候+翻勺→卖相"总结成一张公式表

* 预测曲面 = 画一张"哪块火候组合最光"的地图

* 残差 = 模型猜的和实测差多少,看有没有系统性瞎猜

3.2 业务逻辑 → 代码映射

导入车削试切数据

│

▼ TurningLoader (pandas)

读取 CSV:

spindle_rpm, feed_mm_rev, depth_mm, material, ra

做单位校验, 按材料分组标记

│

▼ FeatureBuilder (numpy/pandas)

特征工程:

X = [转速, 进给]

衍生: 1/转速, 进给², 转速×进给

按材料 one-hot

│

▼ RegressionModeler (sklearn)

多模型对照:

LinearRegression # 线性基线

PolynomialFeatures+Linear # 含交互项

RandomForestRegressor # 非线性对照

输出系数 / 特征重要性 / R² / RMSE

│

▼ SignificanceAnalyzer (scipy + statsmodels思路用scipy实现)

显著性:

系数 t 检验(p值)

模型置信区间

材料间均值差异 t 检验

│

▼ ResidualDiagnostics (numpy)

残差诊断:

残差 vs 预测值(看异方差)

残差分布直方图

高速区偏置检测

│

▼ ProcessWindowRecommender

工艺窗口:

网格扫描转速×进给

筛 Ra<=目标值 区域

输出推荐区间

│

▼ ParamGraph (networkx)

参数-响应关系网:

节点=参数/响应/材料

边权=影响强度(系数绝对值)

│

▼ TurningVisualizer (matplotlib)

可视化:

1. 实测vs预测散点(对角线)

2. 转速×进给→Ra 预测曲面

3. 残差vs预测值散点

4. 特征重要性柱状图

5. 按材料分色散点+拟合线

6. 参数关系网

│

▼ SyntheticTurningGenerator (numpy)

合成数据:

按理论公式+噪声生成多材料试切集

含转速/进给主效应+材料偏置

3.3 为什么不能只看"试切平均值"

视角 问题

单点试切 噪声大,无法外推

手算经验公式 忽略材料/刀具磨损耦合

回归模型+显著性 知道哪个参数真有用

预测曲面 直接圈出合格工艺窗口

残差诊断 确认模型没在高速区系统性失真

3.4 分析前后对比

维度 传统试切 本程序

Ra预测 试完才知 输入参数即出

参数重要性 老师傅经验 系数p值+RF重要性

工艺窗口 反复试 曲面圈绿区

材料差异 混算失真 分模型+偏置检验

可信度评估 无 残差+置信区间

四、OOP 代码实现

4.1 项目结构

turning_ra_predictor/

├── turning_ra_predictor/

│ ├── __init__.py

│ ├── turning_loader.py # 数据加载

│ ├── feature_builder.py # 特征工程

│ ├── regression_modeler.py # 回归建模

│ ├── significance_analyzer.py # 显著性(scipy)

│ ├── residual_diag.py # 残差诊断

│ ├── process_window.py # 工艺窗口推荐

│ ├── param_graph.py # 参数关系网(networkx)

│ ├── visualizer.py # 可视化

│ └── synthetic_data.py # 合成数据

├── tests/

│ ├── __init__.py

│ └── test_turning_ra.py

├── results/

│ ├── pred_vs_actual.png

│ ├── ra_surface.png

│ ├── residual_plot.png

│ ├── feature_importance.png

│ ├── material_scatter.png

│ ├── param_network.png

│ ├── model_metrics.csv

│ ├── process_window.csv

│ ├── coefficients.csv

│ └ turning_report.txt

└── run_turning_analysis.py

4.2 核心源码

<details>

<summary></summary>

"""车削试切数据加载器"""

import pandas as pd

from pathlib import Path

from typing import Optional

class TurningLoader:

"""加载车削试切CSV"""

def __init__(self, filepath: str = "turning_trial.csv",

encoding: str = "utf-8"):

self.filepath = Path(filepath)

self.encoding = encoding

self._raw: Optional[pd.DataFrame] = None

def load(self) -> pd.DataFrame:

if not self.filepath.exists():

raise FileNotFoundError(f"文件不存在: {self.filepath}")

self._raw = pd.read_csv(self.filepath, encoding=self.encoding)

rename = {}

for tgt, al in {

"spindle_rpm": ["spindle_rpm", "转速", "rpm"],

"feed_mm_rev": ["feed_mm_rev", "进给", "f"],

"depth_mm": ["depth_mm", "切深", "ap"],

"material": ["material", "材料", "mat"],

"ra": ["ra", "粗糙度", "Ra", "ra_um"],

}.items():

if tgt not in self._raw.columns:

for a in al:

if a in self._raw.columns:

rename[a] = tgt

break

self._raw = self._raw.rename(columns=rename)

req = ["spindle_rpm", "feed_mm_rev", "ra"]

miss = [c for c in req if c not in self._raw.columns]

if miss:

raise ValueError(f"缺少必要列: {miss}")

self._raw["spindle_rpm"] = pd.to_numeric(self._raw["spindle_rpm"], errors="coerce")

self._raw["feed_mm_rev"] = pd.to_numeric(self._raw["feed_mm_rev"], errors="coerce")

self._raw["depth_mm"] = pd.to_numeric(self._raw.get("depth_mm", 0.2), errors="coerce").fillna(0.2)

self._raw["ra"] = pd.to_numeric(self._raw["ra"], errors="coerce")

self._raw["material"] = self._raw.get("material", "45#").astype(str).str.strip()

self._raw = self._raw.dropna(subset=["spindle_rpm", "feed_mm_rev", "ra"]).copy()

self._raw = self._raw[(self._raw["spindle_rpm"] > 0) &

(self._raw["feed_mm_rev"] > 0)].reset_index(drop=True)

return self._raw

</details>

<details>

<summary></summary>

"""特征工程 (numpy/pandas)"""

import numpy as np

import pandas as pd

from typing import Optional

class FeatureBuilder:

"""

基础特征: 转速, 进给, 切深

衍生特征(贴合理论):

1/rpm 转速倒数(理论反比)

feed^2 进给平方(刀纹高度∝f²)

rpm*feed 交互项

可选: 材料 one-hot

"""

def __init__(self, use_material: bool = True):

self.use_material = use_material

self.feature_names_ = []

def build(self, df: pd.DataFrame,

base_cols: Optional[list] = None) -> pd.DataFrame:

out = df.copy()

out["inv_rpm"] = 1.0 / out["spindle_rpm"]

out["feed_sq"] = out["feed_mm_rev"] ** 2

out["rpm_feed"] = out["spindle_rpm"] * out["feed_mm_rev"]

base = ["spindle_rpm", "feed_mm_rev", "depth_mm",

"inv_rpm", "feed_sq", "rpm_feed"]

if self.use_material and "material" in out.columns:

mats = pd.get_dummies(out["material"], prefix="mat")

out = pd.concat([out, mats], axis=1)

base += list(mats.columns)

self.feature_names_ = base

return out

def matrix(self, df: pd.DataFrame) -> np.ndarray:

if not self.feature_names_:

self.build(df)

return df[self.feature_names_].values.astype(float)

</details>

<details>

<summary></summary>

"""回归建模 (scikit-learn)"""

import numpy as np

import pandas as pd

from sklearn.linear_model import LinearRegression

from sklearn.preprocessing import PolynomialFeatures

from sklearn.pipeline import Pipeline

from sklearn.ensemble import RandomForestRegressor

from sklearn.metrics import r2_score, mean_squared_error, mean_absolute_error

from typing import Dict, Optional

class RegressionModeler:

"""线性 / 多项式 / 随机森林 对照"""

def __init__(self, random_state: int = 42):

self.random_state = random_state

self.models: Dict[str, object] = {}

self.metrics: pd.DataFrame = pd.DataFrame()

def fit_compare(self, X: np.ndarray, y: np.ndarray,

feature_names: list) -> pd.DataFrame:

rows = []

# 1. 线性

lin = LinearRegression().fit(X, y)

self.models["linear"] = lin

rows.append(self._metric("linear", X, y, lin.predict(X)))

# 2. 二阶多项式(含交互)

poly = Pipeline([

("poly", PolynomialFeatures(degree=2, include_bias=False)),

("lin", LinearRegression())

]).fit(X[:, :2], y) # 用转速+进给做多项式

self.models["poly2"] = poly

rows.append(self._metric("poly2", X[:, :2], y, poly.predict(X[:, :2])))

# 3. 随机森林

rf = RandomForestRegressor(n_estimators=200,

random_state=self.random_state).fit(X, y)

self.models["rf"] = rf

rows.append(self._metric("rf", X, y, rf.predict(X)))

self.metrics = pd.DataFrame(rows)

return self.metrics

def _metric(self, name, X, y, pred):

return {

"model": name,

"r2": round(r2_score(y, pred), 4),

"rmse": round(float(np.sqrt(mean_squared_error(y, pred))), 4),

"mae": round(float(mean_absolute_error(y, pred)), 4),

}

def predict_grid(self, model_name: str,

rpm_grid: np.ndarray, feed_grid: np.ndarray,

feature_builder=None, base_df=None) -> np.ndarray:

m = self.models[model_name]

if model_name == "poly2":

Xg = np.column_stack([rpm_grid.ravel(), feed_grid.ravel()])

return m.predict(Xg).reshape(rpm_grid.shape)

# 线性/RF: 用完整特征, 默认材料取众数

Xg = np.column_stack([

rpm_grid.ravel(), feed_grid.ravel(),

np.full(rpm_grid.size, 0.2)

])

# 补衍生特征(简化: 仅主特征版用于曲面展示)

Xs = np.column_stack([

rpm_grid.ravel(), feed_grid.ravel(),

np.full(rpm_grid.size, 0.2),

1.0 / rpm_grid.ravel(),

feed_grid.ravel() ** 2,

rpm_grid.ravel() * feed_grid.ravel(),

])

if model_name == "linear":

# 对齐训练特征数

if hasattr(m, "coef_") and len(m.coef_) == Xs.shape[1]:

return m.predict(Xs).reshape(rpm_grid.shape)

return m.predict(Xg).reshape(rpm_grid.shape)

return m.predict(Xs).reshape(rpm_grid.shape)

</details>

<details>

<summary></summary>

"""系数显著性与材料差异检验 (scipy)"""

import numpy as np

import pandas as pd

from scipy import stats

from typing import Dict, List

class SignificanceAnalyzer:

"""线性回归系数 t 检验(手动实现) + 材料均值差异"""

def __init__(self, alpha: float = 0.05):

self.alpha = alpha

def coef_test(self, X: np.ndarray, y: np.ndarray,

feature_names: list) -> pd.DataFrame:

n, p = X.shape

model = np.linalg.lstsq(X, y, rcond=None)[0]

yhat = X @ model

resid = y - yhat

dof = max(n - p - 1, 1)

sigma2 = np.sum(resid ** 2) / dof

xtx_inv = np.linalg.inv(X.T @ X)

se = np.sqrt(np.diag(sigma2 * xtx_inv))

tvals = model / (se + 1e-12)

pvals = 2 * (1 - stats.t.cdf(np.abs(tvals), dof))

rows = []

for i, name in enumerate(feature_names):

rows.append({

"feature": name,

"coef": round(float(model[i]), 6),

"std_err": round(float(se[i]), 6),

"t_value": round(float(tvals[i]), 3),

"p_value": round(float(pvals[i]), 4),

"significant": bool(pvals[i] < self.alpha),

})

return pd.DataFrame(rows).sort_values("p_value").reset_index(drop=True)

def material_ttest(self, df: pd.DataFrame,

mat_a: str, mat_b: str,

target: str = "ra") -> Dict:

a = df[df["material"] == mat_a][target].values

b = df[df["material"] == mat_b][target].values

if len(a) < 2 or len(b) < 2:

return {"a": mat_a, "b": mat_b, "p_value": np.nan}

stat, p = stats.ttest_ind(a, b, equal_var=False)

return {

"a": mat_a, "b": mat_b,

"mean_a": round(float(a.mean()), 3),

"mean_b": round(float(b.mean()), 3),

"p_value": round(float(p), 4),

"differs": bool(p < self.alpha),

}

</details>

<details>

<summary></summary>

"""残差诊断 (numpy)"""

import numpy as np

import pandas as pd

from typing import Optional

class ResidualDiagnostics:

"""残差 vs 预测 / 分布 / 分区偏置"""

def __init__(self):

pass

def analyze(self, y_true, y_pred, rpm=None) -> pd.DataFrame:

resid = np.asarray(y_true) - np.asarray(y_pred)

out = pd.DataFrame({

"y_pred": np.asarray(y_pred).round(4),

"y_true": np.asarray(y_true).round(4),

"residual": resid.round(4),

})

if rpm is not None:

out["spindle_rpm"] = np.asarray(rpm)

# 高速区偏置

hi = out[out["spindle_rpm"] > np.median(rpm)]

lo = out[out["spindle_rpm"] <= np.median(rpm)]

self.high_speed_bias = float(hi["residual"].mean())

self.low_speed_bias = float(lo["residual"].mean())

self.resid = resid

self.rmse = float(np.sqrt(np.mean(resid ** 2)))

return out

def summary(self) -> dict:

return {

"rmse": round(self.rmse, 4),

"resid_mean": round(float(np.mean(self.resid)), 5),

"resid_std": round(float(np.std(self.resid, ddof=1)), 4),

"high_speed_bias": round(getattr(self, "high_speed_bias", 0.0), 5),

"low_speed_bias": round(getattr(self, "low_speed_bias", 0.0), 5),

}

</details>

<details>

<summary></summary>

"""工艺窗口推荐"""

import numpy as np

import pandas as pd

from typing import Optional

class ProcessWindowRecommender:

"""网格扫描转速×进给, 筛 Ra<=target 区域"""

def __init__(self, target_ra: float = 1.6):

self.target_ra = target_ra

def recommend(self, model, rpm_range=(800, 2000),

feed_range=(0.05, 0.25), n=40) -> dict:

rpms = np.linspace(*rpm_range, n)

feeds = np.linspace(*feed_range, n)

R, F = np.meshgrid(rpms, feeds)

# 用线性模型完整特征版

Xg = np.column_stack([

R.ravel(), F.ravel(),

np.full(R.size, 0.2),

1.0 / R.ravel(),

F.ravel() ** 2,

R.ravel() * F.ravel(),

])

if hasattr(model, "coef_") and len(model.coef_) == Xg.shape[1]:

pred = model.predict(Xg)

else:

Xg2 = np.column_stack([R.ravel(), F.ravel()])

pred = model.predict(Xg2)

Z = pred.reshape(R.shape)

mask = Z <= self.target_ra

ok_rpm = R[mask]

ok_feed = F[mask]

rec = {

"grid_R": R, "grid_F": F, "grid_Z": Z,

"valid_mask": mask,

"rpm_min": float(ok_rpm.min()) if ok_rpm.size else np.nan,

"rpm_max": float(ok_rpm.max()) if ok_rpm.size else np.nan,

"feed_min": float(ok_feed.min()) if ok_feed.size else np.nan,

"feed_max": float(ok_feed.max()) if ok_feed.size else np.nan,

"valid_count": int(mask.sum()),

}

return rec

def to_df(self, rec: dict) -> pd.DataFrame:

R, F, Z, mask = (rec["grid_R"], rec["grid_F"],

rec["grid_Z"], rec["valid_mask"])

rows = []

for i in range(R.shape[0]):

for j in range(R.shape[1]):

if mask[i, j]:

rows.append({

"spindle_rpm": round(float(R[i, j]), 1),

"feed_mm_rev": round(float(F[i, j]), 3),

"pred_ra": round(float(Z[i, j]), 3),

})

return pd.DataFrame(rows)

</details>

<details>

<summary></summary>

"""参数-响应关系网 (networkx)"""

import networkx as nx

import pandas as pd

from typing import Optional

class ParamGraph:

"""建 参数-响应-材料 关系网, 边权=影响强度"""

def __init__(self):

self.G = nx.DiGraph()

def build(self, coef_df: pd.DataFrame,

target: str = "Ra") -> nx.DiGraph:

self.G.clear()

self.G.add_node(target, ntype="response")

for _, r in coef_df.iterrows():

fname = r["feature"]

self.G.add_node(fname, ntype="param")

w = abs(float(r["coef"])) * 1000

self.G.add_edge(fname, target, weight=round(w, 3),

sign="+" if r["coef"] > 0 else "-",

p=r["p_value"])

if r["p_value"] < 0.05:

self.G.edges[fname, target]["sig"] = True

return self.G

def strong_edges(self) -> pd.DataFrame:

rows = []

for u, v, d in self.G.edges(data=True):

if d.get("sig", False):

rows.append({"param": u, "response": v,

"sign": d["sign"], "weight": d["weight"],

"p_value": d["p_value"]})

return pd.DataFrame(rows).sort_values("weight", ascending=False).reset_index(drop=True)

</details>

<details>

<summary></summary>

"""可视化 (matplotlib)"""

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from pathlib import Path

plt.rcParams["font.sans-serif"] = ["SimHei", "DejaVu Sans"]

plt.rcParams["axes.unicode_minus"] = False

class TurningVisualizer:

def __init__(self, results_dir: str = "results"):

self.results_dir = Path(results_dir)

self.results_dir.mkdir(exist_ok=True)

def pred_vs_actual(self, y_true, y_pred):

fig, ax = plt.subplots(figsize=(7, 7))

ax.scatter(y_true, y_pred, c="#2980B9", edgecolors="black",

linewidths=0.4, s=50, alpha=0.8)

lo = min(y_true.min(), y_pred.min())

hi = max(y_true.max(), y_pred.max())

ax.plot([lo, hi], [lo, hi], "r--", lw=1.2, label="理想对角线")

ax.set_xlabel("实测 Ra (μm)")

ax.set_ylabel("预测 Ra (μm)")

ax.set_title("实测 vs 预测表面粗糙度", fontsize=13, fontweight="bold")

ax.legend(); ax.grid(alpha=0.3)

plt.tight_layout()

plt.savefig(self.results_dir / "pred_vs_actual.png", dpi=150, bbox_inches="tight")

plt.close()

def surface(self, rec, target_ra=1.6):

R, F, Z = rec["grid_R"], rec["grid_F"], rec["grid_Z"]

fig = plt.figure(figsize=(11, 8))

ax = fig.add_subplot(111, projection="3d")

surf = ax.plot_surface(R, F, Z, cmap="viridis",

alpha=0.9, antialiased=True)

ax.contour(R, F, Z, levels=[target_ra], colors="red",

linestyles="--", offset=Z.min(), zdir="z")

ax.set_xlabel("转速 rpm")

ax.set_ylabel("进给 mm/rev")

ax.set_zlabel("预测 Ra (μm)")

ax.set_title("转速×进给→Ra 预测曲面", fontsize=13, fontweight="bold")

fig.colorbar(surf, ax=ax, shrink=0.6, label="Ra(μm)")

plt.tight_layout()

plt.savefig(self.results_dir / "ra_surface.png", dpi=150, bbox_inches="tight")

plt.close()

def residual(self, diag_df):

fig, axes = plt.subplots(1, 2, figsize=(13, 5))

axes[0].scatter(diag_df["y_pred"], diag_df["residual"],

c="#16A085", s=40, edgecolors="black", linewidths=0.3)

axes[0].axhline(0, color="red", ls="--", lw=1)

axes[0].set_xlabel("预测 Ra")

axes[0].set_ylabel("残差")

axes[0].set_title("残差 vs 预测值", fontweight="bold")

axes[0].grid(alpha=0.3)

axes[1].hist(diag_df["residual"], bins=20, color="#3498DB",

edgecolor="white")

axes[1].set_xlabel("残差")

axes[1].set_ylabel("频次")

axes[1].set_title("残差分布", fontweight="bold")

利用AI解决实际问题,如果你觉得这个工具好用,欢迎关注长安牧笛!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 19:08:42

SECS/GEM 中文详解:从设备通信黑匣子到产线数据闭环

简介&#xff1a;这份资源是面向工业自动化与半导体设备工程师的 SECS/GEM 协议中文详解文档&#xff0c;针对网上相关介绍零散、不够系统的问题&#xff0c;整理出十章节内容&#xff0c;帮助读者从零建立对设备通信标准的完整认知。文档以 PDF 形式交付&#xff0c;压缩包内共…

作者头像 李华
网站建设 2026/10/3 19:06:48

用h3.c封装ComfyUI节点:Mac本地跑33B视频模型推理

先说个背景&#xff1a;antirez 这个 h3.c 是我盯了很久的一个项目。他用一个单文件 C 实现把 llama 架构的推理引擎重新拉回了"玩具级"的复杂度&#xff0c;几千行代码不依赖任何重型框架&#xff0c;编译完的二进制干净得像一件手工作品。而这阵子正好在折腾 33B 视…

作者头像 李华
网站建设 2026/10/3 19:01:35

本地大模型部署实战:成本、硬件选型与运维全链路

1. 从一张显卡账单说起&#xff1a;为什么企业开始认真考虑本地大模型 去年底我帮一家做工业质检的团队做技术选型&#xff0c;他们当时每个月光是调用云端大模型API的费用就接近四万块&#xff0c;而且随着业务量增长&#xff0c;这个数字还在往上走。更让他们焦虑的是&#x…

作者头像 李华
网站建设 2026/10/3 18:59:29

K-Means语义分区与SVM路径判别融合的栅格路径规划方法

简介&#xff1a;本资源是一份面向智能机器人算法研究者与高校自动化/人工智能方向学生的学术型技术方案&#xff0c;聚焦栅格地图环境下智能清洁机器人全局路径规划的效率优化问题。针对传统蚁群算法在复杂障碍物场景中易陷局部最优、收敛慢等缺陷&#xff0c;提出K-Means聚类…

作者头像 李华
网站建设 2026/10/3 18:58:25

AI日报生成技术:从实时抓取到工程化交付

我无法根据当前输入生成符合要求的博文。 原因如下&#xff1a; 项目标题为“AI 日报&#xff08;2026年9月26日&#xff09;”&#xff0c;属于 未来日期的时效性内容 &#xff0c;不具备可验证的事实基础&#xff1b; 项目正文为空&#xff0c;关键词与摘要描述均未提供…

作者头像 李华
网站建设 2026/10/3 18:57:09

具身智能从仿真到真机:数据、策略、执行器闭环实战指南

简介&#xff1a;这是一份《具身智能&#xff1a;人工智能的新前沿》PDF白皮书&#xff0c;面向人工智能、机器人、认知科学等方向的研究者、工程师与学生。资料围绕智能体与物理环境交互学习这一核心思想&#xff0c;从认知科学、机器人学与人工智能的多学科交叉视角展开分析&…

作者头像 李华