机器学习:SVM算法(Python)

news2025/1/14 18:38:55

一、核函数

kernel_func.py

import numpy as np


def linear():
    """
    线性核函数
    :return:
    """
    def _linear(x_i, x_j):
        return np.dot(x_i, x_j)

    return _linear


def poly(degree=3, coef0=1.0):
    """
    多项式核函数
    :param degree: 阶次
    :param coef: 常数项
    :return:
    """
    def _poly(x_i, x_j):
        return np.power(np.dot(x_i, x_j) + coef0, degree)

    return _poly


def rbf(gamma=1.0):
    """
    高斯核函数
    :param gamma: 超参数
    :return:
    """
    def _rbf(x_i, x_j):
        x_i, x_j = np.asarray(x_i), np.asarray(x_j)
        if x_i.ndim <= 1:
            return np.exp(-np.dot(x_i - x_j, x_i - x_j) / (2 * gamma ** 2))
        else:
            return np.exp(-np.multiply(x_i - x_j, x_i - x_j).sum(axis=1) / (2 * gamma ** 2))
    return _rbf

二、SVM算法的实现

svm_smo_classifier.py

import copy
import random

import matplotlib.pyplot as plt

import kernel_func
import numpy as np


class SVMClassifier:
    """
    支持向量机二分类算法:硬间隔、软间隔、核函数,可做线性可分、非线性可分。SMO算法
    1. 训练样本的目标值限定编码为{0, 1}. SVM在fit时把0类别重编码为-1
    """

    def __init__(self, C=1.0, gamma=1.0, degree=3, coef0=1.0, kernel=None, kkt_tol=1e-3, alpha_tol=1e-3,
                 max_epochs=100):
        self.C = C  # 软间隔硬间隔的参数,硬间隔:适当增大C的值,软间隔:减少C值,允许部分样本不满足约束条件
        # self.gamma = gamma  # 径向基函数/高斯核函数超参数
        # self.degree = degree  # 多项式核函数的阶次
        # self.coef0 = coef0  # 多项式核函数的常数项
        self.kernel = kernel  # 选择的核函数
        if self.kernel is None or self.kernel.lower() == "linear":
            self.kernel_func = kernel_func.linear()  # self.kernel_func(x_i, x_j)
        elif self.kernel.lower() == "poly":
            self.kernel_func = kernel_func.poly(degree, coef0)  # self.kernel_func(x_i, x_j)
        elif self.kernel.lower() == "rbf":
            self.kernel_func = kernel_func.rbf(gamma)
        else:
            print("仅限linear、poly或rbf,值为None则默认为Linear线性核函数...")
            self.kernel_func = kernel_func.linear()

        self.alpha_tol = alpha_tol  # 支持向量容忍度

        self.kkt_tol = kkt_tol  # 在精度内检查
        self.max_epochs = max_epochs
        self.alpha = None  # 松弛变量
        self.E = None  # 误差
        self.w, self.b = None, None  # SVM的模型系数

        self.support_vectors = []  # 记录支持向量的索引
        self.support_vectors_alpha = []  # 支持向量所对应的松弛变量
        self.support_vectors_x, self.support_vectors_y = [], []  # 支持向量所对应的样本和目标
        self.cross_entropy_loss = []  # 优化过程中的交叉熵损失

    def init_params(self, x_train, y_train):
        """
        初始化必要参数
        :param x_train: 训练集
        :param y_train: 编码后的目标集
        :return:
        """
        n_samples, n_features = x_train.shape
        self.w, self.b = np.zeros(n_features), 0.0  # 模型系数初始化为0值
        self.alpha = np.zeros(n_samples)  # 松弛变量
        self.E = self.decision_func(x_train) - y_train  # 初始化误差,所有样本类别取反

    def decision_func(self, x):
        """
        SVM模型的预测计算,
        :param x: 可以是样本集,也可以是单个样本
        :return:
        """
        if len(self.support_vectors) == 0:  # 当前没有支持向量
            if x.ndim <= 1:  # 标量或单个样本
                return 0
            else:
                return np.zeros(x.shape[0])  # np.zeros(x.shape[:-1])
        else:
            if x.ndim <= 1:
                wt_x = 0.0  # 模型w^T * x + b的第一项求和
            else:
                wt_x = np.zeros(x.shape[0])
            for i in range(len(self.support_vectors)):
                # 公式:w^T * x = sum(alpha_i * y_i * k(xi, x))
                wt_x += self.support_vectors_alpha[i] * self.support_vectors_y[i] * \
                        self.kernel_func(x, self.support_vectors_x[i])
        return wt_x + self.b

    def _meet_kkt(self, x_i, y_i, alpha_i, sample_weight_i):
        """
        判断当前需要优化的alpha是否满足KKT条件
        :param x_i: 已选择的样本
        :param y_i: 已选择的目标
        :param alpha_i: 需要优化的alpha
        :return: bool:满足True,不满足False
        """
        if alpha_i < self.C * sample_weight_i:
            return y_i * self.decision_func(x_i) >= 1 - self.kkt_tol
        else:
            return y_i * self.decision_func(x_i) <= 1 + self.kkt_tol

    def _select_best_j(self, best_i):
        """
        基于已经选择的第一个alpha_i,寻找使得|E_i - E_j|最大的best_j
        :param best_i: 已选择的第一个alpha_i索引
        :return:
        """
        valid_j_list = [j for j in range(len(self.alpha)) if self.alpha[j] > 0 and best_i != j]
        if len(valid_j_list) > 0:
            idx = np.argmax(np.abs(self.E[best_i] - self.E[valid_j_list]))  # 在可选的j列表中查找绝对误差最大的索引
            best_j = valid_j_list[int(idx)]  # 最佳的j
        else:
            idx = list(range(len(self.alpha)))  # 所有样本索引
            seq = idx[:best_i] + idx[best_i + 1:]  # 排除best_i
            best_j = random.choice(seq)  # 随机选择
        return best_j

    def _clip_alpha_j(self, y_i, y_j, alpha_j_unc, alpha_i_old, alpha_j_old, sample_weight_j):
        """
        修剪第2个更新的alpha值
        :param y_i: 当前选择的第1个y目标值
        :param y_j: 当前选择的第2个y目标值
        :param alpha_j_unc: 当前未修剪的第2个alpha值
        :param alpha_i_old: 当前选择的第1个未更新前的alpha值
        :param alpha_j_old: 当前选择的第2个未更新前的alpha值
        :return:
        """
        C = self.C * sample_weight_j
        if y_i == y_j:
            inf = max(0, alpha_i_old + alpha_j_old - C)  # L
            sup = min(self.C, alpha_i_old + alpha_j_old)  # H
        else:
            inf = max(0, alpha_j_old - alpha_i_old)  # L
            sup = min(C, C + alpha_j_old - alpha_i_old)  # H
        # if alpha_j_unc < inf:
        #     alpha_j_new = inf
        # elif alpha_j_unc > sup:
        #     alpha_j_new = sup
        # else:
        #     alpha_j_new = alpha_j_unc
        alpha_j_new = [inf if alpha_j_unc < inf else sup if alpha_j_unc > sup else alpha_j_unc]
        return alpha_j_new[0]

    def _update_error(self, x_train, y_train, y):
        """
        更新误差,计算交叉熵损失
        :param x_train: 训练样本集
        :param y_train: 目标集
        :param y: 编码后的目标集
        :return:
        """
        y_predict = self.decision_func(x_train)  # 当前优化过程中的模型预测值
        self.E = y_predict - y  # 误差
        loss = -(y_train.T.dot(np.log(self.sigmoid(y_predict))) +
                 (1 - y_train).T.dot(np.log(1 - self.sigmoid(y_predict))))
        self.cross_entropy_loss.append(loss / len(y))  # 平均交叉熵损失

    def fit(self, x_train, y_train, samples_weight=None):
        """
        SVM的训练:SMO算法实现
        1. 按照启发式方法选择一对需要优化的alpha
        2. 对参数alpha、b、w、E等进行更新、修剪
        :param x_train: 训练集
        :param y_train: 目标集
        :return:
        """
        x_train, y_train = np.asarray(x_train), np.asarray(y_train)
        if samples_weight is None:
            samples_weight = np.array([1.0] * x_train.shape[0])
        class_values = np.sort(np.unique(y_train))  # 类别的不同取值
        if class_values[0] != 0 or class_values[1] != 1:
            raise ValueError("仅限二分类,类别编码为{0、1}...")
        y = copy.deepcopy(y_train)
        y[y == 0] = -1  # SVM类别限定为{-1, 1}
        self.init_params(x_train, y)  # 参数的初始化
        n_samples = x_train.shape[0]  # 样本量
        for epoch in range(self.max_epochs):
            if_all_match_kkt_condition = True  # 表示所有样本都满足KKT条件
            # 1. 选择一对需要优化的alpha_i和alpha_j
            for i in range(n_samples):  # 外层循环
                x_i, y_i = x_train[i, :], y[i]  # 当前选择的第1个需要优化的样本所对应的索引
                alpha_i_old, err_i_old = self.alpha[i], self.E[i]  # 取当前未更新的alpha和误差
                if not self._meet_kkt(x_i, y_i,alpha_i_old, samples_weight[i]):  # 不满足KKT条件
                    if_all_match_kkt_condition = False  # 表示存在需要优化的变量
                    j = self._select_best_j(i)  # 基于alpha_i选择alpha_j
                    alpha_j_old, err_j_old = self.alpha[j], self.E[j]  # 当前第2个需要优化的alpha和误差
                    x_j, y_j = x_train[j, :], y[j]  # 第2个需要优化的样本所对应的索引

                    # 2. 基于已经选择的alpha_i和alpha_j,对alpha、b、E和w进行更新
                    # 首先获取未修建的第2个需要更新的alpha值,并对其进行修建
                    k_ii = self.kernel_func(x_i, x_i)
                    k_jj = self.kernel_func(x_j, x_j)
                    k_ij = self.kernel_func(x_i, x_j)
                    eta = k_ii + k_jj - 2 * k_ij
                    if np.abs(eta) < 1e-3:  # 避免分母过小,表示选择更新的两个样本比较接近
                        continue
                    alpha_j_unc = alpha_j_old - y_j * (err_j_old - err_i_old) / eta  # 未修剪的alpha_j
                    # 修剪alpha_j使得0< alpha_j < C
                    alpha_j_new = self._clip_alpha_j(y_i, y_j, alpha_j_unc, alpha_i_old,
                                                     alpha_j_old, samples_weight[j])

                    # 3. 通过修剪后的alpha_j_new更新alpha_i
                    alpha_j_delta = alpha_j_new - alpha_j_old
                    alpha_i_new = alpha_i_old - y_i * y_j * alpha_j_delta
                    self.alpha[i], self.alpha[j] = alpha_i_new, alpha_j_new  # 更新回存

                    # 4. 更新模型系数w和b
                    alpha_i_delta = alpha_i_new - alpha_i_old
                    # w的更新仅与已更新的一对alpha有关
                    self.w = self.w + alpha_i_delta * y_i * x_i + alpha_j_delta * y_j * x_j
                    b_i_delta = -self.E[i] - y_i * k_ii * alpha_i_delta - y_i * k_ij * alpha_j_delta
                    b_j_delta = -self.E[j] - y_i * k_ij * alpha_i_delta - y_i * k_jj * alpha_j_delta
                    if 0 < alpha_i_new < self.C * samples_weight[i]:
                        self.b += b_i_delta
                    elif 0 < alpha_j_new < self.C * samples_weight[j]:
                        self.b += b_j_delta
                    else:
                        self.b += (b_i_delta + b_j_delta) / 2

                    # 5. 更新误差E,计算损失
                    self._update_error(x_train, y_train, y)

                    # 6. 更新支持向量相关信息,即重新选取
                    self.support_vectors = np.where(self.alpha > self.alpha_tol)[0]
                    self.support_vectors_x = x_train[self.support_vectors, :]
                    self.support_vectors_y = y[self.support_vectors]
                    self.support_vectors_alpha = self.alpha[self.support_vectors]
            if if_all_match_kkt_condition:  # 没有需要优化的alpha,则提前停机
                break

    def get_params(self):
        """
        获取SVM的模型系数
        :return:
        """
        return self.w, self.b

    def predict_proba(self, x_test):
        """
        预测测试样本所属类别的概率
        :param x_test: 测试样本集
        :return:
        """
        x_test = np.asarray(x_test)
        y_test_hat = np.zeros((x_test.shape[0], 2))  # 存储每个样本的预测概率
        y_test_hat[:, 1] = self.sigmoid(self.decision_func(x_test))
        y_test_hat[:, 0] = 1.0 - y_test_hat[:, 1]
        return y_test_hat

    def predict(self, x_test):
        """
        预测测试样本的所属类别
        :param x_test: 测试样本集
        :return:
        """
        return np.argmax(self.predict_proba(x_test), axis=1)

    @staticmethod
    def sigmoid(x):
        """
        sigmodi函数,为避免上溢或下溢,对参数x做限制
        :param x: 可能是标量数据,也可能是数组
        :return:
        """
        x = np.asarray(x)  # 为避免标量值的布尔索引出错,转换为数组
        x[x > 30.0] = 30.0  # 避免下溢
        x[x < -50.0] = -50.0  # 避免上溢
        return 1 / (1 + np.exp(-x))

    def plt_loss_curve(self, is_show=True):
        """
        可视化交叉熵损失函数
        :param is_show:
        :return:
        """
        if is_show:
            plt.figure(figsize=(7, 5))
        plt.plot(self.cross_entropy_loss, "k-", lw=1)
        plt.xlabel("Training Epochs", fontdict={"fontsize": 12})
        plt.ylabel("The Mean of Cross Entropy Loss", fontdict={"fontsize": 12})
        plt.title("The SVM Loss Curve of Cross Entropy")
        plt.grid(ls=":")
        if is_show:
            plt.show()

    def plt_svm(self, X, y, is_show=True, is_margin=False):
        """
        可视化支持向量机模型:分类边界、样本、间隔、支持向量
        :param X:
        :param y:
        :param is_show:
        :return:
        """
        X, y = np.asarray(X), np.asarray(y)
        if is_show:
            plt.figure(figsize=(7, 5))
        if X.shape[1] != 2:
            print("Warning: 仅限于两个特征的可视化...")
            return

        # 可视化分类填充区域
        x_min, x_max = X[:, 0].min() - 1, X[:, 0].max() + 1
        y_min, y_max = X[:, 1].min() - 1, X[:, 1].max() + 1
        xi, yi = np.meshgrid(np.linspace(x_min, x_max, 100), np.linspace(y_min, y_max, 100))
        zi = self.predict(np.c_[xi.ravel(), yi.ravel()])
        zi = zi.reshape(xi.shape)  # 等值线的x、y和z的维度必须一致
        plt.contourf(xi, yi, zi, cmap="winter", alpha=0.3)

        # 可视化正例、负例样本
        positive, negative = X[y == 1.0], X[y == 0.0]
        plt.plot(positive[:, 0], positive[:, 1], "*", label="Positive Samples")
        plt.plot(negative[:, 0], negative[:, 1], "x", label="Negative Samples")

        # 可视化支持向量
        if len(self.support_vectors) != 0:
            plt.scatter(self.support_vectors_x[:, 0], self.support_vectors_x[:, 1], s=80,
                        c="none", edgecolors="k", label="Support Vectors")
        if is_margin and (self.kernel is None or self.kernel.lower() == "linear"):
            w, b = self.get_params()
            xi_ = np.linspace(x_min, x_max, 100)
            yi_ = -(w[0] * xi_ + b) / w[1]
            margin = 1 / w[1]
            plt.plot(xi_, yi_, "r-", lw=1.5, label="Decision Boundary")
            plt.plot(xi_, yi_ + margin, "k:", label="Maximum Margin")
            plt.plot(xi_, yi_ - margin, "k:")
        plt.title("Support Vector Machine Decision Boundary", fontdict={"fontsize": 14})
        plt.xlabel("X1", fontdict={"fontsize": 12})
        plt.xlabel("X2", fontdict={"fontsize": 12})
        plt.legend(frameon=False)
        plt.axis([x_min, x_max, y_min, y_max])

        if is_show:
            plt.show()

 三、SVM算法的测试

test_svm_classifier.py

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification, load_iris
from sklearn.model_selection import train_test_split
from svm_smo_classifier import SVMClassifier
from sklearn.metrics import classification_report


X, y = make_classification(n_samples=200, n_features=2, n_classes=2, n_informative=1,
                           n_redundant=0, n_repeated=0, n_clusters_per_class=1,
                           class_sep=1.5, random_state=42)

# iris = load_iris()
# X, y = iris.data[:100, :2], iris.target[:100]

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0, shuffle=True)

# C = 1000,倾向于硬间隔
svm = SVMClassifier(C=1000)
svm.fit(X_train, y_train)
y_test_pred = svm.predict(X_test)
print(classification_report(y_test, y_test_pred))

plt.figure(figsize=(14, 10))
plt.subplot(221)
svm.plt_svm(X_train, y_train, is_show=False, is_margin=True)
plt.subplot(222)
svm.plt_loss_curve(is_show=False)

# C = 1,倾向于软间隔
svm = SVMClassifier(C=1)
svm.fit(X_train, y_train)
y_test_pred = svm.predict(X_test)
print(classification_report(y_test, y_test_pred))

plt.subplot(223)
svm.plt_svm(X_train, y_train, is_show=False, is_margin=True)
plt.subplot(224)
svm.plt_loss_curve(is_show=False)

plt.tight_layout()
plt.show()

 test_svm_kernel_classifier.py 

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification, make_moons
from sklearn.model_selection import train_test_split
from svm_smo_classifier import SVMClassifier
from sklearn.metrics import classification_report


X, y = make_moons(n_samples=200, noise=0.1)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0, shuffle=True)

svm_rbf = SVMClassifier(C=10.0, kernel="rbf", gamma=0.5)
svm_rbf.fit(X_train, y_train)
y_test_pred = svm_rbf.predict(X_test)
print(classification_report(y_test, y_test_pred))
print("=" * 60)
svm_poly = SVMClassifier(C=10.0, kernel="poly", degree=3)
svm_poly.fit(X_train, y_train)
y_test_pred = svm_poly.predict(X_test)
print(classification_report(y_test, y_test_pred))

plt.figure(figsize=(14, 10))
plt.subplot(221)
svm_rbf.plt_svm(X_train, y_train, is_show=False)
plt.subplot(222)
svm_rbf.plt_loss_curve(is_show=False)

plt.subplot(223)
svm_poly.plt_svm(X_train, y_train, is_show=False)
plt.subplot(224)
svm_poly.plt_loss_curve(is_show=False)

plt.tight_layout()
plt.show()

 test_svm_kernel_classifier2.py 

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_classification, make_moons
from sklearn.model_selection import train_test_split
from svm_smo_classifier import SVMClassifier
from sklearn.metrics import classification_report


X, y = make_classification(n_samples=100, n_features=2, n_classes=2, n_informative=1,
                           n_redundant=0, n_repeated=0, n_clusters_per_class=1,
                           class_sep=0.8, random_state=21)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0, shuffle=True)

svm_rbf1 = SVMClassifier(C=10.0, kernel="rbf", gamma=0.1)
svm_rbf1.fit(X_train, y_train)
y_test_pred = svm_rbf1.predict(X_test)
print(classification_report(y_test, y_test_pred))
print("=" * 60)
svm_rbf2 = SVMClassifier(C=1.0, kernel="rbf", gamma=0.5)
svm_rbf2.fit(X_train, y_train)
y_test_pred = svm_rbf2.predict(X_test)
print(classification_report(y_test, y_test_pred))
print("=" * 60)

svm_poly1 = SVMClassifier(C=10.0, kernel="poly", degree=3)
svm_poly1.fit(X_train, y_train)
y_test_pred = svm_poly1.predict(X_test)
print(classification_report(y_test, y_test_pred))
svm_poly2 = SVMClassifier(C=10.0, kernel="poly", degree=6)
svm_poly2.fit(X_train, y_train)
y_test_pred = svm_poly2.predict(X_test)
print(classification_report(y_test, y_test_pred))

X, y = make_classification(n_samples=100, n_features=2, n_classes=2, n_informative=1,
                           n_redundant=0, n_repeated=0, n_clusters_per_class=1,
                           class_sep=0.8, random_state=21)
X_train1, X_test1, y_train1, y_test1 = train_test_split(X, y, test_size=0.2, random_state=0, shuffle=True)

svm_linear1 = SVMClassifier(C=10.0, kernel="linear")
svm_linear1.fit(X_train1, y_train1)
y_test_pred1 = svm_linear1.predict(X_test1)
print(classification_report(y_test1, y_test_pred1))
svm_linear2 = SVMClassifier(C=10.0, kernel="linear")
svm_linear2.fit(X_train1, y_train1)
y_test_pred = svm_linear2.predict(X_test1)
print(classification_report(y_test1, y_test_pred1))

plt.figure(figsize=(21, 10))
plt.subplot(231)
svm_rbf1.plt_svm(X_train, y_train, is_show=False)
plt.subplot(232)
svm_rbf2.plt_svm(X_train, y_train, is_show=False)
plt.subplot(233)
svm_poly1.plt_svm(X_train, y_train, is_show=False)
plt.subplot(234)
svm_poly2.plt_svm(X_train, y_train, is_show=False)
plt.subplot(235)
svm_linear1.plt_svm(X_train1, y_train1, is_show=False, is_margin=True)
plt.subplot(236)
svm_linear2.plt_svm(X_train1, y_train1, is_show=False, is_margin=True)

plt.tight_layout()
plt.show()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1470924.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

曲线生成 | 图解B样条曲线生成原理(附ROS C++/Python/Matlab仿真)

目录 0 专栏介绍1 控制点计算之插值2 控制点计算之近似3 仿真实现3.1 ROS C实现3.2 Python实现3.3 Matlab实现 0 专栏介绍 &#x1f525;附C/Python/Matlab全套代码&#x1f525;课程设计、毕业设计、创新竞赛必备&#xff01;详细介绍全局规划(图搜索、采样法、智能算法等)&a…

正则表达式详细使用教程

正则是用于匹配字符串中字符组合的模式&#xff0c;在js中&#xff0c;正则也是对象。 定义正则的两种方式&#xff1a; 1.const 变量名new RegExp(/表达式/) <script>const req new RegExp(/a/)console.log(req.test("asd"))//true</script> 2.con…

Ansible 更换aliyun 镜像 并下载tree

目录 查看系统版本找到对应 的版本对当前镜像进行备份下载aliyuan更换成功安装扩展源更换源之后 的三个命令 这里安装一个aliyun 的镜像 本案例 仅供实验参考 生产环境中请谨慎使用 查看系统版本 先查看linux 的系统 版本 ansible slave -m shell -a uname -a找到对应 的版本…

SpringBoot 学习笔记

文章目录 一、IoC二、AOP三、bean3.1 bean 生命周期3.2 三种依赖注入方式3.3 bean 线程安全 四、SpringMVC五、常用注解5.1 Scope5.2 PostConstruct 和 PreDestroy5.3 Component 和 Bean5.4 Autowired 和 Resource 六、基于 ApplicationContextAware 实现工厂模式七、事务失效八…

Cubase学习:Cubase 12常用快捷键

按键盘上的上下箭头就可以让选中的音符向上或向下移动 数字0键: 停止 Ctrl+数字 0 键: 新建视图层 Alt+数字0 键: 重新设置视图层 小数点键: 播放指针回零点 数字1 键: 左定位指针 数字 2 键: 右定位指针 数字3 键--数字9键: 分别控制 3--9 的7个定位标志 Alt+数字1 键--数字9键…

BoomWorks使用wxWidgets+CodeBlocks+GCC开发的软件合集

♦️ 定时执行专家&#xff08;TimingExecutor&#xff09; V7.0 《定时执行专家》是一款制作精良、功能强大、毫秒精度、专业级的定时任务执行软件。软件具有 25 种【任务类型】、12 种【触发器】触发方式&#xff0c;并且全面支持界面化【Cron表达式】设置。软件采用多线程并…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 2月26日,星期一

每天一分钟&#xff0c;知晓天下事&#xff01; 2024年2月26日 星期一 农历正月十七 1、 气象台&#xff1a;3月初之前南方大部将维持阴雨雪天气。 2、 据海关统计&#xff0c;京津冀协同发展十年成效显著&#xff0c;外贸总量跨两个万亿台阶。 3、 2024年研考初试成绩今天起…

C++入门全集(2):类与对象【上】

目录 一、前言 二、struct在C中的变化 三、类的定义 四、类的访问限定符 五、封装 六、类的实例化 七、类对象模型 7.1 如何计算类对象的大小 7.2 类对象的存储方式 八、this指针 8.1 this指针的用途 8.2 this指针的特性 一、前言 C语言是一种面向过程的语言&…

Folx Pro Mac中文p破解版如何使用?为您带来Folx Pro 详细使用教程!

​ Folx pro 5 中文版是mac上一款功能强大的老牌加速下载软件&#xff0c;新版本的Folx pro整体界面非常的简洁和漂亮&#xff0c;具有非常好用的分类管理功能&#xff0c;支持高速下载、定时下载、速度控制、iTunes集成等功能。Folx pro兼容主流的浏览器&#xff0c;不但可以下…

什么是媒体发稿?发稿媒体分类及发稿流程

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体发稿是一种企业推广和宣传的手段&#xff0c;通过媒体渠道传递企业信息和形象。 媒体发稿的含义在于&#xff0c;当企业有新闻、事件或其他消息需要对外公布时&#xff0c;可以选择…

氢氟酸在晶圆厂中的应用与防护

氢氟酸&#xff0c;这种剧毒液体竟然会被用在晶圆的生产中&#xff0c;这个可能让你匪夷所思。实际上&#xff0c;氢氟酸这种看似普通的清澈液体&#xff0c;实则在芯片生产中扮演了至关重要的角色。 氢氟酸的性质&#xff1f; 氢氟酸&#xff08;Hydrofluoric acid&#xff0c…

【VSCode】解决VSCode远程连接问题:远程主机可能不符合 glibc 和 libstdc++

今天用VSCode进行ssh连接时&#xff0c;提示“远程主机可能不符合 glibc 和 libstdc VSCode 服务器的先决条件”。查了一下发现这个问题主要是由于VSCode在一月份发布的最新版本v1.86中要求远程主机 glibc>2.28导致的&#xff0c;所以ssh连接Ubuntu 18.04的时候就会提示这个…

AI之T2I:Stable Diffusion 3的简介、安装和使用方法、案例应用之详细攻略

AI之T2I&#xff1a;Stable Diffusion 3的简介、安装和使用方法、案例应用之详细攻略 目录 Stable Diffusion 3的简介 1、效果测试 官方demo 网友提供 Stable Diffusion 3的安装和使用方法 1、安装 2、使用方法 Stable Diffusion 3的案例应用 1、基础案例 Stable Diff…

jmeter 测试数据库的详细方法

当前版本&#xff1a; jmeter 5.6.3mysql 5.7.39 简介 JMeter是一个功能强大的开源性能测试工具&#xff0c;它被广泛用于测试Web应用程序、Web服务、API、数据库以及其他类型的应用程序。支持测试数据库的性能和可靠性&#xff0c;可以模拟多个并发用户对数据库执行各种不同类…

react中修改state中的值无效?

// 初始化state state {personArr:[{name:张三,id:1},{name:李四,id:2},{name:王五,id:3}] }componentDidMount(){const newName 赵六const indexUpdate 1const newArr this.state.personArr.map((item,index)>{if(indexUpdate index){return {...item,name:newName}}e…

二阶低通滤波器(博途PLC SCL源代码)

在学习滤波器之前我们先了解下截止频率的准确定义,周期正弦信号经过传递函数后的输出信号,其幅值衰减-3dB时对应的频率。-3dB的含义是幅值衰减为原来的约0.707。更多滤波器信号处理相关内容请参看下面文章链接: 1、PLC一阶低通滤波器 https://rxxw-control.blog.csdn.net/…

174基于matlab的雷达数字信号处理

基于matlab的雷达数字信号处理。该程序具备对雷达目标回波的处理能力&#xff0c;能够从噪声中将目标检测出来&#xff0c;并提取目标的距离、速度、角度信息。有相应的试验文档。程序已调通&#xff0c;可直接运行。 174 雷达数字信号处理 目标检测出来 (xiaohongshu.com)

java数据结构与算法刷题-----LeetCode700. 二叉搜索树中的搜索

java数据结构与算法刷题目录&#xff08;剑指Offer、LeetCode、ACM&#xff09;-----主目录-----持续更新(进不去说明我没写完)&#xff1a;https://blog.csdn.net/grd_java/article/details/123063846 文章目录 1. 法一&#xff1a;递归2. 法二&#xff1a;迭代法 解题思路:时…

Qt RGB三色灯上位机

今天突发奇想做一个Qt RGB三色灯上位机&#xff0c;刚好手上有一个RGB三色灯和arduion开发板。 我是想实现一个颜色选择器界面然后鼠标点击颜色区域就可以发出rgb的值&#xff0c;然后把这个值通过串口线发送给arduion,arduion再解析出数据发送给RGB三色灯。 实现界面如下&…

STM32单片机基本原理与应用(九)

SDIO/SD卡实验 实验内容 将SD卡插入实训平台并烧写程序&#xff0c;开机后TFTLCD屏幕上会显示是否成功初始化SD卡并显示SD卡容量。 电路原理图 实验原理 SD卡的通信方式有两种&#xff1a;SPI和SDIO。SD卡有五种寄存器&#xff0c;如下表 SD 卡的指令由 6 个字节组成&…