(6) 聚类算法KMeans(案例:矢量量化的降维)

news2025/7/7 13:37:49

文章目录

  • 理论知识
  • 1 sklearn.cluster.KMeans
    • 1.1 参数n_clusters
      • 1.1.1 小试牛刀
      • 1.1.2 模型评估指标
        • 轮廓系数
        • Calinski-Harabaz Index
      • 1.1.3 案例:基于轮廓系数来选择n_clusters
    • 1.2 参数init & random_state & n_init:初始质心怎么放好?
    • 1.3 重要参数max_iter & tol:让迭代停下来
    • 1.4 重要属性与重要接口
    • 1.5 函数cluster.k_means
  • 2 案例:聚类算法用于降维,KMeans的矢量量化应用

文章内容参考于该B站up主

理论知识

无监督学习是机器学习中的一种方法,其目的是从未标记的数据中发现隐藏的模式和结构。在无监督学习中,分类任务被视为聚类任务,因为数据点通常被标记为类别而不是聚类

聚类是一种无监督学习方法,它将数据集中的相似数据点归为一类。聚类算法尝试找到数据点之间的相似性,并将它们分组以形成一个簇。簇可以是单独的点或由多个点组成的图形。

以下是几种常见的聚类算法:

  1. K 均值聚类 (K-means Clustering):K 均值聚类是一种基于距离的聚类算法。它将根据数据点之间的相似性将数据点分为 K 个簇。该算法的主要目标是最小化簇内之间的距离和最大化簇间之间的距离
  2. 层次聚类 (Hierarchical Clustering):层次聚类是一种自下而上的聚类方法。该算法通过逐步合并相似性的簇来构建簇的结构。该方法可以用于生成聚类层次树,该树可以用于进一步的分类和预测。
  3. 密度聚类 (Density-Based Clustering):密度聚类是一种基于密度的聚类方法。该算法通过将密集区域与稀疏区域分离来确定簇。该方法可以用于发现数据集中的潜在簇,并且可以处理高维数据。
  4. 谱聚类 (Spectral Clustering):谱聚类是一种基于图论的聚类方法。该算法使用相似性矩阵来表示数据点之间的相似性,并将其转换为拉普拉斯矩阵来进行聚类。该方法可以用于处理高维数据和非高斯分布的数据。

image-20230418181557419

image-20230418181654865

无监督学习的一个主要优点是不需要事先知道数据点的类别或标签。因此,它可以用于发现数据集中的潜在结构和模式,并且可以应用于各种领域,如数据挖掘、图像识别、自然语言处理和推荐系统等。

K 均值聚类是一种经典的基于距离的聚类算法,它的目标是将数据点分为 K 个簇。以下是 K 均值聚类的工作过程:

  1. 初始化聚类中心:首先,K 均值聚类将随机选择 K 个数据点作为初始聚类中心。这些聚类中心将作为后续聚类的中心点。
  2. 计算距离:K 均值聚类计算每个数据点到聚类中心的距离,并将每个数据点分配到最近的聚类中心。
  3. 重新计算聚类中心:K 均值聚类根据新的数据点分配重新计算每个簇的聚类中心。
  4. 重复步骤 2 和 3,直到收敛为止:K 均值聚类重复步骤 2 和 3,直到聚类中心不再改变或达到预定的停止条件为止。
  5. 确定簇:K 均值聚类根据聚类中心的位置将数据点分配到相应的簇中。
  6. 重复步骤 2-5,直到收敛为止:K 均值聚类不断重复上述步骤,直到聚类中心和数据点分配保持不变或达到预定的停止条件为止。

K 均值聚类的输出是聚类中心点的位置和聚类的数量。这些聚类中心点可以用作后续分类或聚类的基准

image-20230418182144348

image-20230418182233412

image-20230418182305084

1 sklearn.cluster.KMeans

class sklearn.cluster.KMeans (n_clusters=8, init=’k-means++’, n_init=10, max_iter=300, tol=0.0001,precompute_distances=’auto’, verbose=0, random_state=None, copy_x=True, n_jobs=None, algorithm=’auto’)

1.1 参数n_clusters

n_clusters是KMeans中的k,表示着我们告诉模型我们要分几类。这是KMeans当中唯一一个必填的参数,默认为8类,但通常我们的聚类结果会是一个小于8的结果。通常,在开始聚类之前,我们并不知道n_clusters究竟是多少,因此我们要对它进行探索。

1.1.1 小试牛刀

当我们拿到一个数据集,如果可能的话,我们希望能够通过绘图先观察一下这个数据集的数据分布,以此来为我们聚类时输入的n_clusters做一个参考。

首先,我们来自己创建一个数据集。这样的数据集是我们自己创建,所以是有标签的。

from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt

X, y = make_blobs(n_samples=500, n_features=2, centers=4, random_state=1)
fig, ax1 = plt.subplots(1)
ax1.scatter(X[:, 0], X[:, 1], marker='o', s=10)  # 点的形状为圆形,大小为10
plt.show()

output_4_0

初步看数据大概有4簇。因为这个数据集我们已知其标签,所以如果想要好看点,可以根据不同y加上不同颜色:

color = ["red", "pink", "orange", "gray"]
fig, ax1 = plt.subplots(1)
for i in range(4):
    ax1.scatter(X[y == i, 0], X[y == i, 1], marker='o', s=10, c=color[i])  # 点的形状为圆形,大小为10
plt.show()

output_6_0

接下来使用Kmeans进行聚类。

from sklearn.cluster import KMeans

n_clusters = 3
cluster = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
# KMeans因为并不需要建立模型或者预测结果,因此只需要fit就能够得到聚类结果了
y_pred = cluster.labels_  # 查看每个样本所聚好的类别

执行上述代码时系统会有警告信息,如果你不介意可以不管,不影响后面执行;介意的话,可以参考解决方案。

pre = cluster.fit_predict(X)  # 也可直接用fit_predict一步到位,跟上面是一样的效果
(pre == y_pred).sum()  # 理所当然为500
500

KMeans还有个predict,什么时候使用:数据量很大时,因为此时我们不必使用所有数据来确定质心可以使用部分数据fit后,再用predict去预测剩余的大量数据,尽管会有一些数据聚类错误,但当不要求那么精确时,可以节省时间

cluster_smallsub = KMeans(n_clusters=n_clusters, random_state=0).fit(X[:250])  # 使用部分样本进行训练
y_pred_ = cluster_smallsub.predict(X)
(y_pred == y_pred_).sum()  # 可见使用部分数据训练再predict其他数据时会有一些数据聚类错误
125

cluster_centers_查看质心坐标

centroid = cluster.cluster_centers_
centroid

inertia_查看总距离平方和

inertia = cluster.inertia_
inertia
1903.5607664611762

查看聚类的图像结果:

color = ["red", "pink", "orange", "gray"]
fig, ax1 = plt.subplots(1)
for i in range(n_clusters):
    ax1.scatter(X[y_pred == i, 0], X[y_pred == i, 1], marker='o', s=8, c=color[i])
ax1.scatter(centroid[:, 0], centroid[:, 1], marker='x', s=15, c="black")
plt.show()

output_18_0

如果增大簇数呢?

inertia_list = []
for n_clusters in range(3, 100):
    cluster_ = KMeans(n_clusters=n_clusters, random_state=0).fit(X)
    inertia_ = cluster_.inertia_
    inertia_list.append(inertia_)
plt.plot(inertia_list)
plt.show()

output_2099_0

可以发现随着簇数n_clusters增加,inertia逐渐减少(通过常识也知道,质心越多,总距离平方和越小),但并不代表它越小模型效果就越好。

1.1.2 模型评估指标

不同于分类模型和回归,聚类算法的模型评估不是一件简单的事。在分类中,有直接结果(标签)的输出,并且分类的结果有正误之分,所以我们使用预测的准确度,混淆矩阵,ROC曲线等等指标来进行评估,但无论如何评估,都是在”模型找到正确答案“的能力。而回归中,由于要拟合数据,我们有SSE均方误差,有损失函数来衡量模型的拟合程度。但这些衡量指标都不能够使用于聚类。

轮廓系数

image-20230418182958318

在sklearn中,我们使用模块metrics中的类silhouette_score来计算轮廓系数,它返回的是一个数据集中,所有样本的轮廓系数的均值。但我们还有同在metrics模块中的silhouette_sample,它的参数与轮廓系数一致,但返回的是数据集中每个样本自己的轮廓系数

我们来看看轮廓系数在我们自建的数据集上表现如何:

from sklearn.metrics import silhouette_score
from sklearn.metrics import silhouette_samples

X  # (500,2)
y_pred  # 每个样本所聚好的类别

# 返回一个数据集中,所有样本的轮廓系数的均值
silhouette_score(X, y_pred)  # 0.5882004012129721

# 返回数据集中每个样本自己的轮廓系数
silhouette_samples(X, y_pred)

轮廓系数有很多优点,它在有限空间中取值,使得我们对模型的聚类效果有一个“参考”。并且,轮廓系数对数据的分布没有假设,因此在很多数据集上都表现良好。但它在每个簇的分割比较清洗时表现最好。但轮廓系数也有缺陷,它在凸型的类上表现会虚高,比如基于密度进行的聚类,或通过DBSCAN获得的聚类结果,如果使用轮廓系数来衡量,则会表现出比真实聚类效果更高的分数。

Calinski-Harabaz Index

image-20230418183235322

from sklearn.metrics import calinski_harabasz_score

calinski_harabasz_score(X, y_pred)  # 1809.991966958033

虽然calinski-Harabaz指数没有界,在凸型的数据上的聚类也会表现虚高。但是比起轮廓系数,它有一个巨大的优点,就是计算非常快速。之前使用过魔法命令%%timeit来计算一个命令的运算时间,这次来选择另一种方法:时间戳计算运行时间。

from time import time

t0 = time()
calinski_harabasz_score(X, y_pred)
time() - t0

t1 = time()
silhouette_score(X, y_pred)
time() - t1

import datetime

# 转换成人看的懂时间
datetime.datetime.fromtimestamp(t0).strftime("%Y-%m-%d %H:%M:%S")
'2023-04-09 01:01:19'

可以看得出,calinski-harabaz指数比轮廓系数的计算块了一倍不止。如果使用的数据量是一个以万计的数据,使用轮廓系数就会大大拖慢我们模型的运行速度。

1.1.3 案例:基于轮廓系数来选择n_clusters

我们通常会绘制轮廓系数分布图和聚类后的数据分布图来选择我们的最佳n_clusters。绘图过程比较难,立即推,学习到两点!

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
import matplotlib.pyplot as plt
import numpy as np
import matplotlib.cm as cm

n_clusters = 4
fig, (ax1, ax2) = plt.subplots(1, 2)
fig.set_size_inches(18, 7)  #画布尺寸
#第一个图横坐标是轮廓系数,纵坐标是各个样本,每个簇是一条
ax1.set_xlim([-0.1, 1])
ax1.set_ylim([0, X.shape[0] + (n_clusters + 1) * 10])

#开始建模
clusterer = KMeans(n_clusters=n_clusters, random_state=10).fit(X)
cluster_labels = clusterer.labels_  #聚类结果:标签值

#总的轮廓系数
silhouette_avg = silhouette_score(X, cluster_labels)
print("For n_clusters =", n_clusters, "The average silhouette_score is :",
      silhouette_avg)

#每个样本点的轮廓系数,这就是横坐标
sample_silhouette_values = silhouette_samples(X, cluster_labels)

y_lower = 10  #设定图像最低水平线

#对每一个簇进行循环
for i in range(n_clusters):
    #从每个样本的轮廓系数结果中抽取第i个簇的轮廓系数,并进行排序
    ith_cluster_silhouette_values = sample_silhouette_values[cluster_labels == i]
    ith_cluster_silhouette_values.sort()  #排序,为了图像好看,从小到大
    size_cluster_i = ith_cluster_silhouette_values.shape[0]  #查看这一个簇中有多少个样本
    y_upper = y_lower + size_cluster_i
    color = cm.nipy_spectral(float(i) / n_clusters)
    #填充子图1
    ax1.fill_betweenx(np.arange(y_lower, y_upper),  # 范围内柱状图统一颜色
                      ith_cluster_silhouette_values,  # 柱状图横坐标
                      facecolor=color,
                      alpha=0.7)
    ax1.text(-0.05, y_lower + 0.5 * size_cluster_i, str(i))  #编号

    y_lower = y_upper + 10

ax1.set_title("The silhouette plot for the various clusters.")
ax1.set_xlabel("The silhouette coefficient values")
ax1.set_ylabel("Cluster label")

#把全体样本平均轮廓系数显示在图中
ax1.axvline(x=silhouette_avg, color="red", linestyle="--")
ax1.set_yticks([])

#第二个图
colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters)
ax2.scatter(X[:, 0], X[:, 1], marker='o', s=8, c=colors)

#把生成的质心放到图中
centers = clusterer.cluster_centers_
ax2.scatter(centers[:, 0], centers[:, 1], marker='x', c='red', alpha=1, s=200)

ax2.set_title("The visualization of the clustered data.")
ax2.set_xlabel("Feature space for the 1st feature")
ax2.set_ylabel("Feature space for the 2nd feature")

plt.suptitle(("Silhouette analysis for KMeans clustering on sample data "
              "with n_clusters = %d" % n_clusters),
             fontsize=14,
             fontweight='bold')
plt.show()
For n_clusters = 4 The average silhouette_score is : 0.6505186632729437

output_32_1

将上述过程包装成一个循环,可以得到:

from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np

for n_clusters in [2, 3, 4, 5, 6, 7]:
    n_clusters = n_clusters
    fig, (ax1, ax2) = plt.subplots(1, 2)
    fig.set_size_inches(18, 7)
    ax1.set_xlim([-0.1, 1])
    ax1.set_ylim([0, X.shape[0] + (n_clusters + 1) * 10])
    clusterer = KMeans(n_clusters=n_clusters, random_state=10).fit(X)
    cluster_labels = clusterer.labels_
    silhouette_avg = silhouette_score(X, cluster_labels)
    print("For n_clusters =", n_clusters, "The average silhouette_score is :",
          silhouette_avg)
    sample_silhouette_values = silhouette_samples(X, cluster_labels)
    y_lower = 10

    for i in range(n_clusters):
        ith_cluster_silhouette_values = sample_silhouette_values[cluster_labels
                                                                 == i]
        ith_cluster_silhouette_values.sort()
        size_cluster_i = ith_cluster_silhouette_values.shape[0]
        y_upper = y_lower + size_cluster_i
        color = cm.nipy_spectral(float(i) / n_clusters)
        ax1.fill_betweenx(np.arange(y_lower, y_upper),
                          ith_cluster_silhouette_values,
                          facecolor=color,
                          alpha=0.7)
        ax1.text(-0.05, y_lower + 0.5 * size_cluster_i, str(i))
        y_lower = y_upper + 10

    ax1.set_title("The silhouette plot for the various clusters.")
    ax1.set_xlabel("The silhouette coefficient values")
    ax1.set_ylabel("Cluster label")
    ax1.axvline(x=silhouette_avg, color="red", linestyle="--")
    ax1.set_yticks([])
    ax1.set_xticks([-0.1, 0, 0.2, 0.4, 0.6, 0.8, 1])

    colors = cm.nipy_spectral(cluster_labels.astype(float) / n_clusters)
    ax2.scatter(X[:, 0], X[:, 1], marker='o', s=8, c=colors)
    centers = clusterer.cluster_centers_
    # Draw white circles at cluster centers
    ax2.scatter(centers[:, 0], centers[:, 1], marker='x', c="red", alpha=1, s=200)
    ax2.set_title("The visualization of the clustered data.")
    ax2.set_xlabel("Feature space for the 1st feature")
    ax2.set_ylabel("Feature space for the 2nd feature")
    plt.suptitle(("Silhouette analysis for KMeans clustering on sample data "
                  "with n_clusters = %d" % n_clusters),
                 fontsize=14,
                 fontweight='bold')
plt.show()
For n_clusters = 2 The average silhouette_score is : 0.7049787496083262
For n_clusters = 3 The average silhouette_score is : 0.5882004012129721
For n_clusters = 4 The average silhouette_score is : 0.6505186632729437
For n_clusters = 5 The average silhouette_score is : 0.56376469026194
For n_clusters = 6 The average silhouette_score is : 0.4504666294372765
For n_clusters = 7 The average silhouette_score is : 0.39092211029930857

output_34_1

output_34_2

output_34_3

output_34_4

output_34_5

output_34_6

由此可知,分2簇和4簇都是可以的,那么到底分几簇呢?这时就需要结合具体业务和目的去决定了。

1.2 参数init & random_state & n_init:初始质心怎么放好?

image-20230418183601415

from time import time

t0 = time()
plus = KMeans(n_clusters=10).fit(X)  # init默认为k-means++
print(plus.n_iter_)  # 迭代次数
print(time() - t0)  # 迭代次数少,但时间长(使用k-means++会有个计算过程)
16
0.5312621593475342
t0 = time()
random = KMeans(n_clusters=10, init="random", random_state=420).fit(X)  #init设置random比较一下
print(random.n_iter_)
print(time() - t0)  # 迭代次数多,但时间短
19
0.4864046573638916

1.3 重要参数max_iter & tol:让迭代停下来

在之前描述K-Means的基本流程时我们提到过,当质心不再移动,Kmeans算法就会停下来。但在完全收敛之前,我们也可以使用max_iter,最大迭代次数,或者tol,两次迭代间Inertia下降的量,这两个参数来让迭代提前停下来。有时候,当我们的n_clusters选择不符合数据的自然分布,或者我们为了业务需求,必须要填入与数据的自然分布不合的n_clusters,提前让迭代停下来反而能够提升模型的表现。

max_iter:整数,默认300,单次运行的k-means算法的最大迭代次数

tol:浮点数,默认1e-4,两次迭代间Inertia下降的量,如果两次迭代之间Inertia下降的值小于tol所设定的值,迭代就会停下

from sklearn.metrics import silhouette_samples, silhouette_score

random = KMeans(n_clusters=10, init="random", max_iter=10, random_state=420).fit(X)
y_pred_max10 = random.labels_
silhouette_score(X, y_pred_max10)  # 轮廓系数均值,越接近1越好
0.3952586444034157
random = KMeans(n_clusters=10, init="random", max_iter=20, random_state=420).fit(X)
y_pred_max20 = random.labels_
silhouette_score(X, y_pred_max20)
0.3401504537571701

以上可以看出有时候迭代次数大,模型效果还不一定好,故某些情况让模型提前停下来反而会提升模型效果。

1.4 重要属性与重要接口

image-20230418183704857

1.5 函数cluster.k_means

sklearn.cluster.k_means (X, n_clusters, sample_weight=None, init=’k-means++’, precompute_distances=’auto’,n_init=10, max_iter=300, verbose=False, tol=0.0001, random_state=None, copy_x=True, n_jobs=None,algorithm=’auto’, return_n_iter=False)

聚类算法Kmeans函数k_means的用法其实和类非常相似,不过函数是输入一系列值,而直接返回结果。一次性地,函数k_means会依次返回质心,每个样本对应的簇的标签,inertia以及最佳迭代次数。

from sklearn.cluster import k_means

k_means(X, 4, return_n_iter=True)

2 案例:聚类算法用于降维,KMeans的矢量量化应用

image-20230418183736572

1.导入需要的库

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.datasets import load_sample_image  # 加载图片
from sklearn.utils import shuffle  # 打乱数据
from sklearn.metrics import pairwise_distances_argmin  # 计算最近的质心

2.导入数据,探索数据

china = load_sample_image("china.jpg")
plt.figure(figsize=(15, 15))
plt.imshow(china)
# china
# china.shape  #(427, 640, 3), 427行,640列,3个通道
# china.dtype  # dtype('uint8'), 0-255, 8位无符号整数
# 对于灰度图像,每个像素点只包含一个 8 位无符号整数,用于表示灰度值。因此,灰度图像的数据类型通常称为“uint8”或“unsigned char”
newimage = china.reshape((427 * 640, 3))  #将图片转换为427*640行,3列的数据,每一行代表一个像素点的RGB值

import pandas as pd

pd.DataFrame(newimage).drop_duplicates().shape  #查看图片中有多少种颜色

flower = load_sample_image("flower.jpg")
plt.figure(figsize=(15, 15))
plt.imshow(flower)
plt.show()

output_5200_0

output_52_1

图像探索完毕,我们了解了,图像现在有9W多种颜色。我们希望来试试看,能否使用K-Means将颜色压缩到64种,还不严重损耗图像的质量。为此,我们要使用K-Means来将9W种颜色聚类成64类,然后使用64个簇的质心来替代全部的9W种颜色,记得质心有着这样的性质:簇中的点都是离质心最近的样本点。为了比较,我们还要画出随机压缩到64种颜色的矢量量化图像。我们需要随机选取64个样本点作为随机质心,计算原数据中每个样本到它们的距离来找出离每个样本最近的随机质心,然后用每个样本所对应的随机质心来替换原本的样本。两种状况下,我们观察图像可视化之后的状况,以查看图片信息的损失。在这之前,我们需要把数据处理成sklearn中的K-Means类能够接受的数据。

3. 决定超参数,数据预处理

n_clusters = 64
# 将图片数据转换为浮点数,且将数据缩放到0-1之间
china = np.array(china, dtype=np.float64) / china.max()
w, h, d = original_shape = tuple(china.shape)  # 427, 640, 3
assert d == 3  # 保证图片是RGB三通道的。assert 是一个 Python 内置函数,用于在代码块中抛出一个断言,以便在代码执行期间检查条件是否成立。
# 将图片数据转换为427*640行,3列的数据
image_array = np.reshape(china, (w * h, d))
# image_array
# image_array.shape # (273280, 3)

4.对数据进行K-Means的矢量量化

image_array_sample = shuffle(image_array, random_state=0)[:1000]  # 打乱数据,取前1000个样本
kmeans = KMeans(n_clusters=n_clusters, random_state=0).fit(image_array_sample)
# kmeans.cluster_centers_.shape  # (64, 3)

labels = kmeans.predict(image_array)
# labels.shape  # (273280,)

image_kmeans = image_array.copy()
for i in range(w * h):
    image_kmeans[i] = kmeans.cluster_centers_[labels[i]]  # 将每个样本点替换为对应质心的值
# image_kmeans
# pd.DataFrame(image_kmeans).drop_duplicates().shape  # (64, 3), 64种颜色

image_kmeans = np.reshape(image_kmeans, (w, h, d))  # 将数据转换为427行,640列,3通道的数据
# image_kmeans.shape  # (427, 640, 3)

5.对数据进行随机矢量量化

centroid_random = shuffle(image_array, random_state=0)[:n_clusters]  # 随机选取64个样本点作为随机质心
# 计算原数据中每个样本到它们的距离来找出离每个样本最近的随机质心
labels_random = pairwise_distances_argmin(centroid_random, image_array, axis=0)
# labels_random.shape # (273280,)
# len(set(labels_random)) # 64, 64个质心, 64种颜色
image_random = image_array.copy()
for i in range(w * h):
    image_random[i] = centroid_random[labels_random[i]]
image_random = image_random.reshape(w, h, d)
# image_random.shape # (427, 640, 3)

6.将原图,按KMeans矢量量化和随机矢量量化的图像绘制出来

plt.figure(figsize=(10,10))
plt.axis('off') # 不显示坐标轴
plt.title('Original image (96,615 colors)')
plt.imshow(china)
plt.figure(figsize=(10,10))
plt.axis('off')
plt.title('Quantized image (64 colors, K-Means)')
plt.imshow(image_kmeans)
plt.figure(figsize=(10,10))
plt.axis('off')
plt.title('Quantized image (64 colors, Random)')
plt.imshow(image_random)
plt.show()

output_61_223241

output_61_ii2

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

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

相关文章

二:伙伴系统

内核空间内存分配 目录 内核空间内存分配 伙伴系统 首先从内核空间开始,讲解内存管理模式。 主要分为三种方式: 这篇文章我们集中注意于伙伴系统 伙伴系统 解决了外部碎片问题,针对大块内存分配设计 Linux中的内存管理的“页”大小为4…

java中使用Redis实现分布式锁

前言 目前很多大型的互联网公司后端都采用了分布式架构来支撑前端应用,其中服务拆分就是分布式的一种体现,既然服务拆分了,那么多个服务协调工作就会出现一些资源竞争的情况。比如多个服务对同一个表中的数据进行处理。容易出现类似多线程的…

linux中,和,|和||区别

1、& 表示任务在后台执行,比如运行一个jar文件,但是希望是后台运行可以执行 java -jar test.jar & 2、&& 表示前一条命令执行成功时,才执行后一条命令 ,如 echo step1‘ && echo ‘step2’ step1执行成功…

Java语法理论和面经杂疑篇《十二. JDK8 - 17新特性》

第18章_JDK8-17新特性(下) 6. 新语法结构 新的语法结构,为我们勾勒出了 Java 语法进化的一个趋势,将开发者从复杂、繁琐的低层次抽象中逐渐解放出来,以更高层次、更优雅的抽象,既降低代码量,又…

美颜SDK的优化方法:实现高效、快速、精准的美颜处理

时下,美颜相机、美颜软件等美颜处理应用也越来越受到用户的欢迎。美颜SDK是一种为移动应用提供美颜处理能力的开发工具包,可以帮助开发者快速实现美颜功能,提升应用的用户体验。但是,如何实现高效、快速、精准的美颜处理&#xff…

【spring-boot-seckill分布式秒杀系统 v1.0】java秒杀系统源码

spring-boot-seckill分布式秒杀系统是一个用SpringBoot开发的从0到1构建的分布式秒杀系统,项目案例基本成型,逐步完善中。 开发环境: JDK1.8、Maven、Mysql、IntelliJ IDEA、SpringBoot1.5.10、zookeeper3.4.6、kafka_2.11、redis-2.8.4、cur…

设计模式-创建型模式之抽象工厂模式(Abstract Factory)

4.抽象工厂模式(Abstract Factory)4.1. 模式动机在工厂方法模式中具体工厂负责生产具体的产品,每一个具体工厂对应一种具体产品,工厂方法也具有唯一性,一般情况下,一个具体工厂中只有一个工厂方法或者一组重载的工厂方法。但是有时…

项目制作-3

今天是好日子呀解决了 文件的问题(未测试) 完成了更多的界面的设计 对基本的模块有了更多的完成度 又学习了easyx图形库的一些的应用 一起来看看吧 void menu() {initgraph(640, 800, 0);IMAGE img;loadimage(&img, "C:\\Users\\唐怡佳\\Desktop\\图1.jpg"…

sql实践-01

CREATE DATABASE 人员管控; SHOW DATABASES; use 人员管控; 创建表 CREATE TABLE 住宿人员 ( 身份证号 CHAR(18) NOT NULL PRIMARY KEY, 姓名 VARCHAR(10) NOT NULL, 性别 CHAR(1) NOT NULL, 出生日期 DATE, 户籍 VARCHAR(30), 文化程度 VARCHAR(10), 婚姻状况 CHAR(…

装上这个插件,你就能一键生成接口文档

当有接口对接需求的时候,开发终于不用再担心 API 文档难写了,也不用再一个个接口文档重新写!安装这个 IDEA 插件,可以一步将文档导入到 Postcat。 这款插件操作简单,容易上手,能够让开发者省去API文档编写的…

TypeError: Cannot handle this data type: (1, 1, 33980), |u1

Image.fromarray报错解决 1. 报错信息2. 解决 相关文章 Image.fromarray()详细用法 1. 报错信息 TypeError: Cannot handle this data type: (1, 1, 33980), |u1 2. 解决 报错原因 图片mode格式问题moasic是灰度图片得到的【mode为L】,numpy【值只有0,和255】且…

shell编程入门 第一章 基本语法

shell编程的语法主要分为五个环节,分别是变量,字符串,运算符,流程控制,函数五大部分 shell编程的基础语法 一 变量1.1 shell变量名1.2 使用shell变量1.3只读变量1.4 删除变量 二 字符串2.1 定义时最好用双引号2.2获取字…

EMC 电路设计基础

EMC 在 JIS 中被定义为“电磁兼容性”,意为“不对其他设备产生电磁干扰,即使受到来自其他设备的电磁干扰,仍能保持原有的性能”,也就是具备相互兼顾兼容的性质。 EMC 大致分为 EMI(电磁干扰)和 EMS&#x…

Chinese-LangChain:基于ChatGLM-6b+langchain实现本地化知识库检索与智能答案生成

Chinese-LangChain Chinese-LangChain:中文langchain项目,基于ChatGLM-6blangchain实现本地化知识库检索与智能答案生成 https://github.com/yanqiangmiffy/Chinese-LangChain 俗称:小必应,Q.Talk,强聊,Qi…

python中的logging模块:从入门到高阶

简单使用 在 Python 中,可以使用内置的 logging 模块来记录应用程序的信息。最简单的用法是使用 basicConfig() 函数配置 logging 模块,然后使用 getLogger() 方法创建一个 Logger 对象,用于记录信息。下面是一个简单的例子: im…

基于html+css的图片展示16

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

No.043<软考>《(高项)备考大全》【第26章】软件工程国家标准

【第26章】软件工程国家标准 1 章节相关1.1 考试相关 2 标准2.1 标准级别及目录 3 软件工程术语4 软件生存周期过程、活动和任务4.1 必背4.2 ★软件生命周期各阶段与软件文档编制工作的关系--熟悉.4.3 各类人员与软件文档的使用关系--熟悉 5 文档控制5.1 SRS需求规格说明书 6 软…

一年一度的PMO大会将于2023年6月在京召开

企业要基业长青就必须持续保持组织活力。企业的内外部环境不会一成不变,顺应变化及时调整变革避免组织出现僵化低效才能在激烈的市场竞争中存活下来。PMO从成立到逐渐发挥越来越强的作用本身即是一种组织变革的过程,从这个意义上来说PMO因组织变革而生&a…

Nginx Rewrite

常用的Nginx正则表达式 ^:匹配输入字符串的起始位置 $ : 匹配输入字符串的结束位置 * : 匹配前面的字符零次或多次 :匹配前面的字符一次或多次 ?: 匹配前面的字符零次或一次 . : 匹配除“\n”之外的任何单个字符 ^$ : 空行 \:将后面…

百度发布Apollo城市智驾,距离AI智能驾驶还有多远?

推荐:将NSDT场景编辑器加入你的3D工具链。 工具集:NSDT简石数字孪生 随着人工智能技术的不断发展,智能驾驶已经成为了汽车行业的一个重要领域。智能驾驶可以减少人为驾驶的错误和疲劳驾驶等不安全因素,提高驾驶安全性&#xff0c…