机器学习--课后作业--hw1

news2024/11/18 17:38:28

机器学习(课后作业–hw1)

本篇文章全文参考这篇blog

网上找了很多教程,这个是相对来说清楚的,代码可能是一模一样,只是进行了一些微调,但是一定要理解这个模型具体的处理方法,这个模型我认为最巧妙的它对于数据的处理,直接把前9天所有的参数参数当作变量,最简单粗暴的方法,,然后再是里面一些矩阵的运算,也很重要,可能直接看无法理解,那就手动创造几个数据,进行手动模拟,一定会有不小的收获的

作业介绍

题目要求:利用每天的前9个小时的18个特征(包括PM2.5),来预测第10个小时的PM2.5的值。

特征包括: AMB_TEMP, CH4, CO, NHMC, NO, NO2, NOx, O3, PM10, PM2.5, RAINFALL, RH, SO2, THC, WD_HR, WIND_DIREC, WIND_SPEED, WS_HR,总计18种。每一种都可以作为一个变量加入你的模型里面。

数据下载:Github链接

下载结束以后把文件放入对应的文件夹里面就好了
数据下载

CSV文件,包含台湾丰原地区240天的气象观测资料(取每个月前20天的数据做训练集,12月X20天=240天,每月后10天数据用于测试,对学生不可见)

作业任务:根据每月的观测数据对未来进行预测

题目分析

Dataset里面我们要用的两个csv文件:数据集(train.csv)和测试集(test.csv)。
数据集中记录了12个月的前20天每天24个小时的18个物质浓度的资料,然后测试集就是剩余的数据中再取的。从上述我们可以得到以下结论:

  • 模型的输入:前9个小时的观测数据,每小时18个数据,所以输入参数有9*18个参数值
  • 模型的输出:预测第十个小时的PM2.5浓度
  • 模型:回归模型(Regression Model)
  • 要求:根据前面连续9个小时的观测数据,预测接下来一个小的PM2.5浓度
    • 每一天的信息:(18,24)(18个指标,24个小时)
    • 训练数据:

      训练数据是连续9个小时的观测数据,接下来一个小时的PM2.5作为这个训练数据集的label
      注意:每小时的数据可以作为训练数据,也可以作为label,一共12个月,每个月20天,一天24小时,每天18个观测数据,所以一共有(2024)x18个数据,而训练数据集有2024-9=471个(因为最开始的9个无法作为数据集的label)

代码解答

1. Data Preprocessing

我们需要做的第一件事就是数据的读入和预处理:

  • 按照文件路径读入
  • 去除无用数据
  • 预处理
  • 数据转化
    Rain
# 引入必要的包
import pandas as pd
import numpy as np

# 读取数据保存到data中,路径根据你保存的train.csv位置而有变化
# 数据编码方式,这里选择big5,台湾是繁体字,使用utf-8可能会出现问题
data = pd.read_csv('Dataset/train.csv', encoding='big5')
# print(data)

# 行保留所有,列从第三列开始往后才保留,这样去除了数据中的时间、地点、参数等信息
data = data.iloc[:, 3:]
# print(data)

# 将所有NR的值全部置为0方便之后处理
data[data == 'NR'] = 0
# print(data)

# 将data的所有数据转换为二维数据并用raw_data来保存
raw_data = data.to_numpy()
# print(raw_data)
# 可以每一步都打印出结果,看到数据的变化
2. Feature Engineering

按照train.csv给出的数据,肯定是无法满足我们的使用,我们在进行提取数据集的时候,把一个月的数据全部放在一起,只取连续的9个小时,不管是那一天的,使用我们原先的按天数竖着排列修改为每个月的数据按天数横着排放,这个代码进行实现其实不困,就是不好理解。
数据处理
处理以后才更方便我们提取连续的9小时数据作为数据集和接下来1小时PM2.5作为对于数据集的label

month_data = {}

# month 从0-11 共12个月
# 返回一个18行480列的数组,保存一个月的data(一月20天,一天24小时)
# day从0-19 共20天
for month in range(12):
    sample = np.empty([18, 480])
    for day in range(20):
        # raw的行每次取18行,列取全部列。送到sample中(sample是18行480列)
        # 行给全部行,列只给24列,然后列往后增加
        sample[:, day * 24: (day + 1) * 24] = raw_data[18 * (20 * month + day): 18 * (20 * month + day + 1), :]
    month_data[month] = sample
  • 创建字典,month为key,sample为value
  • 循环遍历:sample和raw_data都是两个参数(行和列),行和列都在变化,但是我们都是优先是行,然后是列(这个建议自己手动演示一下,这个代码真的很奇妙)
    • month = 0,day = 0
      遍历raw_data的第0行(0到18-1)的每一列(一共24列),依次赋值给sample的第0行(一共18行)的第0到24-1列。
    • month = 0,day = 1
      遍历raw_data的第18行(18到182-1)的每一列(一共24列),依次赋值给sample的第0行(一共18行)的第24到242-1列。

真的发现自己和zz一样,python最大的优点就是神奇,python可以直接实现矩阵对应块赋值,所以我们之间进行整块转移就好了,那就很好理解了,
raw_data其实每遍历一次就是去除一天的数据量,sample其实也就是取出前一天后面那一块。

经过上面的处理,数据已经横向转化为方便我们提取训练集的数据集了
训练数据集

# 每月共480个小时,每9个小时一个数据(480列最后一列不可以计入,如果取到最后一列那么最后一个数据
# 便没有了结果{需要9个小时的输入和第10个小时的第10行作为结果}),480-1-9+1=471。
# 12个月共12*471个数据按行排列,每一行一个数据;数据每小时有18个特征,而每个数据9个小时,共18*9列
x = np.empty([12 * 471, 18 * 9], dtype=float)

# 12个月共12*471个数据,每个数据对应一个结果,即第10小时的PM2.5浓度,也就是提取对应label
y = np.empty([12 * 471, 1], dtype=float)

for month in range(12):  # month 0-11
    for day in range(20):  # day 0-19
        for hour in range(24):  # hour 0-23
            if day == 19 and hour > 14:  # 第20天的第23时
                continue
            # 取对应month:行都要取,列取9个,依次进行,最后将整个数据reshape成一行数据
            # (列数无所谓)。然后赋给x,x内的坐标只是为了保证其从0-471*12
            # vector dim:18*9
            x[month * 471 + day * 24 + hour, :] = month_data[month][:, day * 24 + hour: day * 24 + hour + 9].reshape(1, -1)
            # value,结果对应的行数一直是9行(即第10行PM2.5)然后列数随着取得数据依次往后进行
            y[month * 471 + day * 24 + hour, 0] = month_data[month][9, day * 24 + hour + 9]
3. Data Normalization

数据的标准化我在另外一篇博客里面提到过
数据的标准化(normalization)是将数据按比例缩放,使之落入一个小的特定区间。去除数据的单位限制,将其转化为无量纲的纯数值,便于不同单位或量级的指标能够进行比较和加权。
这里我们采用的是最简单的标准化公式:
x* = (x - μ ) / σ
其中μ为所有样本数据的均值,σ为所有样本数据的标准差。
标准化其实是为了让模型更快收敛

mean_x = np.mean(x, axis=0)  # 18 * 9 求均值,axis = 0表示对各列求值,返回 1* 列数 的矩阵
std_x = np.std(x, axis=0)  # 18 * 9 求标准差,axis = 0表示对各列求值,返回 1* 列数 的矩阵
for i in range(len(x)):  # 12 * 471
    for j in range(len(x[0])):  # 18 * 9
        if std_x[j] != 0:
            x[i][j] = (x[i][j] - mean_x[j]) / std_x[j]
4. Splitting Data

将训练数据按8:2拆成训练数据和验证数据。训练数据用于模型的训练,测试数据用于模型的检测,这样可以让我们了解自己建立的模型面对新的数据集的时候的表现。

x_train_set = x[: math.floor(len(x) * 0.8), :]
y_train_set = y[: math.floor(len(y) * 0.8), :]
x_validation = x[math.floor(len(x) * 0.8):, :]
y_validation = y[math.floor(len(y) * 0.8):, :]
5. Model Training:
5.1 Regression Model

采用最普通的线性回归模型,如下列公式所展示,我们在前面将每一组训练数据集进训练压缩,成为一行,所以这一行一共有9*18个变量,每个变量都有其对应的权重(参数),同时还设置了一个偏置(bias)
y = ∑ i = 0 9 ∗ 18 ω i ⋅ x i + b y = \sum_{i=0}^{9*18}{{\omega}_i} \cdot{x_i} + b y=i=0918ωixi+b
xi为对应训练数据集中第i个变量,wi为其对应的权重值,b为偏置项,y为该数据帧样本的预测结果。

5.2 模型训练

数据在进行了前置的处理以后,,我们就要开始训练自己的模型了,我们这里使用的是损失函数Loss和Adagrad算法对参数进行优化。
均方根误差(Root Mean Square Error)
R M S E = 1 n ∑ i = 1 n ( y i − y ^ i ) 2 RMSE = \sqrt{\frac{1}{n}\sum_{i=1}^{n}(y_i - \hat{y}_i)^2} RMSE=n1i=1n(yiy^i)2
Adagrad算法
ω t + 1 = ω t − η ∑ i = 0 t ( g i ) 2 + ϵ g t \omega^{t+1} = \omega^t - \frac{\eta}{\sqrt{\sum_{i=0}^t(g^i)^2 + \epsilon}}g^t ωt+1=ωti=0t(gi)2+ϵ ηgt
其中 η \eta η是学习率, g i g^i gi是第i次训练得到的梯度, ϵ \epsilon ϵ是一个极小正值,防止分母为0
这部分建议先对着代码看一遍,然后按照我写的过程理解一下,矩阵部分求导有点复杂,有兴趣的可以了解一下

# 用来做参数vector的维数,加1是为了对bias好处理(还有个误差项)。即h(x)=w1x1+w2x2+''+wnxn+b
dim = 18 * 9 + 1
# 生成一个dim行1列的数组用来保存参数值
w = np.ones([dim, 1])
# np.ones来生成12*471行1列的全1数组,np.concatenate,axis=1
# 表示按列将两个数组拼接起来,即在x最前面新加一列内容,之前x是12*471行
# 18*9列的数组,新加一列之后变为12*471行18*9+1列的数组'''
x = np.concatenate((np.ones([12 * 471, 1]), x), axis=1).astype(float)
learning_rate = 100  # 学习率
iter_time = 10000  # 迭代次数

# 生成dim行即163行1列的数组,用来使用adagrad算法更新学习率
adagrad = np.zeros([dim, 1])

# 因为新的学习率是learning_rate/sqrt(sum_of_pre_grads**2),
# 而adagrad=sum_of_grads**2,所以处在分母上而迭代时adagrad可能为0,
# 所以加上一个极小数,使其不除0
eps = 0.0000000001
for t in range(iter_time):
    # rmse loss函数是从0-n的(X*W-Y)**2之和/(471*12)再开根号,
    # 即使用均方根误差(root mean square error),具体可看公式,
    # /471/12即/N(次数)'''
    loss = np.sqrt(np.sum(np.power(np.dot(x, w) - y, 2)) / 471 / 12)
    if (t % 100 == 0):  # 每一百次迭代就输出其损失
        print(str(t) + ":" + str(loss))

    # dim*1 x.transpose即x的转置,后面是X*W-Y,即2*(x的转置*(X*W-Y))是梯度,
    # 具体可由h(x)求偏微分获得.最后生成1行18*9+1列的数组。转置后的X,其每一行
    # 是一个参数,与h(x)-y的值相乘之后是参数W0的修正值,同理可得W0-Wn的修正值
    # 保存到1行18*9+1列的数组中,即gradient
    # 计算梯度。梯度是损失函数对参数向量w的偏导数
    gradient = 2 * np.dot(x.transpose(), np.dot(x, w) - y)

    # adagrad用于保存前面使用到的所有gradient的平方,进而在更新时用于调整学习率
    adagrad += gradient ** 2
    w = w - learning_rate * gradient / np.sqrt(adagrad + eps)  # 更新权重
np.save('weight.npy', w)  # 将参数保存下来

训练模型

6. Model Evaluation

在前面进行数据集划分的时候,我们将数据集划分为了两部分,按照8:2的比例,分别进行训练和测试。
但是我这里采用的是全部数据进行训练,然后使用我们分出来的那部分数据进行测试,这样效果相较于其他处理方式,效果较好。
一般来说,数据集的划分比较随意,我们也习惯多次划分尝试,然后对模型得到的参数进行评估,然后选择最好的数据集划分方式。

w = np.load('weight.npy')
# 使用x_validation和y_validation来计算模型的准确率,因为X已经normalize了,
# 所以不需要再来一遍,只需在x_validation上添加新的一列作为bias的乘数即可
x_validation = np.concatenate((np.ones([1131, 1]), x_validation), axis=1).astype(float)
ans_y = np.dot(x_validation, w)
loss = np.sqrt(np.sum(np.power(ans_y - y_validation, 2)) / 1131)
print(loss)

7. Test Data Prediction

7.1 测试数据预处理

测试数据的预处理和前面的训练数据预处理很类似,直接按部就班就好了

testdata = pd.read_csv('Dataset/test.csv', header=None, encoding='big5')
test_data = testdata.iloc[:, 2:]  # 取csv文件中的全行数即第3列到结束的列数所包含的数据
test_data.replace('NR', 0, inplace=True)  # 将testdata中的NR替换为0
test_data = test_data.to_numpy()  # 将其转换为数组
# 创建一个240行18*9列的空数列用于保存textdata的输入
test_x = np.empty([240, 18 * 9], dtype=float)
for i in range(240):  # 共240个测试输入数据
    test_x[i, :] = test_data[18 * i: 18 * (i + 1), :].reshape(1, -1)
# 下面是Normalize,且必须跟training data是同一种方法进行Normalize
for i in range(len(test_x)):
    for j in range(len(test_x[0])):
        if std_x[j] != 0:
            test_x[i][j] = (test_x[i][j] - mean_x[j]) / std_x[j]
# 在test_x前面拼接一列全1数组,构成240行,163列数据
test_x = np.concatenate((np.ones([240, 1]), test_x), axis=1).astype(float)
7.2 数据预测

单纯的矩阵相乘,原理很简单,得到一个列向量,分别对应每一组数据集未来一小时的PM2.5预测值

# 进行预测 
w = np.load('weight.npy')
ans_y = np.dot(test_x, w)  # test data的预测值ans_y=test_x与W的积

8. Saving Predictions

最后一步当然是把数据存入文件里

# 将预测结果填入文件当中
import csv
 
with open('submit.csv', mode='w', newline='') as submit_file:
    csv_writer = csv.writer(submit_file)
    header = ['id', 'value']
    print(header)
    csv_writer.writerow(header)
    for i in range(240):
        row = ['id_' + str(i), ans_y[i][0]]
        csv_writer.writerow(row)
        print(row)

完整代码

这是我文件的一些对应存放位置,调整好了应该就可以直接运行
文件

# 引入必要的包
import pandas as pd
import numpy as np

# 读取数据保存到data中,路径根据你保存的train.csv位置而有变化
# 数据编码方式,这里选择big5,台湾是繁体字,使用utf-8可能会出现问题
data = pd.read_csv('Dataset/train.csv', encoding='big5')
# print(data)

# 行保留所有,列从第三列开始往后才保留,这样去除了数据中的时间、地点、参数等信息
data = data.iloc[:, 3:]
# print(data)

# 将所有NR的值全部置为0方便之后处理
data[data == 'NR'] = 0
# print(data)

# 将data的所有数据转换为二维数据并用raw_data来保存
raw_data = data.to_numpy()
# print(raw_data)
# 可以每一步都打印出结果,看到数据的变化

month_data = {}

# month 从0-11 共12个月
# 返回一个18行480列的数组,保存一个月的data(一月20天,一天24小时)
# day从0-19 共20天
for month in range(12):
    sample = np.empty([18, 480])
    for day in range(20):
        # raw的行每次取18行,列取全部列。送到sample中(sample是18行480列)
        # 行给全部行,列只给24列,然后列往后增加
        sample[:, day * 24: (day + 1) * 24] = raw_data[18 * (20 * month + day): 18 * (20 * month + day + 1), :]
    month_data[month] = sample

# 每月共480个小时,每9个小时一个数据(480列最后一列不可以计入,如果取到最后一列那么最后一个数据
# 便没有了结果{需要9个小时的输入和第10个小时的第10行作为结果}),480-1-9+1=471。
# 12个月共12*471个数据按行排列,每一行一个数据;数据每小时有18个特征,而每个数据9个小时,共18*9列
x = np.empty([12 * 471, 18 * 9], dtype=float)

# 12个月共12*471个数据,每个数据对应一个结果,即第10小时的PM2.5浓度,也就是提取对应label
y = np.empty([12 * 471, 1], dtype=float)

for month in range(12):  # month 0-11
    for day in range(20):  # day 0-19
        for hour in range(24):  # hour 0-23
            if day == 19 and hour > 14:  # 第20天的第23时
                continue
            # 取对应month:行都要取,列取9个,依次进行,最后将整个数据reshape成一行数据
            # (列数无所谓)。然后赋给x,x内的坐标只是为了保证其从0-471*12
            # vector dim:18*9
            x[month * 471 + day * 24 + hour, :] = month_data[month][:, day * 24 + hour: day * 24 + hour + 9].reshape(1, -1)
            # value,结果对应的行数一直是9行(即第10行PM2.5)然后列数随着取得数据依次往后进行
            y[month * 471 + day * 24 + hour, 0] = month_data[month][9, day * 24 + hour + 9]

mean_x = np.mean(x, axis=0)  # 18 * 9 求均值,axis = 0表示对各列求值,返回 1* 列数 的矩阵
std_x = np.std(x, axis=0)  # 18 * 9 求标准差,axis = 0表示对各列求值,返回 1* 列数 的矩阵
for i in range(len(x)):  # 12 * 471
    for j in range(len(x[0])):  # 18 * 9
        if std_x[j] != 0:
            x[i][j] = (x[i][j] - mean_x[j]) / std_x[j]

# 将训练数据拆成训练数据:验证数据=8:2,这样用来验证
import math

x_train_set = x[: math.floor(len(x) * 0.8), :]
y_train_set = y[: math.floor(len(y) * 0.8), :]
x_validation = x[math.floor(len(x) * 0.8):, :]
y_validation = y[math.floor(len(y) * 0.8):, :]

# 用来做参数vector的维数,加1是为了对bias好处理(还有个误差项)。即h(x)=w1x1+w2x2+''+wnxn+b
dim = 18 * 9 + 1
# 生成一个dim行1列的数组用来保存参数值
w = np.ones([dim, 1])
# np.ones来生成12*471行1列的全1数组,np.concatenate,axis=1
# 表示按列将两个数组拼接起来,即在x最前面新加一列内容,之前x是12*471行
# 18*9列的数组,新加一列之后变为12*471行18*9+1列的数组'''
x = np.concatenate((np.ones([12 * 471, 1]), x), axis=1).astype(float)
learning_rate = 100  # 学习率
iter_time = 10000  # 迭代次数

# 生成dim行即163行1列的数组,用来使用adagrad算法更新学习率
adagrad = np.zeros([dim, 1])

# 因为新的学习率是learning_rate/sqrt(sum_of_pre_grads**2),
# 而adagrad=sum_of_grads**2,所以处在分母上而迭代时adagrad可能为0,
# 所以加上一个极小数,使其不除0
eps = 0.0000000001
for t in range(iter_time):
    # rmse loss函数是从0-n的(X*W-Y)**2之和/(471*12)再开根号,
    # 即使用均方根误差(root mean square error),具体可看公式,
    # /471/12即/N(次数)'''
    loss = np.sqrt(np.sum(np.power(np.dot(x, w) - y, 2)) / 471 / 12)
    if (t % 100 == 0):  # 每一百次迭代就输出其损失
        print(str(t) + ":" + str(loss))

    # dim*1 x.transpose即x的转置,后面是X*W-Y,即2*(x的转置*(X*W-Y))是梯度,
    # 具体可由h(x)求偏微分获得.最后生成1行18*9+1列的数组。转置后的X,其每一行
    # 是一个参数,与h(x)-y的值相乘之后是参数W0的修正值,同理可得W0-Wn的修正值
    # 保存到1行18*9+1列的数组中,即gradient
    # 计算梯度。梯度是损失函数对参数向量w的偏导数
    gradient = 2 * np.dot(x.transpose(), np.dot(x, w) - y)

    # adagrad用于保存前面使用到的所有gradient的平方,进而在更新时用于调整学习率
    adagrad += gradient ** 2
    w = w - learning_rate * gradient / np.sqrt(adagrad + eps)  # 更新权重
np.save('weight.npy', w)  # 将参数保存下来

w = np.load('weight.npy')
# 使用x_validation和y_validation来计算模型的准确率,因为X已经normalize了,
# 所以不需要再来一遍,只需在x_validation上添加新的一列作为bias的乘数即可
x_validation = np.concatenate((np.ones([1131, 1]), x_validation), axis=1).astype(float)
ans_y = np.dot(x_validation, w)
loss = np.sqrt(np.sum(np.power(ans_y - y_validation, 2)) / 1131)
print(loss)

testdata = pd.read_csv('Dataset/test.csv', header=None, encoding='big5')
test_data = testdata.iloc[:, 2:]  # 取csv文件中的全行数即第3列到结束的列数所包含的数据
test_data.replace('NR', 0, inplace=True)  # 将testdata中的NR替换为0
test_data = test_data.to_numpy()  # 将其转换为数组
# 创建一个240行18*9列的空数列用于保存textdata的输入
test_x = np.empty([240, 18 * 9], dtype=float)
for i in range(240):  # 共240个测试输入数据
    test_x[i, :] = test_data[18 * i: 18 * (i + 1), :].reshape(1, -1)
# 下面是Normalize,且必须跟training data是同一种方法进行Normalize
for i in range(len(test_x)):
    for j in range(len(test_x[0])):
        if std_x[j] != 0:
            test_x[i][j] = (test_x[i][j] - mean_x[j]) / std_x[j]
# 在test_x前面拼接一列全1数组,构成240行,163列数据
test_x = np.concatenate((np.ones([240, 1]), test_x), axis=1).astype(float)

# 进行预测
w = np.load('weight.npy')
ans_y = np.dot(test_x, w)  # test data的预测值ans_y=test_x与W的积

# 将预测结果填入文件当中
import csv

with open('submit.csv', mode='w', newline='') as submit_file:
    csv_writer = csv.writer(submit_file)
    header = ['id', 'value']
    print(header)
    csv_writer.writerow(header)
    for i in range(240):
        row = ['id_' + str(i), ans_y[i][0]]
        csv_writer.writerow(row)
        print(row)

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

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

相关文章

【1.4】Java微服务:服务注册和调用(Eureka和Ribbon实现)

✅作者简介:大家好,我是 Meteors., 向往着更加简洁高效的代码写法与编程方式,持续分享Java技术内容。 🍎个人主页:Meteors.的博客 💞当前专栏: 微服务 ✨特色专栏: 知识分享 &#x…

小研究 - JVM GC 对 IMS HSS 延迟分析(一)

用户归属服务器(IMS HSS)是下一代通信网(NGN)核心网络 IP 多媒体子系统(IMS)中的主要用户数据库。IMS HSS 中存储用户的配置文件,可执行用户的身份验证和授权,并提供对呼叫控制服务器…

ARTS Activity -- Using Java

About ARTS - Complete one ARTS per week: ● Algorithm: Do at least one LeetCode algorithm per week Review: Read and comment on at least one technical article in English ● Tips: Learn at least one technical trick ● Share: Share a technical article with op…

1.2 eureka注册中心,完成服务注册

目录 环境搭建 搭建eureka服务 导入eureka服务端依赖 编写启动类,添加EnableEurekaServer注解 编写eureka配置文件 启动服务,访问eureka Euraka服务注册 创建了两个子模块 在模块里导入rureka客户端依赖 编写eureka配置文件 添加Services 环境搭建 创建父…

08-向量的范数_范数与正则项的关系

⛳向量的范数 范数的公式是向量每个分量 绝对值 P 次方 再用幂函数计算 P 分之一,这里 P 肯定是整数 1,2,3…到正无穷都是可以的 向量的范数就是把向量变成一个标量,范数的表示就是两个竖线来表示,然后右下角写上 P&a…

LeetCode36.Valid-Sudoku<有效的数独>

题目: 思路: 这题并不难,它类似于N皇后问题。在N皇后问题中,行,列,对角线,写对角线,都不能出现连续的皇后。 本题类似,不过他是行,列,还有一个B…

【数据结构篇C++实现】- 图

友情链接:C/C系列系统学习目录 文章目录 🚀一、图的基本概念和术语1、有向图和无向图3、基本图和多重图4、完全图5、子图6、连通、连通图和连通分量7、强连通图、强连通分量8、生成树、生成森林9、顶点的度、入度和出度10、边的权和网11、稠密图、稀疏图…

【点云处理教程】00计算机视觉的Open3D简介

一、说明 Open3D 是一个开源库,使开发人员能够处理 3D 数据。它提供了一组用于 3D 数据处理、可视化和机器学习任务的工具。该库支持各种数据格式,例如 .ply、.obj、.stl 和 .xyz,并允许用户创建自定义数据结构并在程序中访问它们。 Open3D 广…

介绍壹牛NFT数字艺术藏品数藏源码

这个版本新增了不少功能,也修复了一些地方。 1.平台新增用户找回密码功能 2.平台新增短信注册(实名制功能) 3.平台新增主图后台添加功能 4.平台修复相关问题,系统高效运行 5、H5端与APP端在新UI完美适配 6、加入宝盒功能&…

04-导数判断凹(concave)凸(convex)性_导数用于泰勒展开

导数与函数凹凸性的关系 函数的二阶导数是和函数的凹凸性是有关系的,凹凸性怎么定义的? 先来做简单的回顾,更多的会在最优化方法里面给大家讲,这里先记住凸函数是向下凸的, 反正就是凹的,是否是凸函数可以…

Linux——平台设备及其驱动

目录 前言 一、平台设备 二、平台驱动 三、平台驱动简单实例 四、 电源管理 五、udev 和驱动的自动加载 六、使用平台设备的LED 驱动 七、自动创建设备节点 前言 要满足 Linux 设备模型,就必须有总线、设备和驱动。但是有的设备并没有对应的物理总线&#x…

【双评价笔记】农业指向之水资源评价

农业指向水资源单项评价是基于区域内及邻近地区气象站点长时间序列降水观测资料,通过空间插值得到多年平均降水量分布图层,降水量按照200,400,800,1200这个间断点分为好(很湿润),较好(湿润),一般(半湿润),较差(半干旱),差(干旱)5 个等级。 本次实验过程采用的评价分…

谷粒商城第七天-商品服务之分类管理下的分类的拖拽功能的实现

目录 一、总述 1.1 前端思路 1.2 后端思路 二、前端实现 2.1 判断是否能进行拖拽 2.2 收集受影响的节点,提交给服务器 三、后端实现 四、总结 一、总述 这个拖拽功能对于这种树形的列表,整体的搬迁是很方便的。但是其实现却并不是那么的简单。 …

CMU15-213 课程笔记 01-课程概览

知识点 这门课的目的:深入理解当你执行代码时,计算机在做什么 LLDB:基于 LLVM 的命令行调试器,类似 GBD 内存引用 Bug typedef struct {int a[2];double d; } struct_t;double fun(int i) {volatile struct_t s;s.d 3.14;s.a…

Flowable-服务-邮件任务

目录 定义图形标记XML内容邮件服务器配置界面操作 定义 Flowable 支持通过自动的邮件服务任务(Email Task)增强业务流程,它可以向一个或多个收信人发送 邮件,支持 cc,bcc,HTML 内容等。 流程流转到邮件任务…

xshell连接liunx服务器身份验证不能选择password

ssh用户身份验证不能选择password 只能用public key的解决办法 问题现象 使用密码通过Workbench或SSH方式(例如PuTTY、Xshell、SecureCRT等)远程登录ECS实例时,遇到服务器禁用了密码登录方式错误. 可能原因 该问题是由于SSH服务对应配置文件/etc/ssh/sshd_config中…

【软件安装】MATLAB_R2021b for mac 安装

Mac matlab_r2021b 安装 下载链接:百度网盘 下载链接中所有文件备用。 我所使用的电脑配置: Macbook Pro M1 Pro 16512 系统 macOS 13.5 安装步骤 前置准备 无此选项者,自行百度 “mac 任何来源”。 1 下载好「MATLAB R2021b」安装文…

stm32 舵机 cubemx

文章目录 前言一、cubemx配置二、代码1.serve.c2.serve.h3.主函数 总结 前言 stm32对舵机进行控制,很简单直接一个pwm就可以实现 pwm的周期是50HZ占空比分别对应 一个0.5ms的高电平对应于0度 一个1.5ms的高电平对应于90度 一个2.5ms的高电平对应于180度 因此&#…

【C语言】扫雷(保姆级教程+内含源码)

C系列文章目录 前言 一,模块化编程 二,游戏思路与逻辑 三,实现游戏步骤/过程 1,菜单界面(menu) 2,实现多行多列扫雷 3, 实现多个雷 4,棋盘初始化 5,棋盘的打印 6,布置雷…

连接器信号完整性仿真教程 六

连接器信号完整性仿真教程五中,讲了波导端口中同轴波导端口及多Pin波导端口的设置。本将继续以实例演示的方式讲解波导端口中的微带(Microstrip Line)波导端口的设置及其在连接器信号完整性仿真中的应用。 一 微带线(Microstrip Line) 由介基材(Dielectric Substrate)及…