机器学习实战-聚类算法

聚类算法是一种无监督学习的算法,用于将数据集中的数据分成不同的聚类或组。聚类算法是数据挖掘和机器学习领域中常见的技术之一,具有广泛的应用。 以下是聚类算法的一些知识点:

  1. 聚类算法的目的是将数据集划分为不同的组,使得组内的数据点相似度高,组间的相似度低。
  2. 聚类算法可以分为层次聚类和非层次聚类两种。层次聚类可以分为聚合聚类和分裂聚类两种。
  3. 常用的聚类算法包括K均值聚类、层次聚类、DBSCAN聚类等。其中,K均值聚类是最常见的聚类算法之一,它将数据集分为K个簇,每个簇的中心点被称为质心。
  4. 聚类算法的评价指标包括轮廓系数、Calinski-Harabasz指数、Davies-Bouldin指数等。
  5. 聚类算法的应用包括客户分群、文本聚类、图像分割等。
  6. 聚类算法的优化方法包括选择合适的聚类算法、确定合适的聚类簇数、选择合适的相似度度量等。
  7. 聚类算法的局限性包括需要事先确定聚类簇数、对初始质心的选择敏感、对异常值敏感等。

基于划分的聚类算法

K-Means 聚类算法

K-Means 聚类算法是一种非层次聚类算法,它将数据集分为K个簇,每个簇的中心点被称为质心。K-Means 算法的基本思想是通过不断迭代,将数据点划分到最近的质心所在的簇中,然后重新计算每个簇的质心,直到簇中心不再发生变化或达到最大迭代次数为止。

步骤:

  1. 随机的选取K个中心点,代表K个类别;
  2. 计算N个样本点和K个中心点之间的欧氏距离;
  3. 将每个样本点划分到最近的(欧氏距离最小的)中心点类别中——迭代1;
  4. 计算每个类别中样本点的均值,得到K个均值,将K个均值作为新的中心点——迭代2;
  5. 重复步骤2、3、4;
  6. 满足收敛条件后,得到收敛后的K个中心点(中心点不再变化)。

K-Means 聚类可以用欧式距离,欧式距离很简单,二维平面就是两个点的距离公式,在多维空间里,假设两个样本为 𝑎(𝑥1,𝑥2,𝑥3,𝑥4...𝑥𝑛) , 𝑏(𝑦1,𝑦2,𝑦3,𝑦4...𝑦𝑛) ,求两个样本的欧式距离。

欧式距离是两个样本之间的距离度量,它是最常用的距离度量方式之一。欧式距离指的是两个样本在 n 维空间中的坐标差的平方和的开方,即:

𝑑(𝑥,𝑦)=∑𝑖=1𝑛(𝑥𝑖−𝑦𝑖)2

其中, 和𝑥和𝑦 分别表示两个样本在 n 维空间中的坐标, 和𝑥𝑖和𝑦𝑖 分别表示两个样本在第 i 个维度上的坐标。

python代码实现:

#生成随机点
import matplotlib.pyplot as plt
import numpy as np
from sklearn.datasets.samples_generator import make_blobs
X, y_true = make_blobs(n_samples=300, centers=4,cluster_std=0.60, random_state=0)
plt.scatter(X[:, 0], X[:, 1], s=50)
plt.show()#K-Means 聚类算法
from sklearn.cluster import KMeans
"""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=1, algorithm='auto')Parameters:n_clusters: 聚类个数max_iter:  最大迭代数n_init:    用不同的质心初始化值运行算法的次数init:      初始化质心的方法precompute_distances:预计算距离tol:       关于收敛的参数n_jobs:    计算的进程数random_state: 随机种子copy_x:是否修改原始数据algorithm:“auto”, “full” or “elkan””full”就是我们传统的K-Means算法, “elkan”elkan K-Means算法。默认的”auto”则会根据数据值是否是稀疏的,来决定如何选择”full”和“elkan”,稠密的选 “elkan”,否则就是”full”Attributes:cluster_centers_:质心坐标Labels_: 每个点的分类 inertia_:每个点到其簇的质心的距离之和。 
"""
m_kmeans = KMeans(n_clusters=4)
from sklearn import metricsdef draw(m_kmeans,X,y_pred,n_clusters):centers = m_kmeans.cluster_centers_print(centers)plt.scatter(X[:, 0], X[:, 1], c=y_pred, s=50, cmap='viridis')#中心点(质心)用红色标出plt.scatter(centers[:, 0], centers[:, 1], c='red', s=200, alpha=0.5)print("Calinski-Harabasz score:%lf"%metrics.calinski_harabasz_score(X, y_pred) )plt.title("K-Means (clusters = %d)"%n_clusters,fontsize=20)plt.show()
m_kmeans.fit(X)
KMeans(algorithm='auto', copy_x=True, init='k-means++', max_iter=300,n_clusters=4, n_init=10, n_jobs=None, precompute_distances='auto',random_state=None, tol=0.0001, verbose=0)
y_pred = m_kmeans.predict(X)
draw(m_kmeans,X,y_pred,4)

K-Means 聚类算法升级

  1. K-Means++ 算法:K-Means++ 算法是 K-Means 算法的改进版,它通过改进初始质心的选择方式,提高了算法的聚类效果。K-Means++ 算法的初始质心选择方式是在数据集中随机选择一个点作为第一个质心,然后选择与前面已选质心距离最大的点作为下一个质心,直到选出 K 个质心。与 K-Means 算法相比,K-Means++ 算法的聚类效果更好,收敛速度更快。
  2. Mini-Batch K-Means 算法:Mini-Batch K-Means 算法是 K-Means 算法的一种变体,它采用了一种随机梯度下降的方式更新质心,从而加速了算法的收敛速度。Mini-Batch K-Means 算法将数据集划分为多个小批量,每个小批量包含一部分数据,然后在每个小批量上执行 K-Means 算法,更新质心。与 K-Means 算法相比,Mini-Batch K-Means 算法的计算速度更快,但聚类效果可能略有下降。
  3. K-Means++-C 算法:K-Means++-C 算法是一种基于 K-Means++ 算法的并行聚类算法,它可以加速大规模数据集的聚类过程。K-Means++-C 算法将数据集划分为多个子集,然后在每个子集上执行 K-Means++ 算法,得到每个子集的聚类结果。最后,将所有子集的聚类结果合并,得到最终的聚类结果。与 K-Means++ 算法相比,K-Means++-C 算法的计算速度更快,适用于大规模数据集的聚类。 这些升级版的 K-Means 算法可以根据不同的需求选择使用,以获得更好的聚类效果和更快的计算速度。

K-Means++ 算法对比K-Means 聚类算法示例

#导入必要的库
import numpy as np
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt#生成数据集
X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)#定义 K-Means++ 聚类算法函数
def k_means_pp(X, K):centroids = []# 随机选择一个初始质心i = np.random.randint(0, len(X))centroids.append(X[i])# 选择剩余的质心for k in range(1, K):# 计算每个样本离最近质心的距离的平方和D2 = np.array([min([np.linalg.norm(x-c)**2 for c in centroids]) for x in X])# 按照概率分布选择下一个质心probs = D2 / D2.sum()cumprobs = probs.cumsum()r = np.random.rand()j = np.where(cumprobs >= r)[0][0]centroids.append(X[j])return centroids#定义 K-Means 聚类算法函数
def k_means(X, K, centroids):# 初始化聚类结果、距离矩阵和聚类中心clusters = np.zeros(len(X))D = np.zeros((len(X), K))for k in range(K):D[:, k] = np.linalg.norm(X - centroids[k], axis=1)# 迭代更新聚类结果、距离矩阵和聚类中心while True:# 更新聚类结果new_clusters = np.argmin(D, axis=1)if np.array_equal(new_clusters, clusters):breakclusters = new_clusters# 更新聚类中心centroids = [X[clusters == k].mean(axis=0) for k in range(K)]# 更新距离矩阵for k in range(K):D[:, k] = np.linalg.norm(X - centroids[k], axis=1)return clusters, centroids#调用函数进行聚类
K = 4
centroids = k_means_pp(X, K)
clusters, centroids = k_means(X, K, centroids)#可视化聚类结果
plt.scatter(X[:, 0], X[:, 1], c=clusters)
plt.scatter(np.array(centroids)[:, 0], np.array(centroids)[:, 1], marker='*', s=200, c='k')
plt.show()

基于密度的聚类算法

DBSCAN聚类算法

DBSCAN(Density-Based Spatial Clustering of Applications with Noise)聚类算法是一种基于密度的聚类算法,它可以自动识别任意形状的聚类簇,并能够有效地处理包含噪声的数据。DBSCAN 算法的基本思想是通过寻找数据点周围的相邻点,以及这些相邻点周围的相邻点,来判断数据点是否属于同一个簇中。DBSCAN 算法的核心有两个参数:半径 𝜖 和最小的样本个数 𝑀𝑖𝑛𝑃𝑡𝑠 。其中,半径 𝜖 定义了数据点之间的邻域范围,即距离某个数据点不超过 𝜖 的数据点都被认为是它的邻居;最小的样本个数 𝑀𝑖𝑛𝑃𝑡𝑠 定义了一个簇的最小密度,即在一个数据点的邻域范围内,如果包含的数据点个数不少于 𝑀𝑖𝑛𝑃𝑡𝑠,则认为该点是核心点,可以构成一个簇。DBSCAN 算法的具体实现步骤如下:

  1. 随机选择一个未访问过的数据点 p。
  2. 计算数据点 p 的邻域范围内所有数据点的距离,如果距离不超过半径 𝜖 ,则认为这些点是相互可达的,将它们加入同一个簇中。
  3. 对于簇中的每个数据点,递归地执行步骤 2,直到无法继续扩展该簇为止。
  4. 重复步骤 1 到步骤 3,直到所有数据点都被访问过为止。

示例:

import numpy as np
from sklearn.cluster import DBSCAN
from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt# 生成随机数据
X, y = make_blobs(n_samples=1000, centers=3, cluster_std=0.5, random_state=0)# 使用DBSCAN算法进行聚类
dbscan = DBSCAN(eps=0.5, min_samples=5)
y_pred = dbscan.fit_predict(X)# 绘制聚类结果
plt.scatter(X[:, 0], X[:, 1], c=y_pred)
plt.title('DBSCAN Clustering')
plt.show()

Mean Shift聚类算法

Mean Shift 算法是一种基于密度的非参数聚类算法。它通过寻找密度函数的局部最大值来确定聚类簇的中心,进而将数据点分配到相应的聚类簇中。具体来说,Mean Shift 算法从任意一个数据点开始,通过迭代的方式不断移动该点,直到达到局部最大值为止。在移动过程中,Mean Shift 算法会不断地将数据点向密度函数值最大的方向移动,直到无法再移动为止,这样就能找到该点所在的聚类簇中心。然后,对于每个中心,可以找到与之相似的数据点并将它们分配到该簇中。最终,所有数据点都被分配到相应的聚类簇中。

import numpy as npdef euclidean_distance(x1, x2):return np.sqrt(np.sum((x1 - x2)**2))
#Mean Shift聚类算法
class MeanShift:def __init__(self, radius=4):self.radius = radiusdef fit(self, X):centroids = []for i in range(len(X)):point = X[i]while True:# Find all points within the given radiusneighbors = []for j in range(len(X)):if euclidean_distance(point, X[j]) <= self.radius:neighbors.append(X[j])# Calculate the mean of all points within the radiusnew_point = np.mean(neighbors, axis=0)# If the new point is within a certain distance of the last point, stopif euclidean_distance(point, new_point) < 0.00001:breakpoint = new_pointcentroids.append(point)self.centroids = np.unique(centroids, axis=0)def predict(self, X):labels = []for i in range(len(X)):distances = [euclidean_distance(X[i], c) for c in self.centroids]label = np.argmin(distances)labels.append(label)return labels

测试:

from sklearn.datasets import make_blobs
import matplotlib.pyplot as pltX, y = make_blobs(n_samples=200, centers=3, cluster_std=0.5, random_state=0)model = MeanShift()
model.fit(X)labels = model.predict(X)plt.scatter(X[:, 0], X[:, 1], c=labels)
plt.show()

层次聚类算法

凝聚层次聚类(Aglomerative Hierarchical Clustering,简称 AGNES)

从一个个单独的数据点开始,不断合并最近的两个聚类簇,直到所有数据点都被合并成一个聚类簇为止。凝聚层次聚类的核心是距离计算和聚类合并规则的选择。常用的距离计算方法有欧几里得距离、曼哈顿距离、余弦距离等。常用的聚类合并规则有最小距离法、最大距离法、重心法等。

分裂层次聚类(Divisive Hierarchical Clustering,简称 DIANA)

从所有数据点的整体开始,不断将数据点划分成两个或多个子集,直到每个子集都成为一个聚类簇为止。分裂层次聚类的核心是划分方法的选择,常用的划分方法有 K-Means、PAM 等。 层次聚类算法的优点在于可以自动确定聚类簇的数量和层次结构,但其缺点在于算法的时间复杂度较高,在大数据集上的计算时间可能非常长,并且容易受到噪声数据和异常值的影响。

基于图的聚类算法

谱聚类算法(Spectral Clustering)

将数据点看作图上的节点,通过计算节点之间的相似度矩阵和拉普拉斯矩阵来确定节点之间的相似性和距离,然后通过对拉普拉斯矩阵进行特征分解来得到聚类簇的划分。

import numpy as np
import scipy.spatial.distance as distclass SpectralClustering:def __init__(self, n_clusters=2, affinity='rbf', gamma=1.0):self.n_clusters = n_clustersself.affinity = affinityself.gamma = gammadef fit_predict(self, X):# 计算相似度矩阵if self.affinity == 'rbf':S = self._rbf_kernel(X, gamma=self.gamma)else:S = self._knn_kernel(X, k=self.gamma)# 计算拉普拉斯矩阵L = self._laplacian_matrix(S)# 计算特征值和特征向量eigvals, eigvecs = np.linalg.eig(L)# 取出前k个特征向量idx = eigvals.argsort()[:self.n_clusters]U = eigvecs[:, idx]# 对U进行归一化处理norm = np.linalg.norm(U, axis=1, keepdims=True)U_norm = U / norm# 对U_norm进行k-means聚类from sklearn.cluster import KMeanskmeans = KMeans(n_clusters=self.n_clusters)return kmeans.fit_predict(U_norm)def _rbf_kernel(self, X, gamma):dists = dist.squareform(dist.pdist(X, 'euclidean'))return np.exp(-gamma * dists ** 2)def _knn_kernel(self, X, k):dists = dist.squareform(dist.pdist(X, 'euclidean'))W = np.zeros_like(dists)for i in range(X.shape[0]):idx = np.argsort(dists[i])[:k+1]W[i, idx] = 1return Wdef _laplacian_matrix(self, S):# 计算度矩阵D = np.diag(np.sum(S, axis=1))# 计算拉普拉斯矩阵L = D - Sreturn L

社区发现算法(Community Detection)

将数据点看作社交网络上的节点,通过计算节点之间的社交关系和相似度来确定节点之间的相似性,然后利用社区发现算法将相似度高的节点划分到同一个社区中。

import networkx as nx
import community# 构建图
G = nx.karate_club_graph()# 使用Louvain算法进行社区发现
partition = community.modularity_max.greedy_modularity_communities(G)# 输出每个节点属于哪个社区
for i, com in enumerate(partition):print("Community %d: %s" % (i, com))

聚类算法使用领域

类算法是一种常用的无监督学习算法,可以将相似的数据点分组成簇,通常用于以下领域:

  1. 数据挖掘:聚类算法可以用于数据挖掘中的分析和分类,例如用户行为分析、产品定位、市场细分等。
  2. 图像处理:聚类算法可以用于图像分割、目标检测、图像压缩等应用,通过将图像像素聚类成不同的簇,实现对图像的分割和压缩。
  3. 自然语言处理:聚类算法可以用于文本聚类和主题模型,例如新闻分类、情感分析、文本推荐等。
  4. 生物信息学:聚类算法可以用于基因表达数据的聚类和分类,例如基因功能预测、新药研发等。
  5. 物联网:聚类算法可以用于传感器网络中的数据聚合和分类,例如智能交通、智能医疗等。 聚类算法在各个领域都有广泛的应用,可以帮助解决大规模数据的分类和分析问题,提高数据处理的效率和准确率。

总结

聚类算法是一种无监督学习算法,可以将相似的数据点分组成簇,是数据挖掘和机器学习领域中的重要技术之一。常用的聚类算法包括上文的K-Means、层次聚类、DBSCAN等。聚类算法的优点在于可以自动发现数据的内在结构和规律,可以用于数据挖掘、图像处理、自然语言处理、生物信息学、物联网等领域。在笔者看来,聚类算法的缺点在于需要大量计算资源和时间,容易受到噪声数据和异常值的影响,聚类结果也需要经过人工分析和解释,需要专业性,熟练性人才进入市场才能发挥这款无监督学习算法的强大作用。

原文链接:机器学习实战教程(一):聚类算法 - 知乎

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

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

相关文章

C++ 矩阵

目录 了解矩阵的数学原理&#xff08;大学线性代数&#xff09; 矩阵及转置矩阵 矩阵乘法 矩阵快速幂 相伴矩阵模板 [相伴矩阵,快速矩阵幂]CSES1722 Fibonacci Numbers 了解矩阵的数学原理&#xff08;大学线性代数&#xff09; 矩阵及转置矩阵 这里A就是一个矩阵&…

uniapp 桌面应用插件 Ba-Launcher

简介&#xff08;下载地址&#xff09; Ba-Launcher 可以让你的应用成为简单的桌面应用&#xff0c;如需扩展功能&#xff0c;请联系我。 截图展示 可关注博客&#xff0c;实时更新最新插件&#xff1a; uniapp 常用原生插件大全 使用方法 使用方法也很简单&#xff0c;在插…

PG数据库结构与oracle比较

1.数据库集簇逻辑结构 数据库集簇概念&#xff1a;一个大的数据库是由若干个小的数据库组成&#xff0c;实现数据的隔离存放&#xff0c;在概念上应该是与mysql一样的 在mysql中可以用show database列出数据库 PG中用\l 数据库对象存放在数据库中&#xff1a; PG中的所有数据…

题解:CF1951E(No Palindromes)

题解&#xff1a;CF1951E&#xff08;No Palindromes&#xff09; 题目翻译&#xff1a;给定一个长度为 n n n 的字符串 s s s&#xff0c;询问是否可以将其分成若干份&#xff0c;使得每一份都不是回文串。若可以&#xff0c;输出 YES 并给出任意一组方案&#xff1b;若不可…

【BASH 常用脚本系列3 -- shell实现查找目录并进入目录】

文章目录 shell实现查找目录并进入目录脚本实现shell实现查找目录并进入目录 在linux中终端下工作,如果要进入一个深度很深的目录的话需要 cd ./xx/xx./.. 执行很多次,用起来很麻烦,有些人就建议使用autojump来实现,但是autojump 的一个缺点是:如果本地有多套代码,只是它…

计算机英文论文常见错误写作习惯3

目录 第一部分 Numbers and Equations ‘such as’ and ‘etc.’ 第二部分 第一部分 Numbers and Equations 两个非常常见的错误是关于阿拉伯数字和方程式的表示。中国作家通常写阿拉伯数字&#xff0c;而不是拼出单词。然而&#xff0c;使用阿拉伯数字本身并不是一个错误…

【Shell】part1-Shell-基础入门篇

part1-基础入门 HelloWorld 创建,编写,运行 Shell 脚本 vim test.sh#!/bin/bash echo "Hello World !"# 1.作为可执行程序运行 chmod ax ./test.sh #使脚本具有执行权限 ./test.sh #执行脚本# 2.作为解释器参数运行 /bin/sh test.sh /bin/php test.php变量 变…

【Python】 逻辑回归:从训练到预测的完整案例

我把我唱给你听 把你纯真无邪的笑容给我吧 我们应该有快乐的 幸福的晴朗的时光 我把我唱给你听 用我炙热的感情感动你好吗 岁月是值得怀念的留恋的 害羞的红色脸庞 谁能够代替你呀 趁年轻尽情的爱吧 最最亲爱的人啊 路途遥远我们在一起吧 &#x1f3b5; 叶…

如何利用STM32F103实现太阳板的光线追踪

如何利用STM32F103实现太阳板的光线追踪 太阳能发电效率的提升一直是绿色能源领域的研究热点。通过太阳板的光线追踪技术&#xff0c;我们可以确保太阳板始终面向太阳&#xff0c;从而最大化其接收阳光的面积&#xff0c;提高能源转换效率。本文将介绍如何利用STM32F103微控制…

Redis第15讲——RedLock、Zookeeper及数据库实现分布式锁

由于篇幅原因&#xff0c;在上篇文章我们只介绍了redis实现分布式锁的两种方式——setnx和Redission&#xff0c;并对Reidssion加锁和看门狗机制的源码进行了分析&#xff0c;但这两种方案在极端情况下都会出现或多或少的问题。那么针对上述问题&#xff0c;比较主流的解决方案…

Linux服务器基本操作

Linux下服务器基本操作指令 Vim 文件名 进入 i编辑 esc退出编辑 &#xff1a;wq 保存退出 Cp -r文件夹 path 完整或…/ Cp 文件 path pwd 查看当前目录 rm -rf 2005 删除文件夹 Mkdir 创建文件夹 squeue查看提交队列 tail -f rsl.out.0000 在运行当前目录下查看进度 Scancel j…

用Scrapy 从数据挖掘到监控和自动化测试

Scrapy 是一个 BSD 许可的快速高级网络爬虫和网络抓取框架&#xff0c;用于抓取网站并从其页面中提取结构化数据。它可以用于广泛的用途&#xff0c;从数据挖掘到监控和自动化测试。 安装scrapy pip install scrapy 爬虫示例 示例代码写入文件 import scrapyclass QuotesSp…

Kylin Linux V10 SP1 aarch64部署k8s集群严重bug

目录 1.部署方式 2.遇到问题 3.问题解决 1.部署方式 通过sealos方式部署 2.遇到问题 适配Kylin Linux V10 SP1 aarch64部署pod 不少出现CrashLoopBackOff 通过命令: kubectl describe pod xxx -n default 查看,发现报错如下: Error response from daemon: OCI …

简约大气的全屏背景壁纸导航网源码(免费)

简约大气的全屏背景壁纸导航网模板 效果图部分代码领取源码下期更新预报 效果图 部分代码 <!DOCTYPE html> <html lang"zh-CN"> <!--版权归孤独 --> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible…

工厂模式和策略模式区别

工厂模式和策略模式都是面向对象设计模式&#xff0c;但它们的目的和应用场景有所不同。 工厂模式是一种创建型设计模式&#xff0c;旨在通过使用一个工厂类来创建对象&#xff0c;而不是直接使用new关键字来创建对象。这样做可以使系统更容易扩展和维护&#xff0c;因为新的对…

图论之最短路算法模板总结

来个大致的分类&#xff1a; 朴素的迪杰斯特拉&#xff1a; 实现&#xff1a; 我们让s表示当前已经确定的最短距离的点&#xff0c;我们找到一个不在s中的距离最近的点t&#xff0c;并用t来更新其他的点。 下面是AC代码&#xff1a; #include<bits/stdc.h> using nam…

C语言-整体内容简单的认识

目录 一、数据类型的介绍二、数据的变量和常量三、变量的作用域和生命周期四、字符串五、转义字符六、操作符六、常见的关键字6.1 关键字static 七、内存分配八、结构体九、指针 一、数据类型的介绍 sizeof是一个操作符&#xff0c;是计算机类型/变量所占内存空间的大小   sc…

中间件之异步通讯组件RabbitMQ入门

一、概述 微服务一旦拆分&#xff0c;必然涉及到服务之间的相互调用&#xff0c;目前我们服务之间调用采用的都是基于OpenFeign的调用。这种调用中&#xff0c;调用者发起请求后需要等待服务提供者执行业务返回结果后&#xff0c;才能继续执行后面的业务。也就是说调用者在调用…

Java IO流(二)

1. 缓冲流 1.1 字节缓冲流概述 当对文件或其他数据源进行频繁的读/写操作时&#xff0c;效率比较低&#xff0c;这时如果使用缓存流就能够更高效地读/写信息。 比如&#xff0c;可以使用缓冲输出流来一次性批量写出若干数据减少写出次数来提高写出效率。 如果用生活中的例子做…

使用qemu调试NVME driver

参考nvme驱动相关的博客&#xff0c;可以使用qemu buildroot进行nvme驱动的流程debug。 一、QEMU编译 首先需要编译qemu&#xff0c;可以参考QEMU编译。wget下载最新版本的QEMU&#xff0c;编译之前&#xff0c;最好检查下依赖包是否安装&#xff0c;避免安装过程出现各种错…