[机器学习算法]决策树

news2024/10/6 1:34:21

1. 理解决策树的基本概念

决策树是一种监督学习算法,可以用于分类和回归任务。决策树通过一系列规则将数据划分为不同的类别或值。树的每个节点表示一个特征,节点之间的分支表示特征的可能取值,叶节点表示分类或回归结果。
在这里插入图片描述

2. 决策树的构建过程

2.1. 特征选择

特征选择是构建决策树的第一步,通常使用信息增益、基尼指数或增益率等指标。

  1. 信息增益(Information Gain)

信息增益表示通过某个特征将数据集划分后的纯度增加量,公式如下:
在这里插入图片描述
其中:

D 是数据集。
A 是特征。
V(A) 是特征 A 的所有可能取值。
Dv 是数据集中特征 A 取值为 v 的子集。
∣Dv​∣ 是 Dv​ 中样本的数量。
∣D∣ 是数据集 D 中样本的总数量。
Entropy(D) 是数据集 D 的熵,表示数据集本身的纯度。

选择信息增益最大的特征作为当前节点的划分特征。

熵的计算公式为:
在这里插入图片描述
其中:

c 是类别的数量。
pi 是数据集中属于第 i 类的样本所占的比例。

以下代码展示了如何计算熵、信息增益,并选择最优特征。

import numpy as np
from collections import Counter
from sklearn.datasets import load_iris

def entropy(y):
    hist = np.bincount(y)
    ps = hist / len(y)
    return -np.sum([p * np.log2(p) for p in ps if p > 0])

def information_gain(X, y, feature):
    # Entropy before split
    entropy_before = entropy(y)
    
    # Values and counts
    values, counts = np.unique(X[:, feature], return_counts=True)
    
    # Weighted entropy after split
    entropy_after = 0
    for v, count in zip(values, counts):
        entropy_after += (count / len(y)) * entropy(y[X[:, feature] == v])
    
    return entropy_before - entropy_after

def best_feature_by_information_gain(X, y):
    features = X.shape[1]
    gains = [information_gain(X, y, feature) for feature in range(features)]
    return np.argmax(gains), max(gains)

# Load dataset
iris = load_iris()
X = iris.data
y = iris.target

# Find best feature
best_feature, best_gain = best_feature_by_information_gain(X, y)
print(f'Best feature: {iris.feature_names[best_feature]}, Information Gain: {best_gain}')

  1. 基尼指数(Gini Index)
    也称为基尼不纯度(Gini Impurity),是一种衡量数据集纯度的指标。基尼指数越小,数据集的纯度越高。

基尼指数的计算公式:
对于一个包含 k 个类别的分类问题,基尼指数 G(D) 定义如下:
在这里插入图片描述
其中:

D 是数据集。
k 是类别的数量。
pi 是数据集中属于第 i 类的样本所占的比例。

条件基尼指数:
在某个特征 A 的条件下,数据集 D 的条件基尼指数 G(D∣A) 定义如下:
在这里插入图片描述
其中:

values(A) 是特征 A 的所有可能取值。
Dv​ 是数据集中特征 A 取值为 v 的子集。
∣Dv∣ 是 Dv​ 中样本的数量。
∣D∣ 是数据集 D 中样本的总数量。
G(Dv) 是子集 Dv​ 的基尼指数。

基尼增益(Gini Gain):
基尼增益 GG(D,A) 是通过特征 A 划分数据集 D 后基尼指数的减少量。计算公式如下:
在这里插入图片描述
参数解释

D:整个数据集,包含了所有的样本。
A:某个特征,用于划分数据集。
G(D):数据集 D 的基尼指数,表示数据集本身的纯度。
G(D∣A):在特征 A 的条件下,数据集 D 的条件基尼指数,表示在特征 A 的条件下数据集的纯度。

选择基尼增益最大的特征及其分割点作为当前节点的划分特征。

以下代码展示如何使用上述步骤来选择基尼增益最大的特征:

import numpy as np
from sklearn.datasets import load_iris

def gini(y):
    hist = np.bincount(y)
    ps = hist / len(y)
    return 1 - np.sum([p**2 for p in ps if p > 0])

def gini_gain(X, y, feature):
    # Gini index before split
    gini_before = gini(y)
    
    # Values and counts
    values, counts = np.unique(X[:, feature], return_counts=True)
    
    # Weighted gini after split
    gini_after = 0
    for v, count in zip(values, counts):
        gini_after += (count / len(y)) * gini(y[X[:, feature] == v])
    
    return gini_before - gini_after

def best_feature_by_gini_gain(X, y):
    features = X.shape[1]
    gains = [gini_gain(X, y, feature) for feature in range(features)]
    return np.argmax(gains), max(gains)

# Load dataset
iris = load_iris()
X = iris.data
y = iris.target

# Find best feature
best_feature, best_gain = best_feature_by_gini_gain(X, y)
print(f'Best feature: {iris.feature_names[best_feature]}, Gini Gain: {best_gain}')

  1. 增益率(Gain Ratio)
    决策树中的增益率(Gain Ratio)用于选择最优的划分属性,以便构建决策树。增益率是基于信息增益(Information Gain)的一个修正版本,用于克服信息增益在处理属性取值多样性时可能出现的偏向问题。

信息增益是指选择某一属性划分数据集后,信息熵的减少量。信息增益公式为:

在这里插入图片描述
其中:

IG(T,A):属性 A 对数据集 T 的信息增益。
H(T):数据集 T 的熵。
H(T∣A):在给定属性 A 的条件下数据集 T 的条件熵。

增益率通过将信息增益除以属性的固有值(Intrinsic Value)来计算。固有值是衡量属性取值多样性的一种指标。增益率公式为:
在这里插入图片描述
其中:

GR(T,A):属性 A 对数据集 T 的增益率。
IG(T,A):属性 A 对数据集 T 的信息增益。
IV(A):属性 A 的固有值。

固有值(Intrinsic Value)

固有值反映了属性的取值多样性,计算公式为:

在这里插入图片描述
其中:

Ti​:属性 A 的第 i 个取值所对应的样本子集。
∣Ti∣:属性 A 的第 i 个取值所对应的样本子集的样本数量。
∣T∣:数据集 T 的总样本数量。
n:属性 A 取值的个数。

通过计算每个属性的增益率,选择增益率最高的属性作为决策树节点的划分属性,从而构建最优的决策树。

2.2. 划分节点

根据选定的特征和阈值,数据集被划分成多个子集。

2.3. 递归构建

递归地对每个子集进行特征选择和划分,直到满足停止条件(如当前数据子集中的所有实例都属于同一个类别,或达到预设的最大树深度)。
特征选择以增益率为例,在决策树构建过程中,选择每个节点的分裂特征是基于当前数据集的增益率计算结果的。对于每个分裂点,我们都会重新计算剩余特征的增益率,并选择其中最高的作为下一个分裂特征。

import numpy as np
import pandas as pd

# 计算熵
def entropy(y):
    unique_labels, counts = np.unique(y, return_counts=True)
    probabilities = counts / counts.sum()
    return -np.sum(probabilities * np.log2(probabilities))

# 计算信息增益
def information_gain(data, split_attribute, target_attribute):
    total_entropy = entropy(data[target_attribute])
    values, counts = np.unique(data[split_attribute], return_counts=True)
    weighted_entropy = np.sum([
        (counts[i] / np.sum(counts)) * entropy(data[data[split_attribute] == values[i]][target_attribute])
        for i in range(len(values))
    ])
    info_gain = total_entropy - weighted_entropy
    return info_gain

# 计算固有值
def intrinsic_value(data, split_attribute):
    values, counts = np.unique(data[split_attribute], return_counts=True)
    probabilities = counts / counts.sum()
    return -np.sum(probabilities * np.log2(probabilities))

# 计算增益率
def gain_ratio(data, split_attribute, target_attribute):
    info_gain = information_gain(data, split_attribute, target_attribute)
    iv = intrinsic_value(data, split_attribute)
    return info_gain / iv if iv != 0 else 0

# 递归构建决策树
def build_decision_tree(data, original_data, features, target_attribute, parent_node_class=None):
    # 条件1: 所有数据点属于同一类别
    if len(np.unique(data[target_attribute])) <= 1:
        return np.unique(data[target_attribute])[0]
    
    # 条件2: 数据子集为空
    elif len(data) == 0:
        return np.unique(original_data[target_attribute])[np.argmax(np.unique(original_data[target_attribute], return_counts=True)[1])]
    
    # 条件3: 没有更多的特征可以分裂
    elif len(features) == 0:
        return parent_node_class
    
    else:
        parent_node_class = np.unique(data[target_attribute])[np.argmax(np.unique(data[target_attribute], return_counts=True)[1])]
        
        gain_ratios = {feature: gain_ratio(data, feature, target_attribute) for feature in features}
        best_feature = max(gain_ratios, key=gain_ratios.get)
        
        tree = {best_feature: {}}
        
        features = [i for i in features if i != best_feature]
        
        for value in np.unique(data[best_feature]):
            sub_data = data[data[best_feature] == value]
            subtree = build_decision_tree(sub_data, original_data, features, target_attribute, parent_node_class)
            tree[best_feature][value] = subtree
        
        return tree

# 可视化决策树
def visualize_tree(tree, depth=0):
    if isinstance(tree, dict):
        for attribute, subtree in tree.items():
            if isinstance(subtree, dict):
                for value, subsubtree in subtree.items():
                    print(f"{'|   ' * depth}|--- {attribute} = {value}")
                    visualize_tree(subsubtree, depth + 1)
            else:
                print(f"{'|   ' * depth}|--- {attribute} = {value}: {subtree}")
    else:
        print(f"{'|   ' * depth}|--- {tree}")

# 示例数据
data = pd.DataFrame({
    'Outlook': ['Sunny', 'Sunny', 'Overcast', 'Rain', 'Rain', 'Rain', 'Overcast', 'Sunny', 'Sunny', 'Rain', 'Sunny', 'Overcast', 'Overcast', 'Rain'],
    'Temperature': ['Hot', 'Hot', 'Hot', 'Mild', 'Cool', 'Cool', 'Cool', 'Mild', 'Cool', 'Mild', 'Mild', 'Mild', 'Hot', 'Mild'],
    'Humidity': ['High', 'High', 'High', 'High', 'Normal', 'Normal', 'Normal', 'High', 'Normal', 'Normal', 'Normal', 'High', 'Normal', 'High'],
    'Wind': ['Weak', 'Strong', 'Weak', 'Weak', 'Weak', 'Strong', 'Strong', 'Weak', 'Weak', 'Weak', 'Strong', 'Strong', 'Weak', 'Strong'],
    'PlayTennis': ['No', 'No', 'Yes', 'Yes', 'Yes', 'No', 'Yes', 'No', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'No']
})

# 构建决策树
features = ['Outlook', 'Temperature', 'Humidity', 'Wind']
target_attribute = 'PlayTennis'
tree = build_decision_tree(data, data, features, target_attribute)

# 可视化决策树
print("Decision Tree:")
visualize_tree(tree)

通过运行代码,可以看到每个节点选择的分裂特征以及决策树的结构:

Decision Tree:
|--- Temperature = Cool
|   |--- PlayTennis = Yes
|--- Temperature = Hot
|   |--- PlayTennis = No
|--- Temperature = Mild
|   |--- Outlook = Sunny
|   |   |--- Humidity = High
|   |   |   |--- PlayTennis = No
|   |   |--- Humidity = Normal
|   |   |   |--- PlayTennis = Yes
|   |--- Outlook = Rain
|   |   |--- Wind = Weak
|   |   |   |--- PlayTennis = Yes
|   |   |--- Wind = Strong
|   |   |   |--- PlayTennis = No
|   |--- Outlook = Overcast
|   |   |--- PlayTennis = Yes

解释决策树的结构:

根节点是 Temperature,这是第一个选择的分裂特征。
Temperature 的每个取值(Cool, Hot, Mild)对应一个子节点。
如果 Temperature 是 Cool,则 PlayTennis 是 Yes。
如果 Temperature 是 Hot,则 PlayTennis 是 No。
如果 Temperature 是 Mild,则继续分裂 Outlook 属性:
    Outlook 是 Sunny 时,进一步分裂 Humidity 属性:
        Humidity 是 High 时,PlayTennis 是 No。
        Humidity 是 Normal 时,PlayTennis 是 Yes。
    Outlook 是 Rain 时,进一步分裂 Wind 属性:
        Wind 是 Weak 时,PlayTennis 是 Yes。
        Wind 是 Strong 时,PlayTennis 是 No。
    Outlook 是 Overcast 时,PlayTennis 是 Yes。

通过这种方式,决策树会根据每个节点选择最佳的分裂特征,直到所有数据点都被正确分类或没有更多的特征可供分裂。

2.4. 防止过拟合

防止决策树过拟合的方法主要包括剪枝、设置深度限制和样本数量限制。以下是一些常用的方法及其实现:

  1. 预剪枝 (Pre-pruning)

预剪枝是在构建决策树时限制树的增长。常用的方法包括:

设置最大深度:限制树的深度,防止树过深导致过拟合。
设置最小样本分裂数:如果节点中的样本数小于某个阈值,则不再分裂该节点。
设置最小信息增益:如果信息增益小于某个阈值,则不再分裂该节点。
  1. 后剪枝 (Post-pruning)

后剪枝是在决策树完全生长后,剪去一些不重要的分支。常用的方法包括:

代价复杂度剪枝 (Cost Complexity Pruning):基于一个代价复杂度参数 α,剪去那些对降低训练误差贡献较小但增加了模型复杂度的分支。

代价复杂度剪枝 (CCP) 是一种后剪枝技术,用于简化已经完全生长的决策树。CCP 通过引入一个复杂度惩罚参数 α 来权衡决策树的复杂度与其在训练集上的误差。通过调整 α,我们可以控制模型的复杂度,防止过拟合。
原理

CCP 的基本思想是通过最小化以下代价复杂度函数来选择最佳的子树:
在这里插入图片描述
其中:

Rα(T) 是带有复杂度惩罚项的代价复杂度。
R(T)是子树 T 的误差。
α 是复杂度惩罚项,控制模型复杂度与误差之间的权衡。
∣T∣ 是子树 T 的叶节点数量。

较小的 α 值允许更多的节点,使树更加复杂;较大的 α 值会剪去更多的节点,使树更加简单。
代价复杂度剪枝步骤:

构建完全生长的决策树:首先,生成一棵完全生长的决策树,使其充分拟合训练数据。
计算每个子树的误差:对子树中的所有节点计算其误差 R(T)。
计算代价复杂度:对于每个子树,计算其代价复杂度 Rα(T)。
选择合适的 α:通过关系图或交叉验证结果选择最佳的 α 值。
剪枝:根据选定的 α 值,剪去那些对降低误差贡献不大但增加了复杂度的节点。
import numpy as np
import pandas as pd
from sklearn.tree import DecisionTreeClassifier, export_text
import matplotlib.pyplot as plt

# 示例数据
data = pd.DataFrame({
    'Outlook': ['Sunny', 'Sunny', 'Overcast', 'Rain', 'Rain', 'Rain', 'Overcast', 'Sunny', 'Sunny', 'Rain', 'Sunny', 'Overcast', 'Overcast', 'Rain'],
    'Temperature': ['Hot', 'Hot', 'Hot', 'Mild', 'Cool', 'Cool', 'Cool', 'Mild', 'Cool', 'Mild', 'Mild', 'Mild', 'Hot', 'Mild'],
    'Humidity': ['High', 'High', 'High', 'High', 'Normal', 'Normal', 'Normal', 'High', 'Normal', 'Normal', 'Normal', 'High', 'Normal', 'High'],
    'Wind': ['Weak', 'Strong', 'Weak', 'Weak', 'Weak', 'Strong', 'Strong', 'Weak', 'Weak', 'Weak', 'Strong', 'Strong', 'Weak', 'Strong'],
    'PlayTennis': ['No', 'No', 'Yes', 'Yes', 'Yes', 'No', 'Yes', 'No', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'No']
})

# 将特征和目标变量转换为数值编码
data_encoded = pd.get_dummies(data[['Outlook', 'Temperature', 'Humidity', 'Wind']])
target = data['PlayTennis'].apply(lambda x: 1 if x == 'Yes' else 0)

# 拆分数据集
X = data_encoded
y = target

# 构建完全生长的决策树
clf = DecisionTreeClassifier(random_state=0)
clf.fit(X, y)

# 导出决策树规则
tree_rules = export_text(clf, feature_names=list(data_encoded.columns))
print("Original Decision Tree Rules:")
print(tree_rules)

# 计算代价复杂度剪枝路径
path = clf.cost_complexity_pruning_path(X, y)
ccp_alphas, impurities = path.ccp_alphas, path.impurities

# 训练不同复杂度惩罚项的决策树
clfs = []
for ccp_alpha in ccp_alphas:
    clf = DecisionTreeClassifier(random_state=0, ccp_alpha=ccp_alpha)
    clf.fit(X, y)
    clfs.append(clf)

# 绘制复杂度惩罚项与树结构的关系图
node_counts = [clf.tree_.node_count for clf in clfs]
depth = [clf.tree_.max_depth for clf in clfs]

fig, ax = plt.subplots(3, 1, figsize=(10, 10))
ax[0].plot(ccp_alphas, node_counts, marker='o', drawstyle="steps-post")
ax[0].set_xlabel("alpha")
ax[0].set_ylabel("number of nodes")
ax[0].set_title("Number of nodes vs alpha")

ax[1].plot(ccp_alphas, depth, marker='o', drawstyle="steps-post")
ax[1].set_xlabel("alpha")
ax[1].set_ylabel("depth")
ax[1].set_title("Depth vs alpha")

ax[2].plot(ccp_alphas, impurities, marker='o', drawstyle="steps-post")
ax[2].set_xlabel("alpha")
ax[2].set_ylabel("impurity")
ax[2].set_title("Impurity vs alpha")

plt.tight_layout()
plt.show()

# 选择合适的 alpha 进行剪枝并可视化决策树,例如选择 impurity 最小对应的 alpha
# Impurity 反映了决策树在分裂节点时的纯度,纯度越高(impurity 越低),节点中样本越一致,分类效果越好。
optimal_alpha = ccp_alphas[np.argmin(impurities)]
pruned_tree = DecisionTreeClassifier(random_state=0, ccp_alpha=optimal_alpha)
pruned_tree.fit(X, y)

# 导出剪枝后的决策树规则
pruned_tree_rules = export_text(pruned_tree, feature_names=list(data_encoded.columns))

print("Pruned Decision Tree Rules:")
print(pruned_tree_rules)

3. 使用集成方法

  • 随机森林:通过构建多棵决策树并结合它们的预测结果,可以减少单棵树的过拟合。

使用随机森林(Random Forest)是一种有效的方法来防止单个决策树模型的过拟合问题。随机森林通过构建多棵决策树并集成它们的预测结果,从而提高模型的泛化能力。
随机森林防止过拟合的机制:

1. 集成学习:
    随机森林是一种集成学习方法,通过构建多棵决策树,并将它们的预测结果进行投票或平均,从而得到最终的预测结果。这种方式可以有效地减少单棵决策树的高方差,提高模型的稳定性和泛化能力。

2. 随机特征选择:
    在每棵决策树的节点分裂时,随机森林不会考虑所有特征,而是从所有特征中随机选择一个子集来进行分裂。这样可以减少树之间的相关性,提高集成效果。

3. Bootstrap 重采样:
    每棵决策树都是通过对原始训练数据进行 bootstrap 重采样(有放回抽样)得到的不同样本集进行训练。这样每棵树都有不同的训练数据,进一步减少了树之间的相关性。
  • 梯度提升树:通过逐步构建一系列决策树,每棵树修正前一棵树的错误,可以提高模型的泛化能力。

梯度提升树(Gradient Boosting Trees, GBT)是一种集成学习方法,通过逐步构建一系列决策树来提高模型的预测性能。每棵新树的构建是为了修正之前所有树的误差。
梯度提升树防止过拟合的机制:

1. 分阶段训练:
    梯度提升树采用逐步训练的方法。每次构建新树时,模型会根据之前所有树的预测误差来调整新树的结构。这种逐步优化的方法可以有效减少过拟合。

2. 学习率:
    学习率(learning rate)控制每棵树对最终模型的贡献。较小的学习率使得每棵树的影响较小,从而需要更多的树来拟合训练数据。尽管这会增加计算成本,但可以显著降低过拟合的风险。

3. 树的深度:
    限制每棵树的最大深度可以防止单棵树过于复杂,从而避免过拟合。浅层树(通常 3-5 层)虽然不能完全拟合数据,但可以捕捉到数据的主要结构,从而与其他树一起构成一个强大的集成模型。

4. 子样本采样:
    在构建每棵树时,梯度提升树可以对训练数据进行子样本采样(subsampling)。这种方法通过引入训练数据的随机性,减少了模型的方差,从而防止过拟合。

5. 正则化:
    梯度提升树可以引入正则化参数,如 L1 和 L2 正则化,来进一步防止模型的过拟合。

4. 实际应用中的决策树

决策树可以用于多个实际应用,如客户分类、疾病诊断、风险评估等。在实际应用中,需要根据具体问题调整决策树的参数(如树的最大深度、最小样本分裂数等),以达到最佳效果。

使用 TensorFlow 和 NumPy 实现一个简单的决策树分类器

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

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

相关文章

SD-WAN组网如何帮助企业降低网络成本?

企业在构建IT网络时&#xff0c;常常面临节省费用和提升效益的挑战。IT开销主要包括设备、网络和维护成本。利用OgCloud的SD-WAN组网方案&#xff0c;企业可以有效地应对这些问题。 企业专线网络的高成本问题 企业专线的费用较高&#xff0c;而且数据不能同时在多条专线上传输。…

matlab编写微分方程椭圆型方程(一维形式)

文章目录 理论编程实例原代码 理论 椭圆型方程一维格式即常微分方程&#xff0c;边值问题&#xff0c;方程如下所示&#xff1a; 截断误差&#xff1a; 当 h → ∞ h\rightarrow\infty h→∞时&#xff0c;截断误差趋于零&#xff0c;离散方程组成立&#xff0c; 写成矩阵&…

就因为没在大屏项目加全屏按钮,早上在地铁挨了领导一顿骂

“嗯嗯”&#xff0c;“嗯嗯”&#xff0c;“那产品也没说加呀”&#xff0c;“按F11不行吗&#xff1f;”&#xff0c;“嗯嗯”&#xff0c;“好的”。 早上在4号线上&#xff0c;我正坐在地铁里&#xff0c;边上站着的妹子&#xff0c;我看他背着双肩包&#xff0c;打着电话…

算法排序之冒泡排序及优化

public class Bubbling {public static void main(String[] args) {// 定义需要排序的数组int[] arr {0,1,21,2,31,12,5,8};// 冒泡排序方法bubbleSort(arr);bubbleOptSort(arr);}/*** 冒泡排序* param arr 数组*/public static void bubbleSort(int[] arr){// i0&#xff0c;…

IPFoxy代理IP:IPv4与IPv6性能与安全性对比

在使用IPFoxy静态代理IP的过程中&#xff0c;经常有小白朋友疑惑&#xff0c;IPv4与IPv6有何区别&#xff1f;他们在性能与安全上的差别如何&#xff0c;又该如何选择&#xff1f;在这篇博文中&#xff0c;我们将从各个方面为您科普这一区别&#xff0c;帮助您更好的选择。 一、…

ROS 机器人运动控制

ROS 机器人运动控制 机器人运动 当我们拿到一台机器人&#xff0c;其配套的程序源码中&#xff0c;通常会有机器人核心节点&#xff0c;这个核心节点既能够驱动机器人的底层硬件&#xff0c;同时向上还会订阅一个速度话题。我们只需要编写一个新的节点&#xff08;速度控制节点…

【UML用户指南】-19-对基本行为建模-用例图

目录 1、组成结构 2、表示法 3、一般用法 3.1、对主题的语境建模 3.2、对主题的需求建模 4、常用建模技术 4.1、对系统的语境建模 4.1.1、设计过程 4.2、对系统的需求建模 4.2.1、设计过程&#xff1a; 5、正向工程 UML 中的用例图是对系统的动态方面建模的 5 种图之…

4月份最新出品:上海交大动手学大模型教程,快速入门LLM大模型(附课件)

前有 李沐 大神的动手学深度学习 现有 上海交大 的动手学大模型教程&#xff0c;对大模型感兴趣的直接冲&#xff01; 就在4月份上交大发布了动手学大模型教程&#xff0c;这份教程来自上海交大 《人工智能安全技术》 课程讲义拓展&#xff0c;教师是是张倬胜教授。 朋友们…

[Linux] 历史根源

UNIX系统&#xff1a; 1969年&#xff0c;由贝尔实验室的K.Thompson和D.M.Ritchie为PDP-7机器编写的一个分时操作系统&#xff0c; 最初使用汇编语言编写&#xff0c; 后来1972年C语言出世以后&#xff0c;二人由使用C写了UNIX3&#xff0c; 此后UNIX大为流行开来 UNIX流派树&a…

编程精粹—— Microsoft 编写优质无错 C 程序秘诀 01:假想的编译器

这是一本老书&#xff0c;作者 Steve Maguire 在微软工作期间写了这本书&#xff0c;英文版于 1993 年发布。2013 年推出了 20 周年纪念第二版。我们看到的标题是中译版名字&#xff0c;英文版的名字是《Writing Clean Code ─── Microsoft’s Techniques for Developing》&a…

电脑提示d3dcompiler_47.dll丢失的解决方法,实测靠谱的5种方法

在计算机使用过程中&#xff0c;缺失d3dcompiler_47.dll这一系统文件是一个常见问题&#xff0c;尤其是对于游戏和图形密集型应用程序用户来说尤为重要。这个文件是DirectX软件工具包的一部分&#xff0c;主要用于处理图形渲染的应用程序接口的核心元素。当你在运行游戏或某些软…

[面试题]消息队列

[面试题]Java【基础】[面试题]Java【虚拟机】[面试题]Java【并发】[面试题]Java【集合】[面试题]MySQL[面试题]Maven[面试题]Spring Boot[面试题]Spring Cloud[面试题]Spring MVC[面试题]Spring[面试题]MyBatis[面试题]Nginx[面试题]缓存[面试题]Redis[面试题]消息队列 什么是…

什么是进程

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 在了解进程之前&#xff0c;我们需要知道多任务的概念。多任务&#xff0c;顾名思义&#xff0c;就是指操作系统能够执行多个任务。例如&#xff0c;…

微服务必备容器化技术

文章目录 docker介绍与安装及上手应用什么是容器化技术&#xff1f;为什么需要学习docker&#xff1f;如何理解dockerdocker下载与安装docker的基础组成docker体验 dockerfile介绍并创建go-zero环境容器docker的基础组成从容器构建属于go环境的容器基于dockerfile构建go容器镜像…

嵌入式linux系统中SPI子系统验证03

今天主要给大家分享一下&#xff0c;如何使用SPI总线进行验证的方法。 第一&#xff1a;SPI验证流程 1. echo 1 > /dev / spidev3.0 2&#xff0e;逻辑分析仪抓波形 3.十六进指转化为十进制 4.ASCII字符代码表匹配 第二&#xff1a;SPI验证结果 第三&#xff1a;设备…

蚓链数字化生态平台,开启企业未来新篇章!

在如今数字化浪潮势不可挡的时代&#xff0c;企业发展可谓是机遇与挑战并存&#xff01;而蚓链数字化生态平台系统的出现&#xff0c;绝非是给企业一套平平无奇的营销方案或工具那么简单。 它赋予企业的&#xff0c;是在产业生态链中获取海量数据价值的关键且强大的能力&#x…

18个机器学习核心算法模型总结

最强总结&#xff01;18个机器学习核心算法模型&#xff01;&#xff01; 大家好~ 在学习机器学习之后&#xff0c;你认为最重要的算法模型有哪些&#xff1f; 今儿的内容涉及到~ 线性回归逻辑回归决策树支持向量机朴素贝叶斯K近邻算法聚类算法神经网络集成方法降维算法主成…

Weevil-Optimizer象鼻虫优化算法的matlab仿真实现

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 5.完整程序 1.程序功能描述 Weevil-Optimizer象鼻虫优化算法的matlab仿真实现&#xff0c;仿真输出算法的优化收敛曲线&#xff0c;对比不同的适应度函数。 2.测试软件版本以及运行结果展示…

【Redis】基于Redission实现分布式锁(代码实现)

目录 基于Redission实现分布式锁解决商品秒杀超卖的场景&#xff1a; 1.引入依赖&#xff1a; 2.加上redis的配置&#xff1a; 3.添加配置类&#xff1a; 4.编写代码实现&#xff1a; 5.模拟服务器分布式集群的情况&#xff1a; 1.右键点击Copy Configuration 2.点击Modi…

虚拟现实环境下的远程教育和智能评估系统(十)

VR部署测试&#xff0c;采集眼动数据&#xff1b; 经VR内置Camera采集眼睛注视位置后&#xff0c;输出.txt形式的眼动结果&#xff1a; 经处理后&#xff0c;将射线方向和位置投影到视频屏幕二维坐标的位置&#xff1a; 在视频中可视化如下&#xff1a;