[python数据处理系列] 深入理解与实践基于聚类的过采样与欠采样技术:以K-Means为例

目录

一、过采样介绍

(一)什么是过采样

(二)过采样的优点

(三)过采样的缺点

二、欠采样介绍

(一)什么是欠采样

(二)欠采样的优点

(三)欠采样的缺点

三、基于聚类的欠抽样方法(K-Means欠采样/KMeans-Undersampling)

(一)KMeans欠采样原理及其步骤介绍

(二)为什么不采用简单的欠采样或者过采样而选择Kmeans欠采样

(三)聚类结束后,如何确定多数类样本欠抽样的数据量,并从每个簇中选择样本?------类别权重调整

(1)确定多数类样本欠抽样的数据量-----类别权重调整

(2)从每个簇中选择样本

四、python实现K-Means欠采样

(一)生成数据集

(二)目的

(三)通过Kmeans对X1多数类样本进行聚类

(1)通过手肘法和目标函数确定KMeans的最优K值

(2)选择最优K值后,进行KMeans聚类

(3) 查看每个聚类后类别中的样本数

(4) 计算聚类后每个类别占多数类样本的比例

(5)计算聚类后每个类别中应该抽取的样本数

(6)抽取数据

①随机无放回抽取33个标签为0的样本

 ②随机无放回抽取30个标签为1的样本

 ③随机无放回抽取50个标签为2的样本

 ④随机无放回抽取52个标签为3的样本

 ④随机无放回抽取15个标签为4的样本

 ⑤合并各类抽取后的数据

(四) 将180个多数类样本,和90个少数类样本进行整合。(目标就是多数类样本:少数类样本=2:1)

五、基于聚类的过抽样方法(K-Means过抽样)

六、python实现KMeans过抽样

(一)目的

(二)通过Kmeans对X2少数类样本进行聚类

(1)通过手肘法和目标函数确定KMeans的最优K值

(2)选择最优K值后,进行KMeans聚类

(3) 查看每个聚类后类别中的样本数 

(4) 计算聚类后每个类别占少数类样本的比例 

(5)计算聚类后每个类别中应该抽取的样本数

(6)抽取数据

①随机无放回抽取2个标签为0的样本 

②随机无放回抽取2个标签为1的样本 

③随机无放回抽取3个标签为2的样本 

④随机无放回抽取3个标签为3的样本 

 ⑤合并各类抽取后的数据

(三) 将200个多数类样本,和100个少数类样本进行整合。(目标就是多数类样本:少数类样本=2:1) 


一、过采样介绍

(一)什么是过采样

过采样是一种处理数据不平衡问题的方法,特别是在分类问题中,当某个类别的样本数量远远少于其他类别时,会导致模型在训练和预测中对少数类别的识别能力下降。过采样的主要目的是增加少数类别的样本数量,以改善数据的平衡。

(二)过采样的优点

1.  提高模型对少数类别的识别能力:通过增加少数类别的样本数量,使得模型更容易学习并识别少数类别的特征,从而提高模型在少数类别上的性能。
2.  不丢失信息:过采样生成的新样本是基于原始数据生成的,因此不会丢失原始数据的信息,保留了数据的特征。

(三)过采样的缺点

1.  容易引入噪声:过采样生成的新样本可能并不完全符合真实数据分布,可能会引入噪声,导致模型过拟合。
2.  增加计算复杂度和训练时间:过采样会增加数据集的大小,从而增加模型的计算复杂度和训练时间,尤其是在数据量较大的情况下。

二、欠采样介绍

(一)什么是欠采样

欠采样是一种处理数据不平衡问题的方法,与过采样相反,它是通过减少多数类别的样本数量来实现数据平衡,从而解决在分类问题中多数类别样本数量远远大于少数类别样本数量的情况。

(二)欠采样的优点

1.  减少训练时间和计算复杂度:由于减少了多数类别的样本数量,可以减少模型的训练时间和计算复杂度,提高训练效率。
2.  降低过拟合的风险:减少多数类别的样本数量可以降低模型对多数类别的过度拟合,使得模型更加泛化。

(三)欠采样的缺点

1.  可能丢失重要信息:欠采样会舍弃多数类别的样本,可能会丢失一些重要信息,导致模型在多数类别上的性能下降。
2.  容易丢失少数类别的特征:由于减少了多数类别的样本数量,模型可能无法充分学习到少数类别的特征,导致在少数类别上的性能下降。

三、基于聚类的欠抽样方法(K-Means欠采样/KMeans-Undersampling)

(一)KMeans欠采样原理及其步骤介绍

KMeans欠采样是一种处理不平衡数据集的方法,它结合了聚类和欠采样的思想,通过聚类的方式选择代表性样本,以平衡数据集并提高模型性能。

具体步骤如下:

1.  数据预处理:对数据进行预处理,包括缺失值处理、数据标准化等。
    
2.  KMeans聚类:使用KMeans聚类算法对数据的多类样本数据进行聚类,将数据分成K个簇。
    
3.  选择代表性样本:从每个簇中选择代表性样本,可以选择簇中的中心点或者随机选择一个样本,若在这个簇中需要选取多个样本,可以考虑有放回选取和无放回选取,建议采用无放回选取
    
4.  构建新的数据集:将选择的代表性样本组成新的数据集,用于模型训练和预测。
    
5.  模型训练和预测:使用新的数据集训练模型,并对测试集进行预测。

通过KMeans欠采样,可以有效地平衡数据集,提高模型对少数类样本的学习能力,从而提高分类性能。

(二)为什么不采用简单的欠采样或者过采样而选择Kmeans欠采样

简单的欠采样和过采样方法在处理不平衡数据集时存在一些问题,比如欠采样可能导致信息丢失,过采样可能引入噪声。

KMeans欠采样是一种结合了聚类和欠采样的方法,可以一定程度上克服简单欠采样和过采样的缺点,具有以下优点:

1.  保留数据分布特征:KMeans欠采样通过聚类的方式选择代表性样本,能够更好地保留原始数据的分布特征,避免了简单欠采样可能导致的信息丢失问题。
    
2.  减少噪声引入:KMeans欠采样在选择样本时考虑了样本之间的相似性,避免了简单过采样可能引入的噪声问题,提高了模型的泛化能力。
    
3.  降低计算成本:KMeans欠采样通过聚类的方式减少了样本数量,可以降低模型训练和预测的计算成本,提高了效率。
    
4.  提高分类性能:KMeans欠采样能够更好地平衡数据集,提高了模型对少数类样本的学习能力,从而提高了分类性能。

综上所述,KMeans欠采样是一种比简单欠采样和过采样更加有效的处理不平衡数据集的方法,能够在一定程度上解决不平衡数据集带来的挑战,提高模型性能。

(三)聚类结束后,如何确定多数类样本欠抽样的数据量,并从每个簇中选择样本?------类别权重调整

(1)确定多数类样本欠抽样的数据量-----类别权重调整

前提:正类数量:负类数量>真实世界的真实比例

在处理二分类问题时,我们经常遇到正类和负类样本数量不平衡的情况。假设在一个实际的二分类问题中,正类的样本数量为 N1,而负类的样本数量为N2,并且 N1显著大于 N2。N1/N2的比例远大于真实世界这两种类别的比例。

一旦我们知道了真实的正负类比例ratio,我们可以使用这个信息来调整训练数据,使得模型训练过程中的样本分布更加接近真实世界的分布。为了达到这个目的,我们可以采用KMeans欠采样策略,以负类样本的数量N2作为基准,对正类样本进行欠采样。

通过欠采样,我们希望获得的新的正类样本数量 N1_new 应该与负类样本数量N2成比例,

即:

N1_new=ratio*N2

这就是通过进行类别权重调整,来确定多数类样本欠抽样时的数据量。

这样,经过欠采样后的正类样本数量  将更接近于实际情况下的正负类比例,有助于提高模型的泛化能力和避免过拟合。

补充:这个ratio我们也可以人为的设定

(2)从每个簇中选择样本

上边我们确定了多数类样本也就是正类样本进行欠抽样的数据量N2_new

那么怎么从K个簇中,每个簇中抽取样本呢?

首先,确定从每个簇中抽取的样本量ni:

ni=(N1_i/N2)*N1_new

i=1,2,3,4,5,6......k(k个簇)

其中N1_i,代表聚类后第i个簇中的样本量,N1_i/N1代表第i个簇中的样本量占整个多类样本数量的比例

ni也就是确定的每个簇中抽取的样本量

每次从各个簇中抽取样本时,建议采用不放回抽样,这样可以保证尽量不丢失原始数据的信息,保留数据的特征。

四、python实现K-Means欠采样

(一)生成数据集

import numpy as np
from sklearn.datasets import make_blobs

X1, Y1 = make_blobs(n_samples=200, centers=1, random_state=0)
X2, Y2 = make_blobs(n_samples=90, centers=1, random_state=0)

X = np.vstack((X1, X2))
Y = np.hstack((Y1, Y2 + 1))  # 将第二个类别的标签设置为1,以便与第一个类别区分开

如果想要控制每个类别的数量,可以使用n_samples参数分别设置每个类别的数量,然后使用numpy库将数据合并。例如,生成200个样本属于第一个类别,90个样本属于第二个类别:.

import pandas as pd

# 将 Y 转换为 Pandas Series
Y_series = pd.Series(Y)

# 计算 Y 中每个类别的数量
class_counts = Y_series.value_counts()

print(class_counts)

(二)目的

我们想控制Y1类和Y2类的数量比例ratio是2:1,故若采取欠抽样的话,需要从Y1的的样本中抽取出180个样本量,或者说去除20个样本量 。

(三)通过Kmeans对X1多数类样本进行聚类

(1)通过手肘法和目标函数确定KMeans的最优K值
from matplotlib import pyplot as plt
from sklearn.cluster import KMeans
# 使用手肘法确定最佳的K值
plt.rcParams['font.sans-serif'] = ['SimHei']
inertia = []
for k in range(1, 20):
    kmeans = KMeans(n_clusters=k, random_state=0,init="k-means++")
    kmeans.fit(X1)
    inertia.append(kmeans.inertia_)
# 绘制手肘法图表
plt.figure(figsize=(5, 3),dpi=144)
plt.plot(range(1,20), inertia, marker='o', linestyle='--')

plt.xlabel('K值')
plt.ylabel('距离平方和')
plt.title('手肘法图表')
plt.savefig('手肘法图.png',dpi=300)
# plt.grid(True)

# 设置横坐标刻度值为整数
plt.xticks(range(1, 20, 1))

plt.show()

import numpy as np
# Find the K value with the smallest inertia change
#距离平方和得差,也就是每次K值距上一次K值所对应得距离平方和下降程度
inertia_diff = np.diff(inertia)


plt.figure(figsize=(5, 3),dpi=144)
inertia_diff_abs = np.abs(inertia_diff)  # 取绝对值,使所有值变为非负
plt.plot(range(2, 20), inertia_diff_abs, marker='o', linestyle='--')
#inertia_diff_abs:取绝对值
plt.xlabel('K值')
plt.ylabel('距离平方和下降程度')
plt.title('目标函数(聚类内部元素的总平方距离下降程度)表')
# plt.savefig('手肘法图.png',dpi=300)
# plt.grid(True)

# 设置横坐标刻度值为整数
plt.xticks(range(2, 20, 1))

plt.show()

 

通过分析,K的最优取值为5。具体原理和分析过程,不在这里再具体阐述,感兴趣的小伙伴可以查看上一篇博客进行了解。链接如下:

[机器学习系列]深入解析K-Means聚类算法:理论、实践与优化-CSDN博客

(2)选择最优K值后,进行KMeans聚类
kmeans = KMeans(n_clusters=5, random_state=0)
kmeans.fit(X1)

print(kmeans.labels_)#获取训练数据所属的类别
(3) 查看每个聚类后类别中的样本数
import pandas as pd

# 将 Y 转换为 Pandas Series
kmeans.labels_series = pd.Series(kmeans.labels_)

# 计算 Y 中每个类别的数量
class_counts = kmeans.labels_series.value_counts()

print(class_counts)

(4) 计算聚类后每个类别占多数类样本的比例
# 计算总数(所有类别的数量)
total_count = class_counts.sum()

# 计算每个类别占总数的比例
class_proportions = class_counts / total_count

print(class_proportions)

(5)计算聚类后每个类别中应该抽取的样本数

至于为什么*180,请参考(二)目的第一部分,其中有阐述。

class_proportions*180

那么按照四舍五入,标签为3的这一类从中随机无放回抽取52个样本,标签为2的这一类从中随机无放回抽取50个样本,标签为0的这一类从中随机无放回抽取33个样本,标签为1的这一类从中随机无放回抽取30个样本,标签为4的这一类从中随机无放回抽取15个样本.52+50+33+30+15=180.

(6)抽取数据
# 将 X 转换为 DataFrame
import pandas as pd
df = pd.DataFrame(X1, columns=['Feature1', 'Feature2'])

# 将簇标签添加到原始数据中
df["聚类标签结果"]=kmeans.labels_
df

①随机无放回抽取33个标签为0的样本
cluster_zero_df = df[df["聚类标签结果"] == 0]

import pandas as pd

# 不放回地随机抽取33行数据
sampled_zero = cluster_zero_df.sample(n=33, replace=False)

# print(sampled_zero)

# 在这段代码中,sample函数用于从DataFrame中抽取样本。参数n=33指定了要抽取的样本数量,而replace=False确保了抽取是不放回的。
 ②随机无放回抽取30个标签为1的样本
cluster_one_df = df[df["聚类标签结果"] == 1]
sampled_one = cluster_one_df.sample(n=30, replace=False)
 ③随机无放回抽取50个标签为2的样本
cluster_two_df = df[df["聚类标签结果"] == 2]
sampled_two = cluster_two_df.sample(n=50, replace=False)
 ④随机无放回抽取52个标签为3的样本
cluster_three_df = df[df["聚类标签结果"] == 3]
sampled_three = cluster_three_df.sample(n=52, replace=False)
 ④随机无放回抽取15个标签为4的样本
cluster_four_df = df[df["聚类标签结果"] == 4]
sampled_four = cluster_four_df.sample(n=15, replace=False)
 ⑤合并各类抽取后的数据
combined_df = pd.concat([sampled_zero, sampled_one, sampled_two, sampled_three,sampled_four], axis=0)

(四) 将180个多数类样本,和90个少数类样本进行整合。(目标就是多数类样本:少数类样本=2:1)

combined_df=combined_df.iloc[:, :2]

combined_df["标签"] = 0

df_0类样本=combined_df

df_1类样本= pd.DataFrame(X2, columns=['Feature1', 'Feature2'])

df_1类样本["标签"]=Y2+1 #这里Y2为什么加1呢,因为最开始我们生成数据集时,是分开分别生成了两对数据集X1 Y1 和 X2 Y2,实际上Y1和Y2的标签都是0,所以这里让Y2+1变成标签1


data= pd.concat([df_0类样本, df_1类样本], axis=0)

五、基于聚类的过抽样方法(K-Means过抽样)

K-Means过抽样的内容和Kmeans欠抽样几乎一致,

不过唯一的不同点就是:

K-means过抽样是以多数类样本为基础,对少数类样本进行聚类。

比如我们想要多数类样本N1_new:少数类样本N2_new=2:1

但是现在多数类样本N1=200,少数类样本N2=90,此时200:90不等2:1

如果以多数类样本N1=N1_New为基础不变,那么N2_new就得等于100,此时少数类样本N2有90个样本了,为了使数据信息充分被利用,那么少数类样本依然选择这90个数据,然后还缺100-90=10个少数类样本,此时就对90个少数类样本进行聚类,聚成K个簇

确定从每个簇中抽取的样本量ni:

ni=(N2_i/N2)*(N2_new-N2)

i=1,2,3,4,5,6......k(k个簇)

其中N2_i,代表第i个簇中的样本量,N2_i/N2代表第i个簇中的样本量占整个多类样本数量的比例

ni也就是确定的每个簇中抽取的样本量

N2_new是希望 抽样结束后,少数类样本的总个数

N2是原始数据中少数类样本的总个数

(N2_new-N2)是希望通过聚类过抽样抽取的少数样本总数。

六、python实现KMeans过抽样

(一)目的

我们想控制Y1类和Y2类的数量比例ratio是2:1,故若采取过抽样的话,以多数类样本数量200不动,少数类样本数量要从90变成100,那么就要将90个少数类样本进行聚类,然后按照比例从每簇中抽取数据,共从中随机无放回抽取出10个少数类样本。

(二)通过Kmeans对X2少数类样本进行聚类

(1)通过手肘法和目标函数确定KMeans的最优K值
from matplotlib import pyplot as plt
from sklearn.cluster import KMeans
# 使用手肘法确定最佳的K值
plt.rcParams['font.sans-serif'] = ['SimHei']
inertia = []
for k in range(1, 20):
    kmeans = KMeans(n_clusters=k, random_state=0,init="k-means++")
    kmeans.fit(X2)
    inertia.append(kmeans.inertia_)
# 绘制手肘法图表
plt.figure(figsize=(5, 3),dpi=144)
plt.plot(range(1,20), inertia, marker='o', linestyle='--')

plt.xlabel('K值')
plt.ylabel('距离平方和')
plt.title('手肘法图表')
plt.savefig('手肘法图.png',dpi=300)
# plt.grid(True)

# 设置横坐标刻度值为整数
plt.xticks(range(1, 20, 1))

plt.show()

import numpy as np
# Find the K value with the smallest inertia change
#距离平方和得差,也就是每次K值距上一次K值所对应得距离平方和下降程度
inertia_diff = np.diff(inertia)

plt.figure(figsize=(5, 3),dpi=144)
inertia_diff_abs = np.abs(inertia_diff)  # 取绝对值,使所有值变为非负
plt.plot(range(2, 20), inertia_diff_abs, marker='o', linestyle='--')
#inertia_diff_abs:取绝对值
plt.xlabel('K值')
plt.ylabel('距离平方和下降程度')
plt.title('目标函数(聚类内部元素的总平方距离下降程度)表')
# plt.savefig('手肘法图.png',dpi=300)
# plt.grid(True)

# 设置横坐标刻度值为整数
plt.xticks(range(2, 20, 1))

plt.show()

通过分析,K的最优取值为5。具体原理和分析过程,不在这里再具体阐述,感兴趣的小伙伴可以查看上一篇博客进行了解。链接如下:

[机器学习系列]深入解析K-Means聚类算法:理论、实践与优化-CSDN博客

(2)选择最优K值后,进行KMeans聚类
kmeans = KMeans(n_clusters=4, random_state=0)
kmeans.fit(X2)
(3) 查看每个聚类后类别中的样本数 
import pandas as pd

# 将 Y 转换为 Pandas Series
kmeans.labels_series = pd.Series(kmeans.labels_)

# 计算 Y 中每个类别的数量
class_counts = kmeans.labels_series.value_counts()

print(class_counts)

(4) 计算聚类后每个类别占少数类样本的比例 
# 计算总数(所有类别的数量)
total_count = class_counts.sum()

# 计算每个类别占总数的比例
class_proportions = class_counts / total_count

print(class_proportions)

我们想使多数类样本:少数类样本=2:1,现在是过抽样,以多数类样本的数量200为基础不动,少数类样本应该是有100个,但是现在只有90个,所以需要对这90个样本进行聚类,聚成K个类,然后按照比例分别从这K个类中抽取样本,总共抽取的样本是10个,这样90+10=100少数类样本就一共有100个了,多数类样本:少数类样本就满足比例2:1了。 

(5)计算聚类后每个类别中应该抽取的样本数
class_proportions*10

那么按照四舍五入,标签为2的这一类从中随机无放回抽取3个样本,标签为3的这一类从中随机无放回抽取3个样本,标签为1的这一类从中随机无放回抽取2个样本,标签为0的这一类从中随机无放回抽取2个样本.3+3+2+2=10. 

(6)抽取数据
# 将 X 转换为 DataFrame
import pandas as pd
df = pd.DataFrame(X2, columns=['Feature1', 'Feature2'])

# 将簇标签添加到原始数据中
df["聚类标签结果"]=kmeans.labels_
df

①随机无放回抽取2个标签为0的样本 
cluster_zero_df = df[df["聚类标签结果"] == 0]
sampled_zero = cluster_zero_df.sample(n=2, replace=False)
②随机无放回抽取2个标签为1的样本 
cluster_one_df = df[df["聚类标签结果"] == 1]
sampled_one = cluster_one_df.sample(n=2, replace=False)
③随机无放回抽取3个标签为2的样本 
cluster_two_df = df[df["聚类标签结果"] == 2]
sampled_two = cluster_two_df.sample(n=3, replace=False)
④随机无放回抽取3个标签为3的样本 
cluster_three_df = df[df["聚类标签结果"] == 3]
sampled_three = cluster_three_df.sample(n=3, replace=False)
 ⑤合并各类抽取后的数据
combined_df = pd.concat([sampled_zero, sampled_one, sampled_two, sampled_three], axis=0)

(三) 将200个多数类样本,和100个少数类样本进行整合。(目标就是多数类样本:少数类样本=2:1) 

combined_df=combined_df.iloc[:, :2]

combined_df["标签"] = 1

df_1类抽样样本=combined_df

df_1类样本= pd.DataFrame(X2, columns=['Feature1', 'Feature2'])

df_0类样本= pd.DataFrame(X1, columns=['Feature1', 'Feature2'])
df_0类样本["标签"]=Y1
data= pd.concat([df_0类样本, df_1类样本,df_1类抽样样本], axis=0)

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

UE4 Widget制作搜索框

效果: 一、控件层级结构 1.父控件层级结构 2.子控件层级结构 二、蓝图 1.先清除掉创建子项(注意:这里使用的是reverse循环!) 2.判断是否含有关键字,创建子控件

盲人手机导航:科技之光引领无障碍出行新纪元

在这个日新月异的数字时代,科技不仅改变了我们获取信息的方式,更在无声中拓宽了视障人士的生活半径。盲人手机导航这一创新技术,正逐步成为他们探索世界、实现独立出行的重要伙伴。 对于大多数人而言,日常出行或许只是一次…

Vue3+Nuxt3 从0到1搭建官网项目(SEO搜索、中英文切换、图片懒加载)

Vue2Nuxt2 从 0 到1 搭建官网~ 想开发一个官网,并且支持SEO搜索,当然离不开我们的 Nuxt ,Nuxt2 我们刚刚可以熟练运用,现在有出现了Nuxt3,那通过本篇文章让我们一起了解一下。 安装 Nuxt3 // npx nuxilatest init &…

解析Redis Key Prefix配置之谜:双冒号“::”的由来与作用

前言 在使用Spring Boot集成Redis进行应用开发时,为了增强缓存键的可读性和管理性,我们常常会在配置文件中设定一个全局的key-prefix。如果你发现存储至Redis的键自动附加了“::”,本文将深入探讨这一现象背后的原因,解析Spring …

Redis线程模型及性能优化概述

redis线程模型: 网络模块命令处理 redis的性能: 一个取决于物理内存,另一个是对于socket请求的处理速度。 4.0以前 单线程模式 请求流程:对于一个请求,线程会根据操作产生相应的事件(读,写事…

张大哥笔记:服务器有挖矿木马程序,该如何处理?

这篇文章发表于2021年,今天借这个平台再发布一下,希望对大家有所帮助! 今天收到一个粉丝求助,说收到了阿里云官方短信通知提示有挖矿程序,要求立即整改,否则会关停服务器,以下是我和他的对话内…

机器学习:深入解析SVM的核心概念(问题与解答篇)【二、对偶问题】

对偶问题 **问题一:什么叫做凸二次优化问题?而且为什么符合凸二次优化问题?**为什么约束条件也是凸的半空间(Half-Space)凸集(Convex Set)半空间是凸集的例子SVM 约束定义的半空间总结 **问题二…

CTFHub-Web-SSRF

CTFHub-Web-SSRF-WP 一、内网访问 1.题目提示说访问127.0.0.1的flag.php,在URL后面添加路径没想到直接访问成功 二、伪协议读取文件 1.题目提示说访问Web目录下的flag.php,联想到Web目录一般存放于/var/www/html/里,去修改URL尝试进行访问…

【多级缓存】多级缓存OpenResty,Canal,nginx本地缓存

多级缓存 安装OpenRestyOpenResty入门OpenResty获取请求参数OpenResty向tomcat服务器发送请求 在nginx与tomcat端之间添加redis缓存Redis本地缓存缓存同步缓存同步策略基于Canal的异步通知安装Canal Canal客户端 安装OpenResty OpenResty是一个基于 Nginx的高性能 Web 平台&am…

初探 JUC 并发编程:Java 并发包中并发 List 源码剖析

最近在阅读 《Java 并发编程之美》这本书,感觉学到了很多东西;所以我决定将从事书中学到的思想和一些经典的案例整理成博客的形式与大家分享和交流,如果对大家有帮助别忘了留下点赞和关注捏。 第五部分:Java 并发包中并发 List 源…

STM32CubeMX+MDK通过I2S接口进行音频输入输出(全双工读写一个DMA回调)续-音质问题解决总结

一、前言 之前进行了STM32CubeMXMDK通过I2S接口进行音频输入输出(全双工读写一个DMA回调)的研究总结: https://juejin.cn/post/7339016190612881408#heading-34 后续音质问题解决了,目前测试下来48khz的双声道使用效果很好&…

基于uniapp+微信小程序的智能停车场管理小程序,附源码

博主介绍:✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇…

护航智慧交通安全 | 聚铭精彩亮相2024交通科技创新及信创产品推广交流会

4月26日,石家庄希尔顿酒店内,河北省智能交通协会盛大举办2024年度交通科技创新及信创产品推广交流会。聚铭网络受邀参与,携旗下安全产品及解决方案精彩亮相,为智慧交通安全保驾护航。 为深化高速公路创新驱动发展战略&#xff0…

Java网址url工具类

功能描述 无需引入三方依赖文本匹配网址(支持多个)网址解析(包括协议、主机、路径、参数等) package com.qiangesoft.image.utils;import org.springframework.util.Assert; import org.springframework.util.CollectionUtils;i…

深度学习基础之《TensorFlow框架(16)—神经网络案例》

一、mnist手写数字识别 1、数据集介绍 mnist数据集是一个经典的数据集,其中包括70000个样本,包括60000个训练样本和10000个测试样本 2、下载地址:http://yann.lecun.com/exdb/mnist/ 3、文件说明 train-images-idx3-ubyte.gz: training s…

C#编程模式之装饰模式

创作背景:朋友们,我们继续C#编程模式的学习,本文我们将一起探讨装饰模式。装饰模式也是一种结构型设计模式,它允许你通过在运行时向对象添加额外的功能,从而动态的修改对象的行为。装饰模式本质上还是继承的一种替换方…

分享三款可以给pdf做批注的软件

PDF文件不像Word一样可以直接编辑更改,想要在PDF文件上进行编辑批注需要用到一些专业的软件,我自己常用的有三款,全都是官方专业正版的软件,功能丰富强大,使用起来非常方便! 1.edge浏览器 这个浏览器不仅可…

爬虫实战-房天下(bengbu.zu.fang.com/)数据爬取

详细代码链接https://flowus.cn/hbzx/3c42674d-8e6f-42e3-a3f6-bc1258034676 import requests from lxml import etree #xpath解析库 def 源代码(url): cookies { global_cookie: xeqnmumh38dvpj96uzseftwdr20lvkwkfb9, otherid: b44a1837638234f1a0a15e…

JavaEE 初阶篇-深入了解特殊文件(Properties 属性文件、XML)

🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 Properties 属性文件概述 1.1 Properties 属性文件特性与作用 1.2 使用 Properties 把键值对数据写出到属性文件中 1.3 使用 Properties 读取属性文件里的键值对数…

《动手学深度学习(Pytorch版)》Task03:线性神经网络——4.29打卡

《动手学深度学习(Pytorch版)》Task03:线性神经网络 线性回归基本元素线性模型损失函数随机梯度下降 正态分布与平方损失 线性回归的从零开始实现读取数据集初始化模型参数定义模型定义损失函数定义优化算法训练 线性回归的简洁实现读取数据集…