AHU 人工智能实验-CCA

神经网络覆盖算法——CCA(基于Ling Zhang 和Bo Zhang论文)

Abstract

在这篇文章中我将介绍基于张铃和张钹学者提出的CCA算法,并实现代码复现,给出使用的数据集,以及实验结果对比。

1. Introduction

1.1 Background

  • 我们知道自从1943年 McCulloch和Pitts第一次提出神经元的数学模型以来,神经网络开始逐步得到长足的发展。一个神经元的数学模型如下:

在这里插入图片描述

1.2 Motivation

  • 但是长久以来人工智能领域的学者都在寻找合理的几何意义,去解释上述神经元。基于此种困境,我国学者张铃和张钹提出覆盖算法(下文都用CCA代替)。

2. Geometrical Representation of Neural Model

2.1 The M-P Neuron

  • 我们先从神经元的功能开始聊起,对于一个神经元数学模型 y = sgn ( w x − θ ) y = \text{sgn}(wx - \theta) y=sgn(wxθ),其中 w w w x x x 都是 n n n 维向量, n n n 取决于输入样本的特征数,而 θ \theta θ 是阈值,也可以被称为偏置, s g n sgn sgn 是一个激活函数,它负责将最后运算的结果映射输出,传递到下一个神经元。

2.2 Sphere Neighborhoods

  • 我们先从原来的分类算法的几何意义开始聊起。

    假如我们现在有一个数据集,数据集里的数据来自两类,一个是小狗,一个是小猫,小狗的数据样本为 X = ( x 1 , x 2 , x 3 , . . . , x n , L a b e l = 0 ) X=(x1,x2,x3,...,xn,Label=0) X=(x1,x2,x3,...,xn,Label=0),小猫的数据样本为 X = ( x 1 , x 2 , x 3 , . . . , x n , L a b e l = 1 ) X=(x1,x2,x3,...,xn,Label=1) X=(x1,x2,x3,...,xn,Label=1) ,我们这里便于举例子,将小猫和小狗的特征维度假定为2,那我们在二维的向量空间中就可以标记小猫小狗的样本分布,当然为了让分布在空间中分布的更加均匀,我们首先对所有的数据进行归一化。

    归一化公式如下:
    Normalized Value = x − Min ( x ) Max ( x ) − Min ( x ) \text{Normalized Value} = \frac{x - \text{Min}(x)}{\text{Max}(x) - \text{Min}(x)} Normalized Value=Max(x)Min(x)xMin(x)

​ 我们现在绘出样本在二维空间中的分布:

在这里插入图片描述

由于如果使用超平面直接划分,则至少需要三个超平面,而且几何意义很难解释,同时在输入向量的时候维度可能不同,因此我们选择将数据升维,即将原来的样本空间投射到n+1维的一个向量空间中,这样可以保证样本长度相同。如图所示:

在这里插入图片描述
在这里插入图片描述

3. Constructive Algorithm for Neural Networks

下面我们重点介绍本篇文章的重点部分,即CCA的实现步骤。

3.1 归一化输入样本

公式如下
Normalized Value = x − Min ( x ) Max ( x ) − Min ( x ) \text{Normalized Value} = \frac{x - \text{Min}(x)}{\text{Max}(x) - \text{Min}(x)} Normalized Value=Max(x)Min(x)xMin(x)
相应代码:

# 对读入的数据进行归一化处理
def normalize_data(data):# 数据集的最后一列是标签,将其排除在归一化之外features = data.iloc[:, :-1]labels = data.iloc[:, -1]scaler = MinMaxScaler()# 将特征数据进行归一化normalized_features = scaler.fit_transform(features)# 构建归一化后的数据集,包含原标签列normalized_data_with_labels = pd.DataFrame(normalized_features, columns=features.columns)normalized_data_with_labels['Label'] = labelsreturn normalized_data_with_labels

3.2 升维,将样本投影至 n + 1 n+1 n+1 维样本空间

公式如下:

T : X → S n + 1 , T ( x ) = ( x , R 2 − ∥ x ∥ 2 ) T: X \rightarrow S^{n+1}, \quad T(x) = \left(x, \sqrt{R^2 - \lVert x \rVert^2}\right) T:XSn+1,T(x)=(x,R2x2 ),其中 R R R是所有输入样本中模值最大的值。

补充说明, ∥ x ∥ 2 = ( x 1 2 + x 2 2 + . . . + x n 2 ) \lVert x \rVert^2 = (x1^2+x2^2+...+xn^2) x2=(x12+x22+...+xn2)

举例说明

在这里插入图片描述

其中 R = 8 R=8 R=8, 即是 x 4 x4 x4 的模值,因为它最大,由上述公式我们可得

在这里插入图片描述

升维完毕。

相应代码:

# 升维函数
def uplift_dimension(normalized_data):# 计算模最大值max_norm = torch.norm(torch.tensor(normalized_data.iloc[:, :-1].values, dtype=torch.float32), dim=1).max().item()# 升维uplifted_data = []for i, sample in enumerate(normalized_data.values):original_norm = torch.norm(torch.tensor(sample[:-1].astype(float)))uplifted_value = torch.sqrt(max_norm**2 - original_norm**2).item()uplifted_sample = list(sample[:-1]) + [uplifted_value] + [int(sample[-1])]uplifted_data.append(uplifted_sample)# 创建新的 DataFrameuplifted_columns = list(normalized_data.columns)[:-1] + ['Uplifted'] + [normalized_data.columns[-1]]uplifted_df = pd.DataFrame(uplifted_data, columns=uplifted_columns)return uplifted_df

3.3 构造隐层神经元

我们这里采用的是折中半径算法,这里给出我的一些证明。

我们先随机的选中样本空间中的一个样本记为 S a m p l e A Sample_A SampleA,然后找到最小欧几里得距离的异类样本记为 S a m p l e B Sample_B SampleB,距离记为 d 2 d_2 d2,如图所示:

在这里插入图片描述

然后我们在此前提下,找出不大于 d 2 d_2 d2的欧几里得距离最大的同类样本 S a m p l e C Sample_C SampleC,距离记为 d 1 d_1 d1,然后取折中半径 d = ( d 1 + d 2 ) / 2 d=(d_1+d_2)/2 d=(d1+d2)/2, 如图所示:

在这里插入图片描述

但是我们发现在此种情况下,我们可以使用内积来代替欧几里得距离,证明如下:

欧几里得距离:在这里插入图片描述

这里由于数据已经归一化过了,所以所有的样本模长都等于 R 2 R^2 R2,所以上述距离公式可以化简为 d i s t ( x k , x i ) = 2 R 2 − 2 < x k , x i > dist(x_k,x_i)= \sqrt{2R^2-2<x_k,x_i>} dist(xk,xi)=2R22<xk,xi> ,其中 < x k , x i > <x_k,x_i> <xk,xi>代表两者的内积,因为 R 2 R^2 R2是一个固定值,所以求最小距离等价于求最大的内积,同理求最大距离等价于求最小的内积。

所以上述问题转化为求最大内积的异类样本点,求最小内积的同类样本点。

对于覆盖模型的数据结构,我们采用以下结构体:

# 定义覆盖结构体
class CoverStruct:def __init__(self, center, radius, label, index):self.center = centerself.radius = radiusself.label = labelself.index = index

我们每训练得一个覆盖,就记录他的中心和半径,以及该覆盖的标签,和序号。

相关代码:

    def train_covering_nn(self, data):# 获取样本总数num_samples = len(data)print(num_samples)# 设置已学习样本的集合learned_samples = set()# 记录已学习的样本数量samples_learned_count = 0cover_index = 0# 循环的终止条件是训练集中的所有样本都被学习过while samples_learned_count < num_samples:# 检查是否还有未学习的样本remaining_samples = set(range(num_samples)) - learned_samplesprint(remaining_samples)if not remaining_samples:break  # 所有样本都已学习过,提前结束循环# 随机选择一个未学习的样本Aa_index = random.choice(list(remaining_samples))print(a_index)# 选择样本Aa_sample = torch.tensor(data.iloc[a_index, :-1].values, dtype=torch.float32)print(a_sample)# 找到异类样本B和内积值d1# 从数据集中选择标签与样本A不同的所有样本# 排除已经学习过的样本b_samples = data[(data.index.isin(remaining_samples)) & (data['Label'] != data.iloc[a_index, -1])]# 检查是否有这样的样本if len(b_samples) > 0:# 将所选样本的特征值转换为 PyTorch 张量b_samples_values = torch.tensor(b_samples.iloc[:, :-1].values, dtype=torch.float32)print(b_samples_values)# 计算每个b_samples中的样本与样本A的内积inner_products = torch.matmul(b_samples_values, a_sample)print(inner_products)# 找到b_samples中具有最大内积的样本的索引b_sample_index = inner_products.argmax().item()print("b_sample_index:", b_sample_index)# 提取具有最大内积的样本b_sample = b_samples_values[b_sample_index]print("b_sample:", b_sample)# 提取最大内积的值d1 = inner_products[b_sample_index].item()else:# 如果b_samples中没有样本,则将d1设为0d1 = 0print("Max inner_product", d1)# 找到同类样本C和内积值d2# 从数据集中选择标签与样本A相同的所有样本c_samples = data[(data.index.isin(remaining_samples)) & (data['Label'] == data.iloc[a_index, -1])]# 检查是否有这样的样本# 将所选样本的特征值转换为 PyTorch 张量c_samples_values = torch.tensor(c_samples.iloc[:, :-1].values, dtype=torch.float32)# 计算每个c_samples中的样本与样本A的内积inner_products_c = torch.matmul(c_samples_values, a_sample)valid_inner_products_indices = (inner_products_c > d1).nonzero().view(-1)if len(valid_inner_products_indices) > 0:min_inner_product_index = torch.argmin(inner_products_c[valid_inner_products_indices]).item()# 提取具有最小内积的样本c_sample = c_samples_values[valid_inner_products_indices[min_inner_product_index]]print("c_sample:", c_sample)# 提取最小内积的值d2 = inner_products_c[valid_inner_products_indices[min_inner_product_index]].item()else:# 如果没有满足条件的样本,则将d2设为d1d2 = d1print("Min inner_product", d2)# 如果d2 > d1,则更新覆盖模型if d2 >= d1:d = (d1 + d2) / 2learned_samples.add(a_index)# 创建新的覆盖结构体,其中包括样本A、覆盖半径d和样本A的标签new_cover = CoverStruct(a_sample, d, data.iloc[a_index, -1], cover_index)# 每个覆盖相当于一个神经元# 将新的覆盖添加到模型的覆盖列表中self.cover_list.append(new_cover)# 更新已学习样本的集合,将在新覆盖中的样本标记为已学习learned_samples.update(get_covered_samples(data, new_cover))# 更新已学习的样本数量samples_learned_count = len(learned_samples)print("已学习的样本数量", samples_learned_count)cover_index += 1print("训练完成。")cover_data = {'Center': [cover.center.numpy() for cover in self.cover_list],'Radius': [cover.radius for cover in self.cover_list],'Label': [cover.label for cover in self.cover_list],'Index': [cover.index for cover in self.cover_list]}cover_df = pd.DataFrame(cover_data)print("\n覆盖列表的数据框形式:")print(cover_df)

3.4 测试过程

我们采用十折交叉验证,这里解释一下十折交叉验证(图片来自周志华老师的《机器学习》):

在这里插入图片描述

验证的过程是,每个测试集测试的时候,我们逐个验证覆盖列表中的每一个覆盖,顺序遍历每一个覆盖,直到找到一个覆盖能包含测试样本为止,然后预测标签就等于覆盖标签,如果遍历所有覆盖我们都没有找能够包含测试样本的覆盖,那么我们选取距离覆盖中心内积值最大的(即距离中心欧几里得距离最小的)覆盖的覆盖标签作为预测标签。

相关代码:

    def test_covering_nn(self, test_data):all_outputs = []for _, test_sample in test_data.iterrows():outputs = []test_sample_tensor = torch.tensor(test_sample[:-1].values, dtype=torch.float32)for cover in self.cover_list:inner_product = torch.matmul(test_sample_tensor, cover.center)result = 1 if inner_product > cover.radius else 0output = CoveringResult(cover.label, result)outputs.append(output)# 找到第一个被覆盖的样本covered_sample = Nonefor output in outputs:if output.result == 1:covered_sample = outputbreak# 如果有被覆盖的样本,则返回整个列表if covered_sample is not None:all_outputs.append(covered_sample.label)# 如果没有任何一个覆盖包含测试样本,则返回内积最大的元素的标签else:max_inner_product_index = Nonemax_inner_product_value = float('-inf')for i, output in enumerate(outputs):if output.result > max_inner_product_value:max_inner_product_value = output.resultmax_inner_product_index = iif max_inner_product_index is not None:max_inner_product_label = outputs[max_inner_product_index].labelall_outputs.append(max_inner_product_label)# 使用占位符值 -1 替换 None 值all_outputs = [label if label is not None else -1 for label in all_outputs]# 确保总是返回与测试样本数相匹配的预测标签列表return all_outputs if all_outputs else [-1] * len(test_data)

4. Results and Comparison

DatabaseCCA(accuracy)My_CCA(accuracy)Accuracy Difference
Haberman+s+survival65.30%70.24%4.94%
Fertility80.48%81.20%0.72%
Ionosphere90.77%91.43%0.66%

5. Reflection

这是本人自己第一次实现一个简单的神经网络,经历了日日夜夜的写代码,改代码的痛苦过程,当最后的预测结果和论文差不多时,心情是非常激动的,在此之前,我对神经网络的认识仅仅停留在输入层,输出层,Hidden Layer,还有激活函数,优化等名词,我的总结是人工智能这门课,你不能当作一门理论课去学习,而是应当当作一门实验课去学习,甚至是当作一门语言去学习,我指的是你需要写大量的代码来提高自己的能力。做永远比想更为重要!

6.Resource

数据集来源:

https://archive.ics.uci.edu/datasets?skip=10&take=10&sort=desc&orderBy=NumHits&search=Glass

开源代码:

Pytorch的安装方法可以参考CSDN上其他热门答主的回答。

import torch
import torch.nn as nn
import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from sklearn.model_selection import KFold
import random
from sklearn.metrics import accuracy_score
from sklearn.preprocessing import LabelEncoder
from sklearn.impute import SimpleImputer# 定义覆盖结构体
class CoverStruct:def __init__(self, center, radius, label, index):self.center = centerself.radius = radiusself.label = labelself.index = index# 定义输出结构体
class CoveringResult:def __init__(self, label, result):self.label = labelself.result = result
def get_covered_samples(data, cover):# 找到在给定覆盖中的样本集合covered_samples = set()for i, sample in data.iterrows():sample_values = torch.tensor(sample[:-1].values, dtype=torch.float32)# 计算样本到覆盖中心的内积inner_product = torch.dot(sample_values, torch.tensor(cover.center))# 如果距离大于等于覆盖半径,将该样本加入集合if inner_product >= cover.radius:covered_samples.add(i)return covered_samples# 定义模型
class CoveringNN(nn.Module):def __init__(self, input_size):super(CoveringNN, self).__init__()self.cover_list = []self.input_size = input_size# 我们使用内积来转换欧几里得距离函数,这里我给出自己的一些证明,内积<X1,X2>=X1.1*X2.1+...X1.n*X2.n# 欧几里得距离函数,(X1-X2)^2=X1.1^2+X1.2^2+...+X1.n^2+X2.1^2+X2.2^2+X2.n^2-2*(X1.1*X2.1+...X1.n*X2.n)# 要将此处转换,必须保证的前提是,每个样本的模长相等,我们经过归一化之后,每个样本的模长是R(即是所有样本中最大的模长)# 使用折中半径法,对于没有d1的情况,我们可以使用最大的同类样本距离去度量,即大于最小同类样本内积即可# 对于没有d2的情况,使用最小的异类样本距离,即用小于最大的异类样本内积即可def train_covering_nn(self, data):# 获取样本总数num_samples = len(data)print(num_samples)# 设置已学习样本的集合learned_samples = set()# 记录已学习的样本数量samples_learned_count = 0cover_index = 0# 循环的终止条件是训练集中的所有样本都被学习过while samples_learned_count < num_samples:# 检查是否还有未学习的样本remaining_samples = set(range(num_samples)) - learned_samplesprint(remaining_samples)if not remaining_samples:break  # 所有样本都已学习过,提前结束循环# 随机选择一个未学习的样本Aa_index = random.choice(list(remaining_samples))print(a_index)# 选择样本Aa_sample = torch.tensor(data.iloc[a_index, :-1].values, dtype=torch.float32)print(a_sample)# 找到异类样本B和内积值d1# 从数据集中选择标签与样本A不同的所有样本# 排除已经学习过的样本b_samples = data[(data.index.isin(remaining_samples)) & (data['Label'] != data.iloc[a_index, -1])]# 检查是否有这样的样本if len(b_samples) > 0:# 将所选样本的特征值转换为 PyTorch 张量b_samples_values = torch.tensor(b_samples.iloc[:, :-1].values, dtype=torch.float32)print(b_samples_values)# 计算每个b_samples中的样本与样本A的内积inner_products = torch.matmul(b_samples_values, a_sample)print(inner_products)# 找到b_samples中具有最大内积的样本的索引b_sample_index = inner_products.argmax().item()print("b_sample_index:", b_sample_index)# 提取具有最大内积的样本b_sample = b_samples_values[b_sample_index]print("b_sample:", b_sample)# 提取最大内积的值d1 = inner_products[b_sample_index].item()else:# 如果b_samples中没有样本,则将d1设为0d1 = 0print("Max inner_product", d1)# 找到同类样本C和内积值d2# 从数据集中选择标签与样本A相同的所有样本c_samples = data[(data.index.isin(remaining_samples)) & (data['Label'] == data.iloc[a_index, -1])]# 检查是否有这样的样本# 将所选样本的特征值转换为 PyTorch 张量c_samples_values = torch.tensor(c_samples.iloc[:, :-1].values, dtype=torch.float32)# 计算每个c_samples中的样本与样本A的内积inner_products_c = torch.matmul(c_samples_values, a_sample)valid_inner_products_indices = (inner_products_c > d1).nonzero().view(-1)if len(valid_inner_products_indices) > 0:min_inner_product_index = torch.argmin(inner_products_c[valid_inner_products_indices]).item()# 提取具有最小内积的样本c_sample = c_samples_values[valid_inner_products_indices[min_inner_product_index]]print("c_sample:", c_sample)# 提取最小内积的值d2 = inner_products_c[valid_inner_products_indices[min_inner_product_index]].item()else:# 如果没有满足条件的样本,则将d2设为d1d2 = d1print("Min inner_product", d2)# 如果d2 > d1,则更新覆盖模型if d2 >= d1:d = (d1 + d2) / 2learned_samples.add(a_index)# 创建新的覆盖结构体,其中包括样本A、覆盖半径d和样本A的标签new_cover = CoverStruct(a_sample, d, data.iloc[a_index, -1], cover_index)# 每个覆盖相当于一个神经元# 将新的覆盖添加到模型的覆盖列表中self.cover_list.append(new_cover)# 更新已学习样本的集合,将在新覆盖中的样本标记为已学习learned_samples.update(get_covered_samples(data, new_cover))# 更新已学习的样本数量samples_learned_count = len(learned_samples)print("已学习的样本数量", samples_learned_count)cover_index += 1print("训练完成。")cover_data = {'Center': [cover.center.numpy() for cover in self.cover_list],'Radius': [cover.radius for cover in self.cover_list],'Label': [cover.label for cover in self.cover_list],'Index': [cover.index for cover in self.cover_list]}cover_df = pd.DataFrame(cover_data)print("\n覆盖列表的数据框形式:")print(cover_df)def test_covering_nn(self, test_data):all_outputs = []for _, test_sample in test_data.iterrows():outputs = []test_sample_tensor = torch.tensor(test_sample[:-1].values, dtype=torch.float32)for cover in self.cover_list:inner_product = torch.matmul(test_sample_tensor, cover.center)result = 1 if inner_product > cover.radius else 0output = CoveringResult(cover.label, result)outputs.append(output)# 找到第一个被覆盖的样本covered_sample = Nonefor output in outputs:if output.result == 1:covered_sample = outputbreak# 如果有被覆盖的样本,则返回整个列表if covered_sample is not None:all_outputs.append(covered_sample.label)# 如果没有任何一个覆盖包含测试样本,则返回内积最大的元素的标签else:max_inner_product_index = Nonemax_inner_product_value = float('-inf')for i, output in enumerate(outputs):if output.result > max_inner_product_value:max_inner_product_value = output.resultmax_inner_product_index = iif max_inner_product_index is not None:max_inner_product_label = outputs[max_inner_product_index].labelall_outputs.append(max_inner_product_label)# 使用占位符值 -1 替换 None 值all_outputs = [label if label is not None else -1 for label in all_outputs]# 确保总是返回与测试样本数相匹配的预测标签列表return all_outputs if all_outputs else [-1] * len(test_data)# 首先读入数据集
def read_dataset(file_path):data = pd.read_csv(file_path)# 读取数据,假设第一行是数据# 标签预处理data.iloc[:, -1] = LabelEncoder().fit_transform(data.iloc[:, -1])# 创建一个SimpleImputer实例,使用均值进行填充imputer = SimpleImputer(strategy='mean')data.replace('?', np.nan, inplace=True)data = data.astype(float)data_imputed = pd.DataFrame(imputer.fit_transform(data), columns=data.columns)return data# 对读入的数据进行归一化处理
def normalize_data(data):# 数据集的最后一列是标签,将其排除在归一化之外features = data.iloc[:, :-1]labels = data.iloc[:, -1]scaler = MinMaxScaler()# 将特征数据进行归一化normalized_features = scaler.fit_transform(features)# 构建归一化后的数据集,包含原标签列normalized_data_with_labels = pd.DataFrame(normalized_features, columns=features.columns)normalized_data_with_labels['Label'] = labelsreturn normalized_data_with_labels# 升维函数
def uplift_dimension(normalized_data):# 计算模最大值max_norm = torch.norm(torch.tensor(normalized_data.iloc[:, :-1].values, dtype=torch.float32), dim=1).max().item()# 升维uplifted_data = []for i, sample in enumerate(normalized_data.values):original_norm = torch.norm(torch.tensor(sample[:-1].astype(float)))uplifted_value = torch.sqrt(max_norm**2 - original_norm**2).item()uplifted_sample = list(sample[:-1]) + [uplifted_value] + [int(sample[-1])]uplifted_data.append(uplifted_sample)# 创建新的 DataFrameuplifted_columns = list(normalized_data.columns)[:-1] + ['Uplifted'] + [normalized_data.columns[-1]]uplifted_df = pd.DataFrame(uplifted_data, columns=uplifted_columns)return uplifted_df#读入数据集
file_path = 'example.data'data = read_dataset(file_path)
print(data)#开始归一化处理
normalized_features = normalize_data(data)
print(normalized_features)
#升维
uplifted_data = uplift_dimension(normalized_features)print(uplifted_data)input_size = len(uplifted_data.columns) - 1
model = CoveringNN(input_size)# 初始化十折交叉验证
kf = KFold(n_splits=10, shuffle=True, random_state=42)# 存储每折的性能指标
accuracy_list = []# 开始十折交叉验证
for train_index, test_index in kf.split(uplifted_data):# 划分训练集和测试集train_data, test_data = uplifted_data.iloc[train_index], uplifted_data.iloc[test_index]# 初始化模型model = CoveringNN(input_size)# 训练模型model.train_covering_nn(train_data)# 测试模型test_results = model.test_covering_nn(test_data)results = pd.DataFrame(test_results)merged_data = pd.concat([results, test_data.iloc[:, -1]], axis=1)print(merged_data)# 计算准确率并存储accuracy = accuracy_score(test_data.iloc[:, -1], results)accuracy_list.append(accuracy)# 计算平均准确率
average_accuracy = sum(accuracy_list) / len(accuracy_list)
print(f'Average Accuracy: {average_accuracy * 100:.2f}%')

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Go语言简介

一.Go语言简介 1.1 优点 自带gc静态编译&#xff0c;编译好后&#xff0c;扔服务器直接运行简单思想&#xff0c;没有继承&#xff0c;多态和类等丰富的库和详细开发文档语法层支持并发&#xff0c;和拥有同步并发的channel类型&#xff0c;使并发开发变得非常方便简洁语法&am…

Oracle with as用法

一、简介 with…as关键字&#xff0c;是以‘with’关键字开头的sql语句&#xff0c;在实际工作中&#xff0c;我们经常会遇到同一个查询sql会同时查询多个相同的结果集&#xff0c;即sql一模一样&#xff0c;这时候我们可以将这些相同的sql抽取出来&#xff0c;使用with…as定…

中国(京津冀)太阳能光伏推进大会暨展览会

中国(京津冀)太阳能光伏推进大会暨展览会是一个旨在促进太阳能光伏行业发展的会议和展览会。该事件旨在推动中国在太阳能光伏领域的创新和发展&#xff0c;特别是在京津冀地区。 会议将邀请来自政府、企业、学术界和国际组织的专家和代表&#xff0c;共同探讨太阳能光伏技术、政…

【Redis系列】深入了解 Redis:一种高性能的内存数据库

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

Elastic stack(一):Elastic stack简介、Elasticsearch简介、安装

目录 1 Elastic Stack1.1 Elastic Stack介绍1.2 为什么要用到ELK日志分析1.3 ELK的组件1.4 ELK架构原理1、ELK工作流程2、ELFK工作流程 2 Elasticsearch2.1 Elasticsearch简介1、什么是Elasticsearch2、数据来源&#xff1a;索引&#xff08;indices&#xff09;和文档&#xf…

docker常用操作-docker私有仓库的搭建(Harbor),并将本地镜像推送至远程仓库中。

1、docker-compose安装&#xff0c;下载docker-compose的最新版本 第一步&#xff1a;创建docker-compose空白存放文件vi /usr/local/bin/docker-compose 第二步&#xff1a;使用curl命令在线下载&#xff0c;并制定写入路径 curl -L "https://github.com/docker/compos…

【牛客】VL68 同步FIFO

描述 请设计带有空满信号的同步FIFO&#xff0c;FIFO的深度和宽度可配置。双口RAM的参考代码和接口信号已给出&#xff0c;请在答案中添加并例化此部分代码。 电路的接口如下图所示。端口说明如下表。 接口电路图如下&#xff1a; 双口RAM端口说明&#xff1a; 端口名I/O描述…

如何在CentOS7搭建DashDot服务器仪表盘并实现远程监控

文章目录 1. 本地环境检查1.1 安装docker1.2 下载Dashdot镜像 2. 部署DashDot应用3. 本地访问DashDot服务4. 安装cpolar内网穿透5. 固定DashDot公网地址 本篇文章我们将使用Docker在本地部署DashDot服务器仪表盘&#xff0c;并且结合cpolar内网穿透工具可以实现公网实时监测服务…

08-java基础-锁之AQSReentrantLockBlockingQueueCountDownLatchSemapho

文章目录 0&#xff1a;AQS简介-常见面试题AQS具备特性state表示资源的可用状态AQS定义两种资源共享方式AQS定义两种队列自定义同步器实现时主要实现以下几种方法&#xff1a;同步等待队列条件等待队列 1&#xff1a;AQS应用之ReentrantLockReentrantLock如何实现synchronized不…

Python | Bootstrap图介绍

在进入Bootstrap 图之前&#xff0c;让我们先了解一下Bootstrap&#xff08;或Bootstrap 抽样&#xff09;是什么。 Bootstrap 抽样&#xff08;Bootstrap Sampling&#xff09;&#xff1a;这是一种方法&#xff0c;我们从一个数据集中重复地取一个样本数据来估计一个总体参数…

Capture One 23:光影魔术师,细节掌控者mac/win版

Capture One 23&#xff0c;不仅仅是一款摄影后期处理软件&#xff0c;它更是摄影师们的得力助手和创意伙伴。这款软件凭借其卓越的性能、丰富的功能和前沿的技术&#xff0c;为摄影师们带来了前所未有的影像处理体验。 Capture One 23软件获取 Capture One 23以其强大的色彩…

【C++教程从0到1入门编程】第八篇:STL中string类的模拟实现

一、 string类的模拟实现 下面是一个列子 #include <iostream> namespace y {class string{public: //string() //无参构造函数// :_str(nullptr)//{}//string(char* str) //有参构造函数// :_str(str)//{}string():_str(new char[1]){_str[0] \0;}string(c…

RuoYi开源项目1-下载并实现运行RuoYi项目

下载并实现运行RuoYi项目 环境需要下载项目项目配置后端项目配置前端项目配置 启动后前端登录页面截图 环境需要 JDK > 8MySQL >5.7Maven > 3.0Node > 12Redis > 3 下图是我的环境配置 下载项目 若依官网 1.进入官网&#xff0c;下载版本如下图RuoYi-Vue前后…

【Vue2】组件通信

父子通信 父 -> 子 子 -> 父 props 校验 props: {校验的属性名: {type: 类型, // Number String Boolean ...required: true, // 是否必填default: 默认值, // 默认值validator (value) {// 自定义校验逻辑return 是否通过校验}} },data 的数据是自己的 → 随便改pr…

【2024-完整版】python爬虫 批量查询自己所有CSDN文章的质量分:附整个实现流程

【2024】批量查询CSDN文章质量分 写在最前面一、分析获取步骤二、获取文章列表1. 前期准备2. 获取文章的接口3. 接口测试&#xff08;更新重点&#xff09; 三、查询质量分1. 前期准备2. 获取文章的接口3. 接口测试 四、python代码实现1. 分步实现2. 批量获取文章信息3. 从exce…

豆瓣书影音存入Notion

使用Python将图书和影视数据存放入Notion中。 &#x1f5bc;️介绍 环境 Python 3.10 &#xff08;建议 3.11 及以上&#xff09;Pycharm / Vs Code / Vs Code Studio 项目结构 │ .env │ main.py - 主函数、执行程序 │ new_book.txt - 上一次更新书籍 │ new_video.…

教师如何搭建学生查询考试分数的平台?

随着信息技术的快速发展&#xff0c;搭建一个学生查询考试分数的平台已经成为现代教育管理的重要组成部分。这样的平台不仅可以提高成绩管理的效率&#xff0c;还能为学生提供便捷、及时的成绩查询服务。那么&#xff0c;作为教师&#xff0c;我们应该如何搭建这样一个平台呢&a…

2024年华为HCIA-DATACOM新增题库(H12-811)

801、[单选题]178/832、在系统视图下键入什么命令可以切换到用户视图? A quit B souter C system-view D user-view 试题答案&#xff1a;A 试题解析&#xff1a;在系统视图下键入quit命令退出到用户视图。因此答案选A。 802、[单选题]“网络管理员在三层交换机上创建了V…

GPT与R 在生态环境领域数据统计分析

原文链接&#xff1a;GPT与R 在生态环境领域数据统计分析https://mp.weixin.qq.com/s?__bizMzUzNTczMDMxMg&mid2247597092&idx2&sn0a7ac5cf03d37c7b4659f870a7b71a77&chksmfa823dc3cdf5b4d5ee96a928a1b854a44aff222c82b2b7ebb7ca44b27a621edc4c824115babe&…

Java实现Tron(波场)区块链的开发实践(三)波场链水龙头、WEB3测试实战

上一节我们具体讲到Java实现Tron波场链的逻辑代码实现。 这一节我们通过部署和开发好的代码&#xff0c;针对测试链进行自测开发&#xff0c;准备测试环境。 1. 创建离线地址 首先我们需要一个离线地址&#xff0c;我们不需要在线进行创建&#xff0c;直接可以通过第一节的离…