深度学习之构建MPL神经网络——泰坦尼克号乘客的生存分析
大家好,我是带我去滑雪!
本期使用泰坦尼克号数据集,该数据集的响应变量为乘客是生存还是死亡(survived,其中1表示生存,0表示死亡),特征变量有乘客舱位等级(pclass)、乘客姓名(name)、乘客性别(sex,其中male为男性,female为女性)、乘客年龄(age)、兄弟姊妹或者配偶在船上的人数(sibsp)、父母或子女在船上的人数(parch)、船票号码(ticket)、船票费用(fare)、舱位号码(cabin)、登船的港口号码(embarked,其中有C、Q、S三个港口)。
前一期已经写过《使用Keras构建分类问题的MLP神经网络——用于糖尿病预测》关于搭建MPL神经网络了,这里继续练习的原因是那篇文章所用的数据集是已经处理好了的,可以直接使用。但现实经常是一份没有经过任何处理的数据集,那么我们该怎么对数据进行预处理,进而再搭建MPL神经网络,这是本期主要学习的重点。
目录
1、数据预处理
(1)观察数据
(2)寻找缺失值
(3)删除多余字段
(4)填补缺失值
(5)转化分类数据
(6)将不是分类数据的embarked字段进行独立热编码
(7)移动响应变量到数据框最后一列
2、划分训练集和测试集,并保存划分的数据集
3、搭建MPL神经网络模型
4、编译模型、训练模型、评估模型
5、绘制训练集和验证集的损失分数趋势图、准确率趋势图
6、使用最佳训练周期训练模型,并保存模型结果和权重
7、使用训练好的模型进行预测
1、数据预处理
(1)观察数据
import numpy as np
import pandas as pd
from tensorflow.keras.models import Sequential#导入Sequential模型
from tensorflow.keras.layers import Dense#导入Dense全连接层
df = pd.read_csv(r'E:\工作\硕士\博客\博客32-深度学习之构建MPL神经网络——泰坦尼克号乘客的生存分析\titanic_data.csv')
df输出结果:
pclass survived name sex age sibsp parch ticket fare cabin embarked 0 1 1 Allen Miss. Elisabeth Walton female 29.0000 0 0 24160 211.3375 B5 S 1 1 1 Allison Master. Hudson Trevor male 0.9167 1 2 113781 151.5500 C22 C26 S 2 1 0 Allison Miss. Helen Loraine female 2.0000 1 2 113781 151.5500 C22 C26 S 3 1 0 Allison Mr. Hudson Joshua Creighton male 30.0000 1 2 113781 151.5500 C22 C26 S 4 1 0 Allison Mrs. Hudson J C (Bessie Waldo Daniels) female 25.0000 1 2 113781 151.5500 C22 C26 S ... ... ... ... ... ... ... ... ... ... ... ... 1304 3 0 Zabour Miss. Hileni female 14.5000 1 0 2665 14.4542 NaN C 1305 3 0 Zabour Miss. Thamine female NaN 1 0 2665 14.4542 NaN C 1306 3 0 Zakarian Mr. Mapriededer male 26.5000 0 0 2656 7.2250 NaN C 1307 3 0 Zakarian Mr. Ortin male 27.0000 0 0 2670 7.2250 NaN C 1308 3 0 Zimmerman Mr. Leo male 29.0000 0 0 315082 7.8750 NaN S 1309 rows × 11 columns
使用describe()函数得到数据描述统计:
print(df.describe())
输出结果:
pclass survived age sibsp parch \ count 1309.000000 1309.000000 1046.000000 1309.000000 1309.000000 mean 2.294882 0.381971 29.881135 0.498854 0.385027 std 0.837836 0.486055 14.413500 1.041658 0.865560 min 1.000000 0.000000 0.166700 0.000000 0.000000 25% 2.000000 0.000000 21.000000 0.000000 0.000000 50% 3.000000 0.000000 28.000000 0.000000 0.000000 75% 3.000000 1.000000 39.000000 1.000000 0.000000 max 3.000000 1.000000 80.000000 8.000000 9.000000 fare count 1308.000000 mean 33.295479 std 51.758668 min 0.000000 25% 7.895800 50% 14.454200 75% 31.275000 max 512.329200
通过对比可以发现age和fare的数量不是1309,说明可能存在缺失值。
(2)寻找缺失值
#寻找缺失值
print(df.info())
输出结果:
<class 'pandas.core.frame.DataFrame'> RangeIndex: 1309 entries, 0 to 1308 Data columns (total 11 columns):# Column Non-Null Count Dtype --- ------ -------------- ----- 0 pclass 1309 non-null int64 1 survived 1309 non-null int64 2 name 1309 non-null object 3 sex 1309 non-null object 4 age 1046 non-null float645 sibsp 1309 non-null int64 6 parch 1309 non-null int64 7 ticket 1309 non-null object 8 fare 1308 non-null float649 cabin 295 non-null object 10 embarked 1307 non-null object dtypes: float64(2), int64(4), object(5) memory usage: 112.6+ KB None# 显示没有数据料的条数
print(df.isnull().sum())输出结果:
pclass 0 survived 0 name 0 sex 0 age 263 sibsp 0 parch 0 ticket 0 fare 1 cabin 1014 embarked 2 dtype: int64
通过上述操作可以发现,age、fare、cabin、embarked都存在缺失值,其中age存在263条,fare存在1条,cabin存在1014条,embarked存在2条。
(3)删除多余字段
数据中name、ticket、cabin均是一些文本数据,对于后续构建神经网络没有帮助,将其均剔除。
df = df.drop(["name", "ticket", "cabin"], axis=1)
(4)填补缺失值
age和fare的缺失值均使用平均值进行填补,embarked的缺失值使用计算C、Q、S个数据并排序,缺失值填入个数最多的S进行填补。
# 填补缺失数据
df[["age"]] = df[["age"]].fillna(value=df[["age"]].mean())
df[["fare"]] = df[["fare"]].fillna(value=df[["fare"]].mean())
df[["embarked"]] = df[["embarked"]].fillna(value=df["embarked"].value_counts().idxmax())
print(df[["age"]])
print(df[["fare"]])
print(df["embarked"].value_counts())
print(df["embarked"].value_counts().idxmax())输出结果:
age 0 29.000000 1 0.916700 2 2.000000 3 30.000000 4 25.000000 ... ... 1304 14.500000 1305 29.881135 1306 26.500000 1307 27.000000 1308 29.000000[1309 rows x 1 columns]fare 0 211.3375 1 151.5500 2 151.5500 3 151.5500 4 151.5500 ... ... 1304 14.4542 1305 14.4542 1306 7.2250 1307 7.2250 1308 7.8750[1309 rows x 1 columns] S 916 C 270 Q 123 Name: embarked, dtype: int64 S
(5)转化分类数据
将特征变量sex 由分类数据的female、male变为数值型数据1、0,可以使用map函数进行处理。
df["sex"] = df["sex"].map( {"female": 1, "male": 0} ).astype(int)
print(df["sex"])输出结果:
0 1 1 0 2 1 3 0 4 1.. 1304 1 1305 1 1306 0 1307 0 1308 0 Name: sex, Length: 1309, dtype: int32
(6)将不是分类数据的embarked字段进行独立热编码
在embarked中有S、C、Q三种字段,可以使用map函数将字段转化为数值,或者将一个字段拆分成三个字段的独立热编码:
enbarked_one_hot = pd.get_dummies(df["embarked"], prefix="embarked")#使用pd.get_dummies将原始字段拆分成embarked_C等三个字段
df = df.drop("embarked", axis=1)#删除embarked字段
df = df.join(enbarked_one_hot)#合并三个独立热编码字段
df输出结果:
pclass survived sex age sibsp parch fare embarked_C embarked_Q embarked_S 0 1 1 1 29.000000 0 0 211.3375 0 0 1 1 1 1 0 0.916700 1 2 151.5500 0 0 1 2 1 0 1 2.000000 1 2 151.5500 0 0 1 3 1 0 0 30.000000 1 2 151.5500 0 0 1 4 1 0 1 25.000000 1 2 151.5500 0 0 1 ... ... ... ... ... ... ... ... ... ... ... 1304 3 0 1 14.500000 1 0 14.4542 1 0 0 1305 3 0 1 29.881135 1 0 14.4542 1 0 0 1306 3 0 0 26.500000 0 0 7.2250 1 0 0 1307 3 0 0 27.000000 0 0 7.2250 1 0 0 1308 3 0 0 29.000000 0 0 7.8750 0 0 1 1309 rows × 10 columns
(7)移动响应变量到数据框最后一列
为了后续更好地分割训练集和测试集,将响应变量survived 栏位移至最后。
# 将标签的 survived 栏位移至最后
df_survived = df.pop("survived")
df["survived"] = df_survived
df输出结果:
pclass sex age sibsp parch fare embarked_C embarked_Q embarked_S survived 0 1 1 29.000000 0 0 211.3375 0 0 1 1 1 1 0 0.916700 1 2 151.5500 0 0 1 1 2 1 1 2.000000 1 2 151.5500 0 0 1 0 3 1 0 30.000000 1 2 151.5500 0 0 1 0 4 1 1 25.000000 1 2 151.5500 0 0 1 0 ... ... ... ... ... ... ... ... ... ... ... 1304 3 1 14.500000 1 0 14.4542 1 0 0 0 1305 3 1 29.881135 1 0 14.4542 1 0 0 0 1306 3 0 26.500000 0 0 7.2250 1 0 0 0 1307 3 0 27.000000 0 0 7.2250 1 0 0 0 1308 3 0 29.000000 0 0 7.8750 0 0 1 0 1309 rows × 10 columns
至此,数据预处理完成!下面开始划分数据集构建神经网络进行学习。
2、划分训练集和测试集,并保存划分的数据集
随机将数据集划分成训练集(80%) 、测试集(20%)。
#划分训练集和测试集
mask = np.random.rand(len(df)) < 0.8
df_train = df[mask]
df_test = df[~mask]
print("Train:", df_train.shape)
print("Test:", df_test.shape)输出结果:
Train: (1051, 10) Test: (258, 10)
#储存处理后的数据
df_train.to_csv("titanic_train.csv", index=False)
df_test.to_csv("titanic_test.csv", index=False)输出结果:
3、搭建MPL神经网络模型
首先分割训练集和测试集的特征数据与标签数据,再分别进行数据标准化。定义深度神经网络模型:输入层为9个特征,两个隐藏层的神经元设置为11个,输出层是一个二分类问题,所以神经元设置为1个神经元。其中隐藏层和两个隐藏层的激活函数均设置为ReLU函数,输出层的激活函数为Sigmoid函数。
dataset_train = df_train.values#取出数据集的数组
dataset_test = df_test.values
# 分割特征数据和标签数据
X_train = dataset_train[:, 0:9]
Y_train = dataset_train[:, 9]
X_test = dataset_test[:, 0:9]
Y_test = dataset_test[:, 9]
# 特征标准化
X_train -= X_train.mean(axis=0)
X_train /= X_train.std(axis=0)
X_test -= X_test.mean(axis=0)
X_test /= X_test.std(axis=0)# 定义模型
model = Sequential()
model.add(Dense(11, input_dim=X_train.shape[1], activation="relu"))
model.add(Dense(11, activation="relu"))
model.add(Dense(1, activation="sigmoid"))
model.summary() # 显示模型信息输出结果:
Model: "sequential" _________________________________________________________________Layer (type) Output Shape Param # =================================================================dense (Dense) (None, 11) 110 dense_1 (Dense) (None, 11) 132 dense_2 (Dense) (None, 1) 12 ================================================================= Total params: 254 Trainable params: 254 Non-trainable params: 0
各神经层的参数计算(包括权重和偏移量):第一个隐藏层有9*11+11=110、第二个隐藏层有11*11+11=132、输出层有11*1+1=12,总共参数共有254个。
4、编译模型、训练模型、评估模型
在编译模型中,损失函数使用binary_crossentropy,优化器使用adam,评估标准为准确度accuracy。在训练模型中,验证集为训练集的20%,训练周期为100次,批次尺寸为10。
# 编译模型
model.compile(loss="binary_crossentropy", optimizer="adam",
metrics=["accuracy"])
#训练模型
print("Training ...")
history = model.fit(X_train, Y_train, validation_split=0.2,
epochs=100, batch_size=10)输出结果:
84/84 [==============================] - 0s 2ms/step - loss: 0.3762 - accuracy: 0.8476 - val_loss: 0.4197 - val_accuracy: 0.8294 Epoch 95/100 84/84 [==============================] - 0s 2ms/step - loss: 0.3760 - accuracy: 0.8429 - val_loss: 0.4163 - val_accuracy: 0.8294 Epoch 96/100 84/84 [==============================] - 0s 2ms/step - loss: 0.3754 - accuracy: 0.8429 - val_loss: 0.4185 - val_accuracy: 0.8341 Epoch 97/100 84/84 [==============================] - 0s 2ms/step - loss: 0.3751 - accuracy: 0.8452 - val_loss: 0.4136 - val_accuracy: 0.8436 Epoch 98/100 84/84 [==============================] - 0s 2ms/step - loss: 0.3757 - accuracy: 0.8512 - val_loss: 0.4284 - val_accuracy: 0.8246 Epoch 99/100 84/84 [==============================] - 0s 2ms/step - loss: 0.3744 - accuracy: 0.8488 - val_loss: 0.4212 - val_accuracy: 0.8294 Epoch 100/100 84/84 [==============================] - 0s 2ms/step - loss: 0.3740 - accuracy: 0.8440 - val_loss: 0.4212 - val_accuracy: 0.8341
在输出结果有训练集的损失分数和准确率,验证集的损失分数和准确率。
# 评估模型
print("\n请稍等模型正在评估中 ...")
loss, accuracy = model.evaluate(X_train, Y_train)
print("训练数据集的准确度 = {:.2f}".format(accuracy))
loss, accuracy = model.evaluate(X_test, Y_test)
print("測测试数据集的准确度 = {:.2f}".format(accuracy))输出结果:
请稍等模型正在评估中 ... 33/33 [==============================] - 0s 1ms/step - loss: 0.3804 - accuracy: 0.8478 训练数据集的准确度 = 0.85 9/9 [==============================] - 0s 2ms/step - loss: 0.5483 - accuracy: 0.7519 測测试数据集的准确度 = 0.75
5、绘制训练集和验证集的损失分数趋势图、准确率趋势图
import matplotlib.pyplot as plt
# 绘制训练和验证损失趋势图
loss = history.history["loss"]
epochs = range(1, len(loss)+1)
val_loss = history.history["val_loss"]
plt.plot(epochs, loss, "b-", label="Training Loss")
plt.plot(epochs, val_loss, "r--", label="Validation Loss")
plt.title("Training and Validation Loss")
plt.xlabel("Epochs")
plt.ylabel("Loss")
plt.legend()
plt.savefig("squares1.png",
bbox_inches ="tight",
pad_inches = 1,
transparent = True,
facecolor ="w",
edgecolor ='w',
dpi=300,
orientation ='landscape')输出结果:
#绘制训练和验证准确率趋势图
acc = history.history["accuracy"]
epochs = range(1, len(acc)+1)
val_acc = history.history["val_accuracy"]
plt.plot(epochs, acc, "b-", label="Training Acc")
plt.plot(epochs, val_acc, "r--", label="Validation Acc")
plt.title("Training and Validation Accuracy")
plt.xlabel("Epochs")
plt.ylabel("Accuracy")
plt.legend()
plt.savefig("squares2.png",
bbox_inches ="tight",
pad_inches = 1,
transparent = True,
facecolor ="w",
edgecolor ='w',
dpi=300,
orientation ='landscape')输出结果:
从趋势图大致可以看出,训练周期大概在18次训练模型最好,再多就会出现过拟合。
6、使用最佳训练周期训练模型,并保存模型结果和权重
model = Sequential()
model.add(Dense(11, input_dim=X_train.shape[1], activation="relu"))
model.add(Dense(11, activation="relu"))
model.add(Dense(1, activation="sigmoid"))
# 编译模型
model.compile(loss="binary_crossentropy", optimizer="adam",metrics=["accuracy"])
# 训练模型
print("请稍等模型正在训练中 ...")
model.fit(X_train, Y_train, epochs=18, batch_size=10, verbose=0)
# 评估模型
print("\n请稍等模型正在评估中 ......")
loss, accuracy = model.evaluate(X_train, Y_train)
print("训练数据集的准确度 = {:.2f}".format(accuracy))
loss, accuracy = model.evaluate(X_test, Y_test)
print("测试数据集的准确度 = {:.2f}".format(accuracy))输出结果:
请稍等模型正在训练中 ...请稍等模型正在评估中 ...... 33/33 [==============================] - 0s 1ms/step - loss: 0.3960 - accuracy: 0.8402 训练数据集的准确度 = 0.84 9/9 [==============================] - 0s 1ms/step - loss: 0.5574 - accuracy: 0.7364 测试数据集的准确度 = 0.74
# 存储模型结构与权重
print("保存模型中,请稍等...(已完成)")
model.save("titanic.h5")输出结果:
7、使用训练好的模型进行预测
from tensorflow.keras.models import load_model
# 建立Keras的Sequential模型
model = Sequential()
model = load_model("titanic.h5")#调用之前保存的神经网络结构与权重
# 编译模型
model.compile(loss="binary_crossentropy", optimizer="adam",metrics=["accuracy"])
# 评估模型
loss, accuracy = model.evaluate(X_test, Y_test)
print("测试数据集的准确度= {:.2f}".format(accuracy))输出结果:
9/9 [==============================] - 0s 1ms/step - loss: 0.5574 - accuracy: 0.7364 测试数据集的准确度= 0.74
predict=model.predict(X_test)
# Y_pred=np.argmax(predict,axis=1)
Y_pred = np.int64(predict>0.5)
y_pred = np.squeeze(Y_pred)
print(y_pred[:5])
#print(Y_test.astype(int))
#显示混淆矩阵
tb = pd.crosstab(Y_test.astype(int), y_pred,
rownames=["label"], colnames=["predict"])
print(tb)输出结果:
9/9 [==============================] - 0s 1ms/step [1 1 1 0 0] predict 0 1 label 0 126 21 1 47 64
更多优质内容持续发布中,请移步主页查看。
点赞+关注,下次不迷路!
相关文章:

深度学习之构建MPL神经网络——泰坦尼克号乘客的生存分析
大家好,我是带我去滑雪! 本期使用泰坦尼克号数据集,该数据集的响应变量为乘客是生存还是死亡(survived,其中1表示生存,0表示死亡),特征变量有乘客舱位等级(pclass&#x…...
一条神奇的sql
背景:人脸闸机,每刷一次人脸,就会有一条记录插入到通行记录表。而闸机可能会多次识别同一个人的人脸,那么这时通行记录表就会插入多次同一个人的记录,同一个人的记录中,只不过通行时间不同而已 需求&#…...
数据结构总结3:栈和队列
后续会有补充和更改 栈和队列 栈和队列也属于线性表 栈 一种特殊的线性表,只允许在固定的一端进行插入和删除元素。该端称为栈顶,另一端称为栈底。 栈中的数据遵循后进先出(LIFO)的原则 压栈/进栈/入栈:数据插入…...

私有化部署的即时通讯软件:消息、文件安全加密,全面可控
如今,数字化转型进入纵深阶段,在企业数字化转型过程中,数据规模激增,结构更为复杂,数据零散化和安全性问题日益显著,使得众多企业在数据资产管理上面临不小的挑战。企业为提高内部沟通效率,通常…...
27-Django项目实战(5)
1 歌曲搜索 音乐平台的每个网页顶部都设置了歌曲搜索功能,歌曲搜索框以网页表单的形式展示,并且以POST请求方式实现歌曲搜索功能,搜索结果显示在歌曲搜索页。歌曲搜索页由项目应用search实现,首先在search的urls.py中定义路由sea…...

【JVM】1. JVM与Java体系结构
文章目录 1.1. 前言🍉1.2. 参考书目🍉1.3. Java及JVM简介🍉1.4. Java发展的重大事件🍉1.5. 虚拟机与Java虚拟机🍉1.6. JVM的整体结构🍉1.7. Java代码执行流程🍉1.8. JVM的架构模型🍉…...

活动回顾|Kyligence x 亚马逊云科技,携手加速零售电商数智化转型
5月19日,Kyligence 与亚马逊云科技联合主办的「指标驱动,加速零售电商行业数智化转型」主题沙龙在上海成功举办。来自乐高、Kyligence、亚马逊云科技的专家分享了如何以数据和指标驱动,加速零售行业的数智化转型,并与现场观众进行…...

本科毕业生10大高薪专业出炉,IT行业赢麻了
据环球网报道,现在大学毕业生转行率高达80%! 非常后悔!有不少粉丝向播妞倾诉,曾经以为读了大学就能找到体面的工作,实际上是掉入了天坑专业,成了现实版孔乙己。 大学生找不到对口好工作,似乎已成…...

工厂安灯呼叫系统解决方案
在选择安灯呼叫系统之前,需要先了解自己的需求。不同的工厂可能有不同的需求,例如生产线的规模、生产过程中可能会出现的问题等。因此,选择安灯呼叫系统之前,需要先考虑自己的需求,以便选择到最适合自己的系统。要从多…...

微信xr-frame官方案例基础能力之渲染目标
前言:什么是渲染目标?(详见:RenderTarget-渲染目标) 在3D计算机图形领域,渲染目标是现代图形处理单元(GPU)的一个特征,它允许将3D场景渲染到中间存储缓冲区或渲染目标纹理…...

自动控制原理笔记-根轨迹法
目录 一,根轨迹的基本概念 1.根轨迹的基本概念 2.根轨迹方程 3.根轨迹方程的应用 二,根轨迹的绘制规则 【规则一】根轨迹有n条分支: 【规则二】根轨迹对称于实轴: 【规则三】根轨迹的起点和终点: 【规则四】…...

准备半个月,面试5分钟不到就凉了,问的实在太····
从外包出来,没想到竟然死在了另一家厂子 自从加入这家公司,每天都在加班,钱倒是给的不少,所以我也就忍了。没想到12月一纸通知,所有人都不许加班,薪资直降30%,顿时有吃不起饭的赶脚。 好在有个…...

基础IO(三)
软硬链接和动静态库 1.软硬链接2.动态库和静态库2.1理解现象2.2静态库的设计2.3动态库2.4动态库的配置2.5动态库的理解 🌟🌟hello,各位读者大大们你们好呀🌟🌟 🚀🚀系列专栏:【Linux…...

如何用国产DBDesginer软件进行数据库建模设计?
我们在开发软件系统之前都需要进行数据结构的建模设计,传统的都是通过PowerDesiger等国外的软件或直接Excel来进行数据库表结构设计,今天来了解一下如何使用国产软件来进行数据库建模设计 1、首先是注册DBDesigner用户( http://dbdesigner.n…...

精选 100 种最佳 AI 工具大盘点
为了应对对精简流程和数据分析日益增长的需求,整合人工智能工具在多个领域变得至关重要。 本文精选了2023年可用的100种最佳人工智能工具,旨在提高您的生产力、创造力和效率。 以下是 2023 年排名前 100 的人工智能工具: Aidoc:A…...

Recognizing Micro-Expression in Video Clip with Adaptive Key-Frame Mining阅读笔记
本文主要贡献 据我们所知,这是第一项旨在将视频剪辑中的信息时间子集的端到端学习与单个网络中的微表情识别相结合的工作。 此外,所提出网络中所有模块的设计都与输入视频剪辑的长度无关。 换句话说,网络容忍各种长度的微表情剪辑。 本文的贡…...

【SpringBoot整合RabbitMQ(上)】
一、简单的生产者-消费者 1.1、创建连接工具类获取信道 public class RabbitMqUtils {public static Channel getChannel() throws IOException, TimeoutException {//创建一个链接工厂ConnectionFactory factory new ConnectionFactory();//工厂IP 链接RabbitMQ的队列facto…...

Linux 设备驱动程序(二)
系列文章目录 Linux 内核设计与实现 深入理解 Linux 内核(一) 深入理解 Linux 内核(二) Linux 设备驱动程序(一) Linux 设备驱动程序(二) Linux设备驱动开发详解 文章目录 系列文章目…...

性价比提升15%,阿里云发布第八代企业级计算实例g8a和性能增强型实例g8ae
5 月 17 日,2023 阿里云峰会常州站上,阿里云正式发布第八代企业级计算实例 g8a 以及性能增强性实例 g8ae。两款实例搭载第四代 AMD EPYC 处理器,标配阿里云 eRDMA 大规模加速能力,网络延时低至 8 微秒。其中,g8a 综合性…...

Unity VR开发教程 OpenXR+XR Interaction Toolkit 番外(一)用 Grip 键, Trigger 键和摇杆控制手部动画
文章目录 📕制作手部动画📕设置 Animation Controller📕添加触摸摇杆的 Input Action📕代码部分 在大部分 VR 游戏中,手部的动画通常是由手柄的三个按键来控制的。比如 Grip 键控制中指、无名指、小拇指的弯曲…...

深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

ABAP设计模式之---“简单设计原则(Simple Design)”
“Simple Design”(简单设计)是软件开发中的一个重要理念,倡导以最简单的方式实现软件功能,以确保代码清晰易懂、易维护,并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计,遵循“让事情保…...

R语言速释制剂QBD解决方案之三
本文是《Quality by Design for ANDAs: An Example for Immediate-Release Dosage Forms》第一个处方的R语言解决方案。 第一个处方研究评估原料药粒径分布、MCC/Lactose比例、崩解剂用量对制剂CQAs的影响。 第二处方研究用于理解颗粒外加硬脂酸镁和滑石粉对片剂质量和可生产…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...