机器学习实验作业

news2024/12/26 18:17:47

根据本章所学内容,选取任一机器学习算法(包括神经网络),编写对应代码。并简述梯度下降算法的原理和流程、什么是过拟合及其解决方案、如何根据混淆矩阵计算准确率等指标。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.metrics import precision_recall_curve, confusion_matrix, recall_score, precision_score, accuracy_score, \
    f1_score, roc_curve, auc
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV
import seaborn as sns

from 逻辑回归 import List_score, AUC

pd.set_option('display.max_columns', None)


def data_read():
    df = pd.read_csv(r"C:\Users\zhang\Desktop\附件133.csv", encoding="gbk")
    df.rename(columns={'Y(1=default, 0=non-default)': 'Y'}, inplace=True)
    return df


def get_category_bin(df, col, binsnum, labels, qcut=False):
    ## 这块没考虑null和"",之后优化代码可以考虑
    if qcut:
        localdf = pd.qcut(df[col], q=binsnum, labels=labels)
    else:
        localdf = pd.cut(df[col], bins=binsnum, labels=labels)  # equal-length cut  可以根据指定分界点对连续数据进行分箱处理
    localdf = pd.DataFrame(localdf)
    name = col + '_' + 'bin'
    localdf[name] = localdf[col]
    df = df.join(localdf[name])  ## 新增加一列 连接进去
    df = df.drop(i, axis=1)
    df[name] = df[name].astype(object)
    return df


def category_continue_separation(df, feature_names):
    categorical_var = []
    numerical_var = []
    if 'Y' in feature_names:
        feature_names.remove('Y')
    if '编号' in feature_names:
        feature_names.remove('编号')
    ##先判断类型,如果是int或float就直接作为连续变量
    numerical_var = list(df[feature_names].select_dtypes(
        include=['int', 'float', 'int32', 'float32', 'int64', 'float64']).columns.values)
    categorical_var = numerical_var
    return categorical_var, numerical_var


def data_analysis_plot(categorical_var, df, start, mid, row, col, showlabel=False):
    p = 1
    plt.figure(figsize=(20, 18))
    for i in categorical_var[start:mid]:
        df_var = "df_" + i
        df_var = pd.crosstab(df[i], df["Y"])
        df_var["bad_rate"] = round(df_var[1] / (df_var[1] + df_var[0]), 4)
        # print('df_var', df_var)
        # print(df_var.index)
        # print(df_var.columns)
        # print(p)

        # 添加子区间绘制,
        ax1 = plt.subplot(row, col, p)  # 子区空间为n行n列

        year = df_var.index  # 横坐标
        data1 = df_var[0]  # 纵坐标 好用户
        data2 = df_var[1]  # 纵坐标 坏用户
        data3 = df_var["bad_rate"]

        # 先得到year长度, 再得到下标组成列表
        x = range(len(year))
        bar_width = 0.3

        # 好坏用户柱状图
        ax1.bar(x, data1, width=bar_width, color='#3A669C', label="好用户")
        # 向右移动0.2, 柱状条宽度为0.2
        ax1.bar([i + bar_width for i in x], data2, width=bar_width, color='#C0504D', label="违约用户")

        # 底部汉字移动到两个柱状条中间(本来汉字是在左边蓝色柱状条下面, 向右移动0.1)
        plt.xticks([i + bar_width / 2 for i in x], year)
        if p == 1 or p == col + 1:
            ax1.set_ylabel('用户数量', size=10)
        ax1.set_xlabel(i, size=10)

        text_heiht = 3
        # 为每个条形图添加数值标签
        for x1, y1 in enumerate(data1):
            ax1.text(x1, y1 + text_heiht, y1, ha='center', fontsize=8)
        for x2, y2 in enumerate(data2):
            ax1.text(x2 + bar_width, y2 + text_heiht, y2, ha='center', fontsize=8)

        # bad_rate线 共用纵坐标轴
        ax2 = ax1.twinx()
        p3 = ax2.plot([i + bar_width / 2 for i in x], data3, color="gray", linestyle='--', label="坏用户占比")

        if p == 3 or p == 6:
            ax2.set_ylabel("坏用户占比")

        if p == 1 and showlabel == True:
            ax1.legend(loc="upper center")
            ax2.legend(loc=2)

        p = p + 1

    plt.show()


def data_analysis_plot_num(numerical_var, df, start, mid, row, col, showlabel=False):
    p = 1
    plt.figure(figsize=(20, 18))
    for i in numerical_var[start:mid]:
        df_var = "df_" + i
        df_var = pd.DataFrame({'Y': df["Y"], 'variables': df[i]})
        df_var_good = df_var.loc[df_var["Y"] == 0,]
        df_var_good = df_var_good.sort_values(["variables"])  # 排序
        df_var_bad = df_var.loc[df_var["Y"] == 1,]
        df_var_bad = df_var_bad.sort_values(["variables"])  # 排序
        plt.subplot(row, col, p)  # 子区空间为2行3列
        if i == "period" or i == "age":
            bins_i = 60
        elif i == "credit_limit":
            bins_i = 150
        else:
            bins_i = 50
        plt.rcParams['font.sans-serif'] = ['SimHei']  # 设置中文字体为黑体
        plt.rcParams['axes.unicode_minus'] = False  # 解决负号显示问题
        plt.hist(df_var_good["variables"], bins=bins_i, color='r', alpha=0.5, rwidth=0.6, density=True, label='好用户')
        plt.hist(df_var_bad['variables'], bins=bins_i, color='b', alpha=0.5, rwidth=0.6, density=True, label='坏用户')
        plt.legend()
        if p == 1:
            plt.title('好坏用户分布直方图')
        plt.xlabel(i)
        plt.ylabel('count')
        p = p + 1
    plt.show()


# 计算iv值
def calc_iv(df, feature, target, pr=False):
    lst = []
    df[feature] = df[feature].fillna("NULL")
    for i in range(df[feature].nunique()):  ## 计数,不同值的个数
        val = list(df[feature].unique())[i]  ## 取出几个不同的值
        lst.append([feature,  # Variable
                    val,  # Value
                    df[df[feature] == val].count()[feature],  # All
                    df[(df[feature] == val) & (df[target] == 0)].count()[feature],  # Good (think: Fraud == 0)
                    df[(df[feature] == val) & (df[target] == 1)].count()[feature]])  # Bad (think: Fraud == 1)

    # 整理成dataframe 通常计算woe iv的格式
    data = pd.DataFrame(lst, columns=['Variable', 'value', 'All', 'Good', 'Bad'])

    data['Share'] = data['All'] / data['All'].sum()
    data['Bad Rate'] = data['Bad'] / data['All']

    # woe的计算
    # data['Distribution Good'] = (data['All'] - data['Bad']) / (data['All'].sum() - data['Bad'].sum())
    data['Distribution Good'] = (data['Good']) / (data['Good'].sum())
    data['Distribution Bad'] = data['Bad'] / data['Bad'].sum()
    data['WoE'] = np.log(data['Distribution Good'] / data['Distribution Bad'])
    data = data.replace({'WoE': {np.inf: 0, -np.inf: 0}})

    # iv的计算
    data['IV'] = data['WoE'] * (data['Distribution Good'] - data['Distribution Bad'])
    data = data.sort_values(by=['Variable', 'value'], ascending=[True, True])
    data.index = range(len(data.index))

    if pr:
        print(data)
        print('IV = ', data['IV'].sum())

    # 变量的iv值
    iv = data['IV'].sum()
    print('This variable\'s IV is:', iv)
    print(df[feature].value_counts())
    return iv, data


df = data_read()
y = df.iloc[:, -1]
for i in ['X2', 'X4', 'X10']:
    df = get_category_bin(df, i, 5, [1, 2, 3, 4, 5], qcut=False)
df.to_excel(r"C:\Users\zhang\Desktop\分箱.xlsx")
feature_names = df.columns.tolist()
categorical_var, numerical_var = category_continue_separation(df, feature_names)
data_analysis_plot(categorical_var, df, 0, 22, 3, 7, showlabel=True)
df.describe()
data_analysis_plot_num(numerical_var, df, 0, 22, 3, 7, showlabel=False)
data_train, data_test = train_test_split(df, test_size=0.2, random_state=10, stratify=df.Y)
for s in set(numerical_var):
    print('变量' + s + '可能取值' + str(len(data_train[s].unique())))
    if len(data_train[s].unique()) <= 10:
        categorical_var.append(s)
        numerical_var.remove(s)
        ##同时将后加的数值变量转为字符串
        index_1 = data_train[s].isnull()
        if sum(index_1) > 0:
            data_train.loc[~index_1, s] = data_train.loc[~index_1, s].astype('str')
        else:
            data_train[s] = data_train[s].astype('str')
        index_2 = data_test[s].isnull()
        if sum(index_2) > 0:
            data_test.loc[~index_2, s] = data_test.loc[~index_2, s].astype('str')
        else:
            data_test[s] = data_test[s].astype('str')
data_test.info()
data_train.info()
ivtable = pd.DataFrame(columns=['Feature', 'IV'])
for feature in feature_names:
    iv, _ = calc_iv(df, feature, target='Y', pr=True)
    ivtable = pd.concat([ivtable, pd.DataFrame({'Feature': [feature], 'IV': [iv]})], ignore_index=True)

ivtable_dict = dict(zip(ivtable['Feature'], ivtable['IV']))
print('ivtable', ivtable)

df_iv_values = pd.DataFrame.from_dict(ivtable_dict, orient='index')
df_iv_values.columns = ['iv']
df_iv_values = df_iv_values.sort_values(by=["iv"], ascending=False)
df_iv_cols = list(df_iv_values[df_iv_values['iv'] >= 0.02].index)
df_iv_cols.append('Y')
print(df_iv_cols)
columns_to_drop = [col for col in df.columns if col not in df_iv_cols]
df_woe = df.copy()
df_woe.drop(columns_to_drop, axis=1, inplace=True)

# 假设 df 是你的 DataFrame
# 指定所需的列顺序列表
desired_column_order = ['X1', 'X2_bin', 'X3', 'X4_bin', 'X5', 'X6', 'X7', 'X9', 'X10_bin', 'X11', 'X15', 'X16', 'X18',
                        'X20', 'Y']
# 使用 reindex 方法调整列的顺序
df_woe = df_woe.reindex(columns=desired_column_order)
data_train_woe, data_test_woe = train_test_split(df_woe, test_size=0.2, random_state=10, stratify=df_woe.Y)

correlation_table = pd.DataFrame(data_train_woe.corr())
correlation_table.to_excel(r"C:\Users\zhang\Desktop\correlation.xlsx")
plt.figure(figsize=(18, 10))
sns.heatmap(correlation_table)
plt.subplots_adjust(bottom=0.3, left=0.3)
plt.show()
data_train_woe.to_excel(r"C:\Users\zhang\Desktop\data_train_woe.xlsx")
##训练模型
####取出训练数据与测试数据
x_train = np.array(data_train_woe[[i for i in data_train_woe.columns if i != 'Y']])
y_train = np.array(data_train_woe.Y)

x_test = np.array(df_woe[[i for i in df_woe.columns if i != 'Y']])
y_test = np.array(df_woe.Y)
##网络搜索查找最优参数
lr_param = {'C': [0.01, 0.1, 0.2, 0.5, 1, 1.5, 2],
            'class_weight': [{1: 1, 0: 1}, {1: 2, 0: 1}, {1: 3, 0: 1}, 'balanced'],
            'max_iter': range(0, 3000, 300)}

##逻辑回归模型
lr_gsearch = GridSearchCV(
    estimator=LogisticRegression(random_state=0, fit_intercept=True, penalty='l2'),
    param_grid=lr_param, cv=5, scoring='f1', n_jobs=-1, verbose=2)

##执行超参数优化
lr_gsearch.fit(x_train, y_train)
print('logistic model best_score_ is {0},and best_params_ is {1}'.format(lr_gsearch.best_score_,
                                                                         lr_gsearch.best_params_))

##用最优参数,初始化Logistic模型
LR_model_2 = LogisticRegression(C=lr_gsearch.best_params_['C'], penalty='l2',
                                class_weight=lr_gsearch.best_params_['class_weight'],
                                max_iter=lr_gsearch.best_params_['max_iter'])
##训练Logistic模型
LR_model_fit = LR_model_2.fit(x_train, y_train)
# 预测概率值
y_score_test = LR_model_fit.predict_proba(x_test)[:, 1]

##计算不同概率阈值的精确召回对
test_precision, test_recall, thresholds = precision_recall_curve(y_test, y_score_test)

##区分测试集中真实的好坏样本数据
df_pre_all = pd.DataFrame({'y_score': y_score_test, 'y_test': y_test})
df_pre_good = df_pre_all.loc[df_pre_all["y_test"] == 0,]
df_pre_good = df_pre_good.sort_values(["y_score"])
df_pre_bad = df_pre_all.loc[df_pre_all["y_test"] == 1,]
df_pre_bad = df_pre_bad.sort_values(["y_score"])
# print('df_pre_good', df_pre_good)
# print('df_pre_bad', df_pre_bad)
##结果绘图
plt.figure(figsize=(10, 6))
plt.hist(df_pre_good["y_score"], bins=100, color='r', alpha=0.5, rwidth=0.6, density=True, label='未逾期')
plt.hist(df_pre_bad['y_score'], bins=100, color='b', alpha=0.5, rwidth=0.6, density=True, label='逾期')
plt.legend()
plt.title('信用情况分布直方图')
plt.xlabel('predict y proba')
plt.ylabel('count')
plt.show()

##计算混淆矩阵、P、R 与f1-score
y_pred = LR_model_fit.predict(x_test)
cnf_matrix = confusion_matrix(y_test, y_pred, labels=[0, 1])  # 混淆矩阵
recall_value = recall_score(y_test, y_pred)
precision_value = precision_score(y_test, y_pred)
acc = accuracy_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
print(cnf_matrix)
print('Validation set:  model recall is {0},and percision is {1},and f1-score is {2}'.format(recall_value,
                                                                                             precision_value, f1))
###绘制混淆矩阵
f, ax = plt.subplots()
sns.heatmap(cnf_matrix, annot=True, ax=ax)  # 画热力图
ax.set_title('混淆矩阵')  # 标题
ax.set_xlabel('predict')  # x轴
ax.set_ylabel('true')  # y轴
plt.show()

##绘制pr曲线,需要用到上面计算的不同概率阈值的精确召回对
# 计算不同概率阈值的精确召回对

plt.figure(figsize=(12, 6))
lw = 2
fontsize_1 = 16
plt.plot(test_recall, test_precision, color='darkorange', lw=lw)
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xticks(fontsize=fontsize_1)
plt.yticks(fontsize=fontsize_1)
plt.xlabel('Recall', fontsize=fontsize_1)
plt.ylabel('Precision', fontsize=fontsize_1)
plt.title('PR曲线', fontsize=fontsize_1)
plt.show()

##计算TPR FPR ROC曲线 AUC AR gini等
fpr, tpr, thresholds = roc_curve(y_test, y_score_test)
roc_auc = auc(fpr, tpr)
ar = 2 * roc_auc - 1
gini = ar
ks = max(tpr - fpr)
print('test set:  model AR is {0},and ks is {1},auc={2}'.format(ar,
                                                                ks, roc_auc))
##绘制ROC曲线
plt.figure(figsize=(10, 6))
lw = 2
fontsize_1 = 16
plt.plot(fpr, tpr, color='darkorange', lw=lw, label='ROC curve(area=%.2f)' % roc_auc)
plt.plot([0, 1], [0, 1], color='navy', lw=lw, linestyle='--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.05])
plt.xticks(fontsize=fontsize_1)
plt.yticks(fontsize=fontsize_1)
plt.xlabel('FPR', fontsize=fontsize_1)
plt.ylabel('TPR', fontsize=fontsize_1)
plt.title('ROC曲线', fontsize=fontsize_1)
plt.legend(loc='lower right', fontsize=fontsize_1)
plt.show()

P0 = 100
PDO = 10
theta0 = 1.0 / 20
B = PDO / np.log(2)
A = P0 + B * np.log(theta0)
print("A:", A)
print("B:", B)

##x的权重与偏置项
list_coef = list(LR_model_fit.coef_[0])
intercept = LR_model_fit.intercept_
print('list_coef', list_coef)
print('intercept', intercept)

# LR_model_fit.predict_proba(x_test)全部x的预测概率 包括好客户和坏客户 index=0为好客户,index=1为坏客户
# 获取全部x数据预测为坏用户的概率
pos_probablity_list = LR_model_fit.predict_proba(x_test)[:, 1]
print('pos_probablity_list', pos_probablity_list)


def score(pos_probablity_list, A, B):
    list = []
    for i in pos_probablity_list:
        score = A - B * np.log(i / (1 - i))
        list.append(score)
    return list
list_score1 = List_score(pos_probablity_list)
auc_value = AUC(y, list_score1)
print("auc_value:",auc_value)
# 获取全部测试样本分数
list_score = score(pos_probablity_list, A, B)
list_predict = LR_model_fit.predict(x_test)
df_result = pd.DataFrame(
    {"label": y_test, "predict": list_predict, "pos_probablity": pos_probablity_list, "score": list_score})
df_result.to_excel(r"C:\Users\zhang\Desktop\score_proba1.xlsx")
print('df_result', df_result)

缺少的文件和代码库见:
通过网盘分享的文件:机器学习数据
链接: https://pan.baidu.com/s/1yR_Mp5zSUYiZl-H17_Cuvw?pwd=bebw 提取码: bebw
–来自百度网盘超级会员v4的分享

代码解读:
导入必要的库和自定义函数:代码开始部分导入了数据处理、数值计算、数据可视化、机器学习模型构建和评估所需的库,以及自定义的 List_score 和 AUC 函数。
数据读取与预处理:通过 data_read 函数读取CSV文件,并重命名目标变量。接着,对特定的连续变量进行分箱处理,以便于后续的模型训练。
特征工程:代码中定义了函数来分离分类变量和连续变量,并对低基数的连续变量进行特殊处理,将它们转换为分类变量。此外,还计算了每个特征的信息值(IV),以评估特征的重要性。
数据集划分与模型训练:将数据集划分为训练集和测试集,使用逻辑回归模型进行训练,并通过 GridSearchCV 进行超参数优化,以找到最佳的模型参数。
模型评估与可视化:评估模型的性能,包括精确度、召回率、F1分数等,并绘制混淆矩阵、PR曲线和ROC曲线。同时,计算AUC值以衡量模型的分类能力。
评分卡模型构建:根据逻辑回归模型的系数和截距,计算评分卡模型的A和B参数,用于将预测概率转换为评分。
结果保存:最后,将模型的预测概率和评分结果保存到Excel文件中,便于进一步分析和应用。

1.梯度下降算法的原理和流程
梯度下降(Gradient Descent)通过迭代的方式更新参数,使目标函数的值不断减小,从而找到函数的最小值点。具体而言,算法通过计算目标函数在当前参数点处的梯度,然后按照梯度的反方向更新参数,不断迭代直到满足停止条件,梯度下降就像在一个山谷中行走,不断迈出在当前位置下降最快的那一步,直到找到一个最低点也就是收敛点,当然这个点可能是局部最优解而非全局最优解。

目标函数:通常是损失函数(例如,均方误差、交叉熵等),表示模型预测与实际标签之间的差异。我们希望通过调整模型的参数,使得损失函数的值最小。
梯度:是目标函数对每个参数的导数,表示损失函数在参数空间的变化率。梯度指出了参数值的增加方向,因此为了最小化损失函数,我们需要沿着梯度的反方向调整参数。
学习率:学习率(learning rate)是一个超参数,决定了每次调整步长的大小。学习率太大可能导致跳过最优解,太小则可能导致收敛速度过慢。
流程:
初始化模型参数(如权重和偏置)。
计算损失函数和每个参数的梯度。
更新参数:将参数沿梯度的反方向更新。
重复步骤 2 和 3,直到损失函数收敛(即变化非常小)或达到最大迭代次数。
2. 过拟合及其解决方案
过拟合(Overfitting)是指模型在训练数据上表现得很好,但在新数据(如验证集或测试集)上表现较差的现象。过拟合通常发生在模型过于复杂,学习到了训练数据中的噪声和细节,而这些细节在测试数据上并不具备代表性。

表现:
训练误差非常低,而验证误差较高。
模型在训练数据上“记忆”了很多细节,导致对新数据的泛化能力差。
解决过拟合的方法:
减少模型复杂度:选择更简单的模型(如减少层数或每层神经元数量)可以防止模型过度拟合。
增加训练数据量:更多的数据可以帮助模型更好地捕捉数据的真实规律,而不是噪声。
使用正则化技术:
L1/L2正则化:通过在损失函数中添加一个惩罚项,限制模型权重的大小。
Dropout:在训练过程中随机丢弃一定比例的神经元,减少模型对某些特定神经元的依赖。
数据增强:通过对训练数据进行旋转、平移、缩放等变换,增加数据的多样性。
提前停止(Early Stopping):监控验证集的损失,当验证集损失不再下降时停止训练。
交叉验证:使用K折交叉验证来评估模型的性能,确保模型对不同数据集的泛化能力。
3. 如何根据混淆矩阵计算准确率等指标
混淆矩阵(Confusion Matrix)是一个用于评估分类模型性能的工具,显示了模型在各个类别上的预测结果。它由 4 个部分组成:

TP(True Positive):真正例,正确预测为正类的样本数。
TN(True Negative):真反例,正确预测为负类的样本数。
FP(False Positive):假正例,错误预测为正类的样本数。
FN(False Negative):假反例,错误预测为负类的样本数。
混淆矩阵通常用于二分类问题,但也可以扩展到多分类问题。

准确率和其他常见指标计算:
准确率(Accuracy):模型预测正确的样本占总样本的比例。
精确率(Precision):预测为正类的样本中实际为正类的比例,表示预测正类的准确性。
召回率(Recall):实际为正类的样本中被预测为正类的比例,表示模型发现正类样本的能力。
F1 分数(F1-Score):精确率和召回率的调和平均数,平衡了精确率和召回率。

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

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

相关文章

微信小程序介绍-以及写项目流程(重要)

前言&#xff1a;本篇文章介绍微信小程序以及项目介绍&#xff1a; 文章介绍&#xff1a;介绍了微信小程序常用的指令、组件、api。tips&#xff1a;最好按照官方文档来进行学习&#xff0c;大致可以我的目录来学习&#xff0c;对于写项目是没有问题的 微信小程序官方文档https…

嵌入式蓝桥杯学习5 定时中断实现按键

Cubemx配置 打开cubemx。 前面的配置与前文一样&#xff0c;这里主要配置基本定时器的定时功能。 1.在Timer中点击TIM6&#xff0c;勾选activated。配置Parameter Settings中的预分频器&#xff08;PSC&#xff09;和计数器&#xff08;auto-reload Register&#xff09; 补…

特别分享!SIM卡接口功能及其电路设计相关注意事项

SIM卡接口功能及其电路设计相关注意事项对电子工程师来说非常重要。SIM卡接口用于连接SIM卡并读取SIM卡信息&#xff0c;以便在注册4G网络时进行鉴权身份验证&#xff0c;是4G通信系统的必要功能。 一、SIM卡接口功能描述 Air700ECQ/Air700EAQ/Air700EMQ系列模组支持1路USIM接…

OpenGL ES详解——文字渲染

目录 一、文字渲染 二、经典文字渲染&#xff1a;位图字体 1.概念 2.优缺点 三、现代文字渲染&#xff1a;FreeType 1.着色器 2.渲染一行文字 四、关于未来 一、文字渲染 当你在图形计算领域冒险到了一定阶段以后你可能会想使用OpenGL来绘制文字。然而&#xff0c;可能…

devops-Dockerfile+Jenkinsfile方式部署Java前后端应用

文章目录 概述部署前端Vue应用一、环境准备1、Dockerfile2、.dockerignore3、nginx.conf4、Jenkinsfile 二、Jenkins部署1、新建任务2、流水线3、Build Now 构建 & 访问 Springboot后端应用1. 准备工作2. 创建项目结构3. 编写 Dockerfile后端 Dockerfile (backend/Dockerfi…

VTK编程指南<三>:基于VTK入门程序解析来理解VTK基础知识

1、VTK入门程序 下面是一个完整的Vtk入门程序&#xff0c;我们基于这个程序来对VTK的基本知识进行一个初步了解。 #include <iostream>#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL2);// VTK was built with vtkRenderingOpenGL2 VTK_MODULE_INI…

十二、消息队列-MQ

文章目录 前言一、MQ介绍1. 背景2. 解决思路3. 解决方案 二、应用场景三、常见的MQ产品四、MQ选型总结五、相关知识1. AMQP2. JMS 五、如何设计实现一个消息队列1. 设计消息队列的思路2. 实现队列基本功能1. RPC通信协议2. 高可用3. 服务端承载消息堆积的能力4. 存储子系统的选…

新手如何做好一份技术文档

对于新手来说&#xff0c;编写技术文档可能是一项挑战&#xff0c;但这也是一个提升自己技术写作能力的绝佳机会。技术文档不仅仅是代码的补充说明&#xff0c;它更是团队协作和项目成功的基石。本文将为你提供一些实用的指导和建议&#xff0c;帮助你编写出一份高质量的技术文…

如何设置PPT以“只读方式”打开?3种简单方法!

在PPT中设置文件为“只读”模式&#xff0c;可以防止自己意外修改&#xff0c;也可以防止他人对文件内容进行修改&#xff0c;确保文件的安全性。根据需求不同&#xff0c;PPT可以设置3种不同的”只读方式“&#xff0c;一起来看看吧&#xff01; 方式1&#xff1a;设置文件为只…

DICOM医学影象应用篇——多平面重建(MPR)在DICOM医学影像中的应用详解

目录 MPR(多平面重建)概述 基本原理 具体实现 代码详解 总结 MPR(多平面重建)概述 多平面重建&#xff08;MPR, Multi-Planar Reconstruction&#xff09;是一项用于从三维医学影像数据集中生成不同平面的二维切片的技术。通常应用于CT或MRI数据集&#xff0c;MPR可以帮助医…

Vue前端开发-多级路由配置

在Vue 路由数组中&#xff0c;允许配置多级的路由对象结构&#xff0c;可以是二级、三级或者更多级别&#xff0c;最大级别原则上没有限制&#xff0c;但通常最大的是三或四级&#xff0c;这种路由结构&#xff0c;称之为多级路由。 例如&#xff1a;一级路由地址/list&#x…

【二分查找】力扣 875. 爱吃香蕉的珂珂

一、题目 二、思路 速度 k&#xff08;单位&#xff1a;根/小时&#xff09;是存在一个取值范围的。 速度越大肯定在规定的时间之内一定会吃完全部的香蕉&#xff0c;但也是可以确定出一个上界的。由于只要保证一小时之内&#xff0c;可以吃完香蕉数目最多的那一堆的香蕉&…

C语言——指针基础

1 指针基础 怎么获得变量地址 1 如何产生一个指针变量——>类型* 标识符;int* p1;char* p2;double* p3;//不同类型的基本指针占用内存是一样的都是4个字节&#xff08;32位&#xff09;/8个字节&#xff08;64位&#xff09;&#xff0c;都是存的地址2 数组名是数组首地址…

Leetcode day1.两数相加(2) 2.整数反转(7)

注意点&#xff1a;1.链表会出现其中一个已经为空&#xff0c;另一个缺还是有数据 2.相加时会出现进位操作 解法一、 利用队列的性质&#xff08;基础不好 第一时间想到的&#xff09; 很像队列的性质&#xff0c;先进先出&#xff0c;逐步计算。但是最后要换成链表样式。 …

在Ubuntu-22.04 [WSL2]中配置Docker

文章目录 0. 进入Ubuntu-22.041. 更新系统软件包2. 安装Docker相关依赖包3. 添加Docker官方GPG密钥4. 添加Docker软件源5. 安装Docker Engine5.1 更新软件包列表5.2 安装Docker相关软件包 6. 验证Docker安装是否成功6.1 查看Docker版本信息6.2 启动Docker6.3 配置镜像加速器6.4…

51单片机应用开发(进阶)---串口接收字符命令

实现目标 1、巩固UART知识&#xff1b; 2、掌握串口接收字符数据&#xff1b; 3、具体实现目标&#xff1a;&#xff08;1&#xff09;上位机串口助手发送多字符命令&#xff0c;单片机接收命令作相应的处理&#xff08;如&#xff1a;openled1 即打开LED1;closeled1 即关…

【查询基础】.NET开源 ORM 框架 SqlSugar 系列

&#x1f4a5; .NET开源 ORM 框架 SqlSugar 系列 &#x1f389;&#x1f389;&#x1f389; 【开篇】.NET开源 ORM 框架 SqlSugar 系列【入门必看】.NET开源 ORM 框架 SqlSugar 系列【实体配置】.NET开源 ORM 框架 SqlSugar 系列【Db First】.NET开源 ORM 框架 SqlSugar 系列…

基于Matlab BP神经网络的电力负荷预测模型研究与实现

随着电力系统的复杂性和规模的不断增长&#xff0c;准确的电力负荷预测对于电网的稳定性和运行效率至关重要。传统的负荷预测方法依赖于历史数据和简单的统计模型&#xff0c;但这些方法在处理非线性和动态变化的负荷数据时&#xff0c;表现出较大的局限性。近年来&#xff0c;…

LeetCode - #150 逆波兰表达式求值

文章目录 前言1. 描述2. 示例3. 答案关于我们 前言 我们社区陆续会将顾毅&#xff08;Netflix 增长黑客&#xff0c;《iOS 面试之道》作者&#xff0c;ACE 职业健身教练。&#xff09;的 Swift 算法题题解整理为文字版以方便大家学习与阅读。 LeetCode 算法到目前我们已经更新…

mysql基础学习1

useradd -r -g mysql -s /bin/false mysql (-r)系统用户 不能登录 A temporary password is generated for rootlocalhost: d>#jT7rfoaz) 看是否启动 看进程 端口 直接连接 看日志 varchar (20) char(20)更耗空间 create table student_info(id int,name varchar(20),s…