《统计学习方法:李航》笔记 从原理到实现(基于python)-- 第3章 k邻近邻法

news2024/12/24 1:40:47

文章目录

  • 第3章 k邻近邻法
    • 3.1 k近邻算法
    • 3.2 k近邻模型
      • 3.2.1 模型
      • 3.2.2 距离度量
      • 3.2.3 k值的选择
      • 3.2.4 分类决策规则
    • 3.3 k近邻法的实现:kd树
      • 3.3.1 构造kd树
      • 3.3.2 搜索kd树
    • 算法实现
      • 课本例3.1
      • iris数据集
      • scikit-learn实例
      • kd树:构造平衡kd树算法
      • 例3.2

《统计学习方法:李航》笔记 从原理到实现(基于python)-- 第3章 k邻近邻法
《统计学习方法:李航》笔记 从原理到实现(基于python)-- 第1章 统计学习方法概论
《统计学习方法:李航》笔记 从原理到实现(基于python)-- 第 2章感知机

我算是有点基础的(有过深度学习和机器学的项目经验),但也是半路出家,无论是学Python还是深度学习,都是从问题出发,边查边做,没有系统的学过相关的知识,这样的好处是入门快(如果想快速入门,大家也可以试试,直接上手项目,从小项目开始),但也存在一个严重的问题就是,很多东西一知半解,容易走进死胡同出不来(感觉有点像陷入局部最优解,找不到出路),所以打算系统的学习几本口碑比较不错的书籍。
  书籍选择: 当然,机器学习相关的书籍有很多,很多英文版的神书,据说读英文版的书会更好,奈何英文不太好,比较难啃。国内也有很多书,周志华老师的“西瓜书”我也有了解过,看了前几章,个人感觉他肯能对初学者更友好一点,讲述的非常清楚,有很多描述性的内容。对比下来,更喜欢《统计学习方法》,毕竟能坚持看完才最重要。
  笔记内容: 笔记内容尽量省去了公式推导的部分,一方面latex编辑太费时间了,另一方面,我觉得公式一定要自己推到一边才有用(最好是手写)。尽量保留所有标题,但内容会有删减,通过标黑和列表的形式突出重点内容,要特意说一下,标灰的部分大家最好读一下(这部分是我觉得比较繁琐,但又不想删掉的部分)。
  代码实现: 最后是本章内容的实践,如果想要对应的.ipynb文件,可以留言

第3章 k邻近邻法

  k近邻法(k-nearest neighbor,k-NN) 是一种基本分类与回归方法。

  k近邻法的输入为实例的特征向量,对应于特征空间的点;输出为实例的类别,可以取多类。

  k近邻法假设给定一个训练数据集,其中的实例类别已定。分类时,对新的实例,根据其k个最近邻的训练实例的类别,通过多数表决等方式进行预测。

  因此,k近邻法不具有显式的学习过程。k近邻法实际上利用训练数据集对特征向量空间进行划分,并作为其分类的“模型”。

  k值的选择距离度量分类决策规则是k近邻法的三个基本要素

3.1 k近邻算法

  k近邻算法简单、直观:给定一个训练数据集,对新的输入实例,在训练数据集中找到与该实例最邻近的k个实例,这k个实例的多数属于某个类,就把该输入实例分为这个类。

k近邻算法:

输入: 训练数据集

T = ( ( x 1 , y 1 ) , ( x 2 , y 2 ) , . . . . . . ( x N , y N ) ) T=((x_1,y_1),(x_2,y_2),......(x_N,y_N)) T=((x1,y1),(x2,y2),......(xN,yN))

  其中, x i ∈ R n x_i\in R^n xiRn为实例的特征向量, y i ∈ Y = ( c 1 , c 2 , … , c K ) y_i\in Y=({c_1,c_2,…,c_K}) yiY(c1c2,,cK)为实例的类别

输出: 实例x所属的类y。

  (1)根据给定的距离度量,在训练集T中找出与x最邻近的k个点,涵盖这k个点的x的邻域记作 N k ( x ) N_k(x) Nk(x)
  (2)在 N k ( x ) N_k(x) Nk(x)中根据分类决策规则(如多数表决)决定x的类别y:

y = a r g m a x ∑ x i ∈ N k ( x ) I ( t i = c j ) , i = 1 , 2.... N ; j = 1 , 2.... K y=arg max \sum_{x_i \in N_k(x)}I(t_i=c_j),i=1,2....N;j=1,2....K y=argmaxxiNk(x)I(ti=cj),i=1,2....N;j=1,2....K

  其中,I为指示函数,即当 y i = c j y_i=c_j yicj时I为1,否则I为0。

3.2 k近邻模型

  k近邻法使用的模型实际上对应于对特征空间的划分

  模型由三个基本要素——距离度量、k值的选择和分类决策规则决定。

3.2.1 模型

  特征空间中,对每个训练实例点 x i x_i xi,距离该点比其他点更近的所有点组成一个区域,叫作单元(cell)。每个训练实例点拥有一个单元,所有训练实例点的单元构成对特征空间的一个划分。

  最近邻法将实例 x i x_i xi的类 y i y_i yi作为其单元中所有点类标记(class label)。这样,每个单元的实例点的类别是确定的。

3.2.2 距离度量

  特征空间中两个实例点的距离是两个实例点相似程度的反映。k近邻模型的特征空间一般是 n维实数向量空间 R n R^n Rn 使用的距离是欧氏距离,但也可以是其他距离。

  设特征空间X是n维实数向量空间 R n R^n Rn , x i , x i ∈ X ,x_i,x_i \in X ,xi,xiX x i = ( x i ( 1 ) , x i ( 2 ) … x i ( T ) ) T x_i=(x_i^{(1)},x_i^{(2)}…x_i^{(T)})^T xi=(xi(1),xi(2)xi(T))T x j = ( x j ( 1 ) , x j ( 2 ) … x j ( n ) ) T x_j=(x_j^{(1)},x_j^{(2)}…x_j^{(n)})^T xj=(xj(1),xj(2)xj(n))T**

   x i , x i x_i,x_i xi,xi的距离 L p L_p Lp定义为:

L p ( x i , x j ) = ( ∑ l = 1 n ∣ x i ( l ) − x j ( l ) ∣ p ) 1 p L_p(x_i,x_j)=(\sum_{l=1}^n|x_i^{(l)}-x_j^{(l)}|^p)^{\frac{1}{p}} Lp(xi,xj)=(l=1nxi(l)xj(l)p)p1

  • 当p≥1。当p=2时,称为欧氏距离(Euclidean distance);
  • 当p=1时,称为曼哈顿距离(Manhattan distance)
  • 当p=∞ 时,它是各个坐标距离的最大值

下面的例子说明,由不同的距离度量所确定的最近邻点是不同的。

在这里插入图片描述

3.2.3 k值的选择

  k值的选择会对k近邻法的结果产生重大影响。

  • 如果选择较小的k值: 就相当于用较小的邻域中的训练实例进行预测
    • “学习”的近似误差(approximation error)会减小,只有与输入实例较近的(相似的)训练实例才会对预测结果起作用。
    • 但缺点是“学习”的估计误差(estimation error)会增大,预测结果会对近邻的实例点非常敏感[2]。(如果邻近的实例点恰巧是噪声,预测就会出错。换句话说,k值的减小就意味着整体模型变得复杂,容易发生过拟合。)
  • 如果选择较大的k值: 就相当于用较大邻域中的训练实例进行预测。
    • 其优点是可以减少学习的估计误差。
    • 但缺点是学习的近似误差会增大。这时与输入实例较远的(不相似的)训练实例也会对预测起作用,使预测发生错误。(k值的增大就意味着整体的模型变得简单。)

  在应用中,k值一般取一个比较小的数值。通常采用交叉验证法来选取最优的k值。

3.2.4 分类决策规则

  k近邻法中的分类决策规则往往是多数表决,即由输入实例的k个邻近的训练实例中的多数类决定输入实例的类。
多数表决规则(majority voting rule):

  对给定的实例 x ∈ X x\in X xX,其最近邻的k个训练实例点构成集合 N k ( x ) N_k(x) Nk(x)。如果涵盖 N k ( x ) N_k(x) Nk(x)的区域的类别是 c j c_j cj,那么误分类率是:

1 k ∑ x i ∈ N x ( x ) I ( y i ≠ c j ) = 1 − 1 k ∑ x i ∈ N x ( x ) I ( y i = c j ) \frac{1}{k}\sum_{x_i\in N_x(x)}I(y_i\neq c_j)=1-\frac{1}{k}\sum_{x_i\in N_x(x)}I(y_i=c_j) k1xiNx(x)I(yi=cj)=1k1xiNx(x)I(yi=cj)

  要使误分类率最小即经验风险最小,就要使 ∑ x i ∈ N x ( x ) I ( y i = c j ) \sum_{x_i\in N_x(x)}I(y_i=c_j) xiNx(x)I(yi=cj)最大,所以多数表决规则等价于经验风险最小化

3.3 k近邻法的实现:kd树

  实现k近邻法时,主要考虑的问题是如何对训练数据进行快速k近邻搜索
k近邻法最简单的实现方法是线性扫描(linear scan)。这时要计算输入实例与每一个训练实例的距离。
  为了提高k近邻搜索的效率,可以考虑使用特殊的结构存储训练数据,以减少计算距离的次数。

3.3.1 构造kd树

  kd树是一种对k维空间中的实例点进行存储以便对其进行快速检索的树形数据结构。

  kd树是二叉树,表示对k维空间的一个划分(partition)。构造kd树相当于不断地用垂直于坐标轴的超平面将k维空间切分,构成一系列的k维超矩形区域。kd树的每个结点对应于一个k维超矩形区域。

构造kd树的方法如下:

  • 构造根结点,使根结点对应于k维空间中包含所有实例点的超矩形区域;
  • 通过下面的递归方法,不断地对k维空间进行切分,生成子结点。
  • 在超矩形区域(结点)上选择一个坐标轴和在此坐标轴上的一个切分点,确定一个超平面,这个超平面通过选定的切分点并垂直于选定的坐标轴,将当前超矩形区域切分为左右两个子区域(子结点);
  • 这时,实例被分到两个子区域。这个过程直到子区域内没有实例时终止(终止时的结点为叶结点)。

在这里插入图片描述

3.3.2 搜索kd树

  下面介绍如何利用kd树进行k近邻搜索。可以看到,利用kd树可以省去对大部分数据点的搜索,从而减少搜索的计算量。

  这里以最近邻为例加以叙述,同样的方法可以应用到k近邻。

  • 给定一个目标点,搜索其最近邻。
  • 首先找到包含目标点的叶结点;
  • 然后从该叶结点出发,依次回退到父结点;
  • 不断查找与目标点最邻近的结点,当确定不可能存在更近的结点时终止。

  这样搜索就被限制在空间的局部区域上,效率大为提高。

  包含目标点的叶结点对应包含目标点的最小超矩形区域。以此叶结点的实例点作为当前最近点。目标点的最近邻一定在以目标点为中心并通过当前最近点的超球体的内部(参阅图3.5)。

  然后返回当前结点的父结点,如果父结点的另一子结点的超矩形区域与超球体相交,那么在相交的区域内寻找与目标点更近的实例点。如果存在这样的点,将此点作为新的当前最近点。算法转到更上一级的父结点,继续上述过程。如果父结点的另一子结点的超矩形区域与超球体不相交,或不存在比当前最近点更近的点,则停止搜索。

在这里插入图片描述

算法实现

import math
from itertools import combinations
def L(x, y, p=2):
	# x1 = [1, 1], x2 = [5,1]
	if len(x) == len(y) and len(x) > 1:
		sum = 0
		for i in range(len(x)):
			sum += math.pow(abs(x[i] - y[i]), p)
		return math.pow(sum, 1 / p)
	else:
	return 0

课本例3.1

在这里插入图片描述

x1 = [1, 1]
x2 = [5, 1]
x3 = [4, 4]
# x1, x2
for i in range(1, 5):
	r = {'1-{}'.format(c): L(x1, c, p=i) for c in [x2, x3]}
	print(min(zip(r.values(), r.keys())))
==============================
(4.0, '1-[5, 1]')
(4.0, '1-[5, 1]')
(3.7797631496846193, '1-[4, 4]')
(3.5676213450081633, '1-[4, 4]')

iris数据集

python实现,遍历所有数据点,找出n个距离最近的点的分类情况,少数服从多数

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
%matplotlib inline

from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from collections import Counter

# data
iris = load_iris()
df = pd.DataFrame(iris.data, columns=iris.feature_names)
df['label'] = iris.target
df.columns = ['sepal length', 'sepal width', 'petal length', 'petal width', 'label']
# data = np.array(df.iloc[:100, [0, 1, -1]])
sepal lengthsepal widthpetal lengthpetal widthlabel
05.13.51.40.2
14.93.01.40.2
24.73.21.30.2
34.63.11.50.2
45.03.61.40.2
55.43.91.70.4
64.63.41.40.3
75.03.41.50.2
84.42.91.40.2
94.93.11.50.1
105.43.71.50.2
114.83.41.60.2
124.83.01.40.1
134.33.01.10.1
145.84.01.20.2
155.74.41.50.4
165.43.91.30.4
175.13.51.40.3
185.73.81.70.3
195.13.81.50.3
205.43.41.70.2
215.13.71.50.4
224.63.61.00.2
235.13.31.70.5
244.83.41.90.2
255.03.01.60.2
265.03.41.60.4
275.23.51.50.2
285.23.41.40.2
294.73.21.60.2
1206.93.25.72.3
1215.62.84.92.0
1227.72.86.72.0
1236.32.74.91.8
1246.73.35.72.1
1257.23.26.01.8
1266.22.84.81.8
1276.13.04.91.8
1286.42.85.62.1
1297.23.05.81.6
1307.42.86.11.9
1317.93.86.42.0
1326.42.85.62.2
1336.32.85.11.5
1346.12.65.61.4
1357.73.06.12.3
1366.33.45.62.4
1376.43.15.51.8
1386.03.04.81.8
1396.93.15.42.1
1406.73.15.62.4
1416.93.15.12.3
1425.82.75.11.9
1436.83.25.92.3
1446.73.35.72.5
1456.73.05.22.3
1466.32.55.01.9
1476.53.05.22.0
1486.23.45.42.3
1495.93.05.11.8

150 rows × 5 columns

plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')
plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()

在这里插入图片描述

data = np.array(df.iloc[:100, [0, 1, -1]])
X, y = data[:,:-1], data[:,-1]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)
class KNN:
    def __init__(self, X_train, y_train, n_neighbors=3, p=2):
        """
        parameter: n_neighbors 临近点个数
        parameter: p 距离度量
        """
        self.n = n_neighbors
        self.p = p
        self.X_train = X_train
        self.y_train = y_train

    def predict(self, X):
        # 取出n个点
        knn_list = []
        for i in range(self.n):
            dist = np.linalg.norm(X - self.X_train[i], ord=self.p)
            knn_list.append((dist, self.y_train[i]))

        for i in range(self.n, len(self.X_train)):
            max_index = knn_list.index(max(knn_list, key=lambda x: x[0]))
            dist = np.linalg.norm(X - self.X_train[i], ord=self.p)
            if knn_list[max_index][0] > dist:
                knn_list[max_index] = (dist, self.y_train[i])

        # 统计
        knn = [k[-1] for k in knn_list]
        count_pairs = Counter(knn)
#         max_count = sorted(count_pairs, key=lambda x: x)[-1]
        max_count = sorted(count_pairs.items(), key=lambda x: x[1])[-1][0]
        return max_count

    def score(self, X_test, y_test):
        right_count = 0
        n = 10
        for X, y in zip(X_test, y_test):
            label = self.predict(X)
            if label == y:
                right_count += 1
        return right_count / len(X_test)
clf = KNN(X_train, y_train)
clf.score(X_test, y_test)
==============================
0.95

test_point = [6.0, 3.0]
print('Test Point: {}'.format(clf.predict(test_point)))
=================================
Test Point: 1.0
plt.scatter(df[:50]['sepal length'], df[:50]['sepal width'], label='0')
plt.scatter(df[50:100]['sepal length'], df[50:100]['sepal width'], label='1')
plt.plot(test_point[0], test_point[1], 'bo', label='test_point')
plt.xlabel('sepal length')
plt.ylabel('sepal width')
plt.legend()

在这里插入图片描述

scikit-learn实例

from sklearn.neighbors import KNeighborsClassifier
clf_sk = KNeighborsClassifier()
clf_sk.fit(X_train, y_train)
======================================
KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski',
           metric_params=None, n_jobs=None, n_neighbors=5, p=2,
           weights='uniform')


clf_sk.score(X_test, y_test)
========================================
0.95

kd树:构造平衡kd树算法

# kd-tree每个结点中主要包含的数据结构如下
class KdNode(object):
    def __init__(self, dom_elt, split, left, right):
        self.dom_elt = dom_elt  # k维向量节点(k维空间中的一个样本点)
        self.split = split  # 整数(进行分割维度的序号)
        self.left = left  # 该结点分割超平面左子空间构成的kd-tree
        self.right = right  # 该结点分割超平面右子空间构成的kd-tree


class KdTree(object):
    def __init__(self, data):
        k = len(data[0])  # 数据维度

        def CreateNode(split, data_set):  # 按第split维划分数据集exset创建KdNode
            if not data_set:  # 数据集为空
                return None
            # key参数的值为一个函数,此函数只有一个参数且返回一个值用来进行比较
            # operator模块提供的itemgetter函数用于获取对象的哪些维的数据,参数为需要获取的数据在对象中的序号
            #data_set.sort(key=itemgetter(split)) # 按要进行分割的那一维数据排序
            data_set.sort(key=lambda x: x[split])
            split_pos = len(data_set) // 2  # //为Python中的整数除法
            median = data_set[split_pos]  # 中位数分割点
            split_next = (split + 1) % k  # cycle coordinates

            # 递归的创建kd树
            return KdNode(
                median,
                split,
                CreateNode(split_next, data_set[:split_pos]),  # 创建左子树
                CreateNode(split_next, data_set[split_pos + 1:]))  # 创建右子树

        self.root = CreateNode(0, data)  # 从第0维分量开始构建kd树,返回根节点


# KDTree的前序遍历
def preorder(root):
    print(root.dom_elt)
    if root.left:  # 节点不为空
        preorder(root.left)
    if root.right:
        preorder(root.right)
# 对构建好的kd树进行搜索,寻找与目标点最近的样本点:
from math import sqrt
from collections import namedtuple

# 定义一个namedtuple,分别存放最近坐标点、最近距离和访问过的节点数
result = namedtuple("Result_tuple",
                    "nearest_point  nearest_dist  nodes_visited")


def find_nearest(tree, point):
    k = len(point)  # 数据维度

    def travel(kd_node, target, max_dist):
        if kd_node is None:
            return result([0] * k, float("inf"),
                          0)  # python中用float("inf")和float("-inf")表示正负无穷

        nodes_visited = 1

        s = kd_node.split  # 进行分割的维度
        pivot = kd_node.dom_elt  # 进行分割的“轴”

        if target[s] <= pivot[s]:  # 如果目标点第s维小于分割轴的对应值(目标离左子树更近)
            nearer_node = kd_node.left  # 下一个访问节点为左子树根节点
            further_node = kd_node.right  # 同时记录下右子树
        else:  # 目标离右子树更近
            nearer_node = kd_node.right  # 下一个访问节点为右子树根节点
            further_node = kd_node.left

        temp1 = travel(nearer_node, target, max_dist)  # 进行遍历找到包含目标点的区域

        nearest = temp1.nearest_point  # 以此叶结点作为“当前最近点”
        dist = temp1.nearest_dist  # 更新最近距离

        nodes_visited += temp1.nodes_visited

        if dist < max_dist:
            max_dist = dist  # 最近点将在以目标点为球心,max_dist为半径的超球体内

        temp_dist = abs(pivot[s] - target[s])  # 第s维上目标点与分割超平面的距离
        if max_dist < temp_dist:  # 判断超球体是否与超平面相交
            return result(nearest, dist, nodes_visited)  # 不相交则可以直接返回,不用继续判断

        #----------------------------------------------------------------------
        # 计算目标点与分割点的欧氏距离
        temp_dist = sqrt(sum((p1 - p2)**2 for p1, p2 in zip(pivot, target)))

        if temp_dist < dist:  # 如果“更近”
            nearest = pivot  # 更新最近点
            dist = temp_dist  # 更新最近距离
            max_dist = dist  # 更新超球体半径

        # 检查另一个子结点对应的区域是否有更近的点
        temp2 = travel(further_node, target, max_dist)

        nodes_visited += temp2.nodes_visited
        if temp2.nearest_dist < dist:  # 如果另一个子结点内存在更近距离
            nearest = temp2.nearest_point  # 更新最近点
            dist = temp2.nearest_dist  # 更新最近距离

        return result(nearest, dist, nodes_visited)

    return travel(tree.root, point, float("inf"))  # 从根节点开始递归

例3.2

在这里插入图片描述

data = [[2,3],[5,4],[9,6],[4,7],[8,1],[7,2]]
kd = KdTree(data)
preorder(kd.root)
==================================
[7, 2]
[5, 4]
[2, 3]
[4, 7]
[9, 6]
[8, 1]
from time import clock
from random import random

# 产生一个k维随机向量,每维分量值在0~1之间
def random_point(k):
    return [random() for _ in range(k)]
 
# 产生n个k维随机向量 
def random_points(k, n):
    return [random_point(k) for _ in range(n)]
ret = find_nearest(kd, [3,4.5])
print (ret)
=========================================
Result_tuple(nearest_point=[2, 3], nearest_dist=1.8027756377319946, nodes_visited=4)
N = 400000
t0 = clock()
kd2 = KdTree(random_points(3, N))            # 构建包含四十万个3维空间样本点的kd树
ret2 = find_nearest(kd2, [0.1,0.5,0.8])      # 四十万个样本点中寻找离目标最近的点
t1 = clock()
print ("time: ",t1-t0, "s")
print (ret2)
=========================================
time:  5.4623788 s
Result_tuple(nearest_point=[0.09929288205798159, 0.4954936771850429, 0.8005722800665575], nearest_dist=0.004597223680778027, nodes_visited=42)

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

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

相关文章

把Windows系统装进U盘,到哪都有属于你自己的电脑系统

前言 自从接触到WinPE启动盘之后&#xff0c;小白就突然萌生了一个想法&#xff1a;为啥不能把完整的Windows放进U盘呢&#xff1f; 实际上Windows是可以安装进U盘的&#xff0c;外出的时候带上&#xff0c;只需要有台正常开机的电脑就可以使用属于自己的系统。 这个是早已经…

一分钟教你搭建《幻兽帕鲁》服务器

幻兽帕鲁是一款由Pocketpair开发的开放世界生存游戏&#xff0c;融合了多种玩法的游戏&#xff0c;其独特的题材和画风吸引了很多玩家&#xff0c;越来越多的玩家开始尝试自己搭建服务器&#xff0c;享受更加自由的游戏体验。本文将为大家详细介绍如何从零开始搭建《幻兽帕鲁》…

「 网络安全常用术语解读 」杀链Kill Chain详解

1. 简介 早在2009年&#xff0c;Lockheed Martin公司就提出了杀链(Kill Chain)理论&#xff0c;现在也称之为攻击者杀链(Attacker Kill Chain)。杀链其实就是攻击者进行网络攻击时所采取的步骤。杀链模型包括7个步骤&#xff1a;1侦察 -> 2武器化 -> 3交付 -> 4利用 …

java程序判等问题

注意 equals 和 的区别 对基本类型&#xff0c;比如 int、long&#xff0c;进行判等&#xff0c;只能使用 &#xff0c;比较的是直接值。因为基本类型的值就是其数值。对引用类型&#xff0c;比如 Integer、Long 和 String&#xff0c;进行判等&#xff0c;需要使用 equals 进…

【立创EDA-PCB设计基础】6.布线铺铜实战及细节详解

前言&#xff1a;本文进行布线铺铜实战及详解布线铺铜的细节 在本专栏中【立创EDA-PCB设计基础】前面完成了布线铺铜前的设计规则的设置&#xff0c;接下来进行布线 布局原则是模块化布局&#xff08;优先布局好确定位置的器件&#xff0c;例如排针、接口、主控芯片&#xff…

Sulfo Cy3 hydrazide,磺化-Cy3-酰肼,可用于与生物分子的羰基衍生物偶联

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;Sulfo-Cyanine3-hydrazide&#xff0c;Sulfo Cy3 hydrazide&#xff0c;Sulfo Cyanine3 HZ&#xff0c;磺化 Cy3 酰肼&#xff0c;磺化-Cy3-酰肼 一、基本信息 产品简介&#xff1a;Sulfo-Cyanine3-hydrazide能够与…

远程连接银河麒麟

目录 一、防火墙服务 二、安装SSH服务 1.验证SSH服务是否安装 2.安装SSH服务 三、启动SSH服务 四、远程连接 1.切换登录用户 2.查看IP地址 3.FinalShell连接 4.切换root用户 前言: 本篇主要讲述在Win10系统中通过FinalShell远程连接银河麒麟桌面操作系统V10 一、防火…

android studio从空白开始

对我来说&#xff0c;真正的第一步是清理电脑C盘。从剩余8G清理到25G&#xff0c;把原来看不顺眼又不敢删的文件夹和软件全删了&#xff0c;删爽了的后果就是&#xff0c;用两天的时间在把一些环境配置慢慢装回来&#xff0c;node.js&#xff0c;jdk&#xff0c;npm。努力把它们…

零基础学习【Mybatis Plus】这一篇就够了

学习目录 1. 快速入门1-1. 常用注解总结 1-2. 常用配置 2. 核心功能3. 扩展功能4. 插件功能 1. 快速入门 1-1. 常用注解 MybatisPlus中比较常用的几个注解如下&#xff1a; TableName: 用来指定表名Tableld: 用来指定表中的主键字段信息TableField: 用来指定表中的普通字段信…

Excel·VBA时间范围筛选及批量删除整行

看到一个帖子《excel吧-筛选开始时间&#xff0c;结束时间范围内的所有记录》&#xff0c;根据条件表中的开始时间和结束时间构成的时间范围&#xff0c;对数据表中的开始时间和结束时间范围内的数据进行筛选 目录 批量删除整行&#xff0c;整体删除批量删除整行&#xff0c;分…

[每日一题] 01.24 - 求三角形

求三角形 n int(input()) count1 (1 n) * n // 2 count2 n * n lis1 [str(i).zfill(2) for i in range(1,count1 1)] lis2 [str(i).zfill(2) for i in range(1,count2 1)]for i in range(0,len(lis2),n):print(.join(lis2[i:i n]))print()for i in range(1,n 1):tem…

Vue+Element(el-upload+el-form的使用)+springboot

目录 1、编写模板 2、发请求调接口 3、后端返回数据 1.编写实体类 2.Controller类 3、interface接口&#xff08;Service层接口&#xff09; 4.Service&#xff08;接口实现&#xff09; 5、interface接口&#xff08;Mapper层接口&#xff09; 6、xml 4、upload相关参…

微信小程序之全局配置-window和tabBar

学习的最大理由是想摆脱平庸&#xff0c;早一天就多一份人生的精彩&#xff1b;迟一天就多一天平庸的困扰。各位小伙伴&#xff0c;如果您&#xff1a; 想系统/深入学习某技术知识点… 一个人摸索学习很难坚持&#xff0c;想组团高效学习… 想写博客但无从下手&#xff0c;急需…

抖捧AI实景自动直播怎么玩

​在如今的全民直播时代&#xff0c;直播已经成为了众多实体店、品牌方所刚需的技能&#xff0c;但是大多数都不具备太多的直播能力 &#xff0c;这个时候实景自动直播就应运而生&#xff0c;但是很多人都没有想清楚&#xff0c;AI实景自动直播&#xff0c;到底适不适合自己用呢…

使用官方标定工具Dynamic Calibrator对RealSense D435i进行标定(二)

工具的安装教程可以看我的上一篇博文&#xff1a;Ubuntu 18.04安装Dynamic Calibration software for the Intel RealSense™ D400 Series Cameras&#xff08;一&#xff09; 使用教程参考user guide&#xff1a;https://www.intel.com/content/www/us/en/support/articles/0…

2023春秋杯冬季赛 --- Crypto wp

文章目录 前言Cryptonot_wiener 前言 比赛没打&#xff0c;赛后随便做一下题目 Crypto not_wiener task.py: from Crypto.Util.number import * from gmpy2 import * import random, os from hashlib import sha1 from random import randrange flagb x bytes_to_long(f…

IO 专题

使用try-with-resources语句块&#xff0c;可以自动关闭InputStream [实践总结] FileIUtils 共通方法最佳实践 [实践总结] java 获取在不同系统下的换行符 [实践总结] StreamIUtils 共通方法最佳实践 斜杠“/“和反斜杠“\“的区别 路径中“./”、“…/”、“/”代表的含义…

MySql索引事务讲解和(经典面试题)

&#x1f3a5; 个人主页&#xff1a;Dikz12&#x1f525;个人专栏&#xff1a;MySql&#x1f4d5;格言&#xff1a;那些在暗处执拗生长的花&#xff0c;终有一日会馥郁传香欢迎大家&#x1f44d;点赞✍评论⭐收藏 目录 索引 概念 索引的相关操作 索引内部数据结构 事务 为…

容联七陌x新飞电器|升级高效智能客服,实现满意度跃升新台阶

随着电商兴起&#xff0c;电器行业深入到各大电子商务平台&#xff0c;订单量、咨询量也随之增长&#xff0c;对及时响应、准确回答、高效解决、提高服务品质等需求逐渐增加。 新飞电器选择了与容联七陌合作企业版在线客服产品&#xff0c;共同打造高效、便捷、个性化的优质客…

达梦数据库增删改查常用操作及-2723: 仅当指定列列表,且SET IDENTITY_INSERT为ON时,才能对自增列赋值问题修复

创建表 CREATE TABLE DICT ( "ID" INT IDENTITY(1, 1) NOT NULL, "TYPE" VARCHAR(30), "CODE" BIGINT, "NAME" VARCHAR(300), "VALUE" VARCHAR(200), "DESCRIPTION" VARCHAR(255), "OPERATOR"…