当前位置: 首页 > news >正文

游戏AI的创造思路-技术基础-机器学习(2)

本篇存在大量的公式,数学不好的孩子们要开始恶补数学了,尤其是统计学和回归方程类的内容。

小伙伴们量力而行~~~~~

游戏呢,其实最早就是数学家、元祖程序员编写的数学游戏,一脉相承传承至今,囊括了更多的设计师、美术家、音乐家、作家、导演、演员等等,发展形成了今天大家看到的繁花般的多彩游戏世界。作为游戏工作者特别是游戏算法程序员,我们应当不停的学习数学知识,满足应用需求哦

大家共勉!

(后面算法先给出些简单示例和伪代码,可能有些来不及写完,后续逐步补充)

目录

4. 最常见的机器学习算法

4.1. 线性回归(Linear Regression)

4.2. 逻辑回归(Logistic Regression)

4.2.1. 逻辑回归模型

4.2.2. 损失函数

4.2.3. 优化方法

4.2.4. 算法示例

4.3. 决策树(Decision Tree)

4.3.1. 特征选择

4.3.2. 决策树生成

4.3.3. 决策树剪枝

4.3.4. 算法示例

4.4. 支持向量机(Support Vector Machine, SVM)

4.4.1. SVM 的主要概念

4.4.2. SVM 的优点

4.4.3. 算法示例

C++ 算法示例

4.5. 朴素贝叶斯(Naive Bayes)

4.5.1. 算法介绍

4.5.2. 算法示例

4.6. k-近邻算法(K-Nearest Neighbors, KNN)

4.6.1. k-近邻算法介绍

4.6.2. k-近邻算法步骤

4.6.3. 算法示例

4.7. k-平均算法(K-Means)

4.7.1. k-平均算法介绍

4.7.2. k-平均算法步骤

4.7.3. 算法示例

4.8. 庆祝下


4. 最常见的机器学习算法

最常见的机器学习算法包括线性回归、逻辑回归、支持向量机、决策树、随机森林、神经网络(包括卷积神经网络)等。机器学习的基础算法及其示例可以归纳为以下几点:

4.1. 线性回归(Linear Regression)

  • 基础概念:线性回归是一种用于预测数值类型的机器学习算法,通过建立自变量和因变量之间的线性关系模型来进行预测。
  • 算法示例:北京房价预测。通过收集房屋的各种特征(如面积、房间数等),使用线性回归模型来预测房价。

线性回归(Linear Regression)是一种统计学上的预测分析,用于估计两个或多个变量之间的关系。在线性回归中,目标变量(因变量)被预测为自变量的线性组合。简单来说,线性回归试图找到一条最佳拟合直线,使得预测值与实际值之间的残差平方和最小。

线性回归模型可以表示为:

(y = \beta_0 + \beta_1x_1 + \beta_2x_2 + ... + \beta_nx_n + \epsilon)

其中(y)是因变量,(x_1, x_2, ..., x_n)是自变量,(\beta_0, \beta_1, ..., \beta_n)是回归系数,(\epsilon)是误差项。

Python 算法示例
在 Python 中,我们通常使用 sklearn 库来进行线性回归。以下是一个简单的示例:

from sklearn.linear_model import LinearRegression  
import numpy as np  # 创建一些样本数据  
X = np.array([[1], [2], [3], [4], [5]])  # 自变量  
y = np.array([2, 4, 6, 8, 10])  # 因变量  # 创建一个线性回归模型对象  
model = LinearRegression()  # 使用样本数据训练模型  
model.fit(X, y)  # 使用模型进行预测  
X_test = np.array([[6], [7]])  
y_pred = model.predict(X_test)  print("预测值:", y_pred)

C++ 算法示例
在 C++ 中,你可能需要手动实现线性回归算法。以下是一个简单的示例,使用最小二乘法求解回归系数:

#include <iostream>  
#include <vector>  
#include <Eigen/Dense>  int main() {  // 样本数据  Eigen::MatrixXd X(5, 2);  // 5个样本,每个样本有1个自变量和1个截距项(全为1)  X << 1, 1,  1, 2,  1, 3,  1, 4,  1, 5;  Eigen::VectorXd y(5);  // 5个因变量值  y << 2, 4, 6, 8, 10;  // 使用最小二乘法求解回归系数 (beta = (X'X)^(-1)X'y)  Eigen::VectorXd beta = X.transpose() * X).inverse() * X.transpose() * y;  // 输出回归系数  std::cout << "回归系数: " << beta.transpose() << std::endl;  // 使用模型进行预测  Eigen::MatrixXd X_test(2, 2);  // 2个测试样本,每个样本有1个自变量和1个截距项(全为1)  X_test << 1, 6,  1, 7;  Eigen::VectorXd y_pred = X_test * beta;  // 进行预测  // 输出预测值  std::cout << "预测值: " << y_pred.transpose() << std::endl;  return 0;  
}

注意:C++ 示例中使用了 Eigen 库来进行矩阵运算。你需要先安装 Eigen 库才能编译和运行此代码。你可以从 Eigen 官网下载和安装 Eigen。

这两个示例都展示了如何使用线性回归模型进行简单的预测。Python 示例使用了 scikit-learn: machine learning in Python — scikit-learn 1.5.0 documentation 库,而 C++ 示例则使用了 Eigen 库来进行矩阵运算。


4.2. 逻辑回归(Logistic Regression)

  • 基础概念:逻辑回归是一种用于分类问题的机器学习算法,特别适用于二分类问题。它通过将数据映射到概率空间来进行建模。
  • 算法示例:信用卡欺诈检测。通过分析信用卡交易数据,使用逻辑回归模型来预测某笔交易是否为欺诈行为。

逻辑回归(Logistic Regression)是一种广义的线性模型,用于解决二分类问题。它使用逻辑函数(也称为Sigmoid函数)将线性回归的输出映射到0和1之间,从而表示概率。逻辑回归的名字中虽然有“回归”,但它实际上是一种分类算法。

4.2.1. 逻辑回归模型

逻辑回归的模型可以表示为:

[ P(Y=1|x) = \frac{1}{1 + e^{-(w \cdot x + b)}} ]

其中,( w )是权重向量,( x ) 是特征向量,( b )是偏置项。这个函数将线性回归的输出 ( w \cdot x + b )通过Sigmoid函数映射到0和1之间,表示给定特征 ( x ) 下,( Y=1 )的概率。

4.2.2. 损失函数

逻辑回归通常使用交叉熵损失函数(Cross-Entropy Loss):

[ L(w, b) = -\frac{1}{m} \sum_{i=1}^{m} [y_i \log(p_i) + (1-y_i) \log(1-p_i)] ]

其中,( m )是样本数量,( y_i )是第( i )个样本的真实标签(0或1),( p_i )是模型预测的第 ( i )个样本为正类的概率。

4.2.3. 优化方法

逻辑回归通常使用梯度下降法(Gradient Descent)或其变种(如随机梯度下降SGD、小批量梯度下降Mini-Batch GD等)来优化损失函数。

4.2.4. 算法示例

Python算法示例

在Python中,我们可以使用scikit-learn库中的LogisticRegression类来实现逻辑回归:

from sklearn.linear_model import LogisticRegression  
from sklearn.datasets import load_iris  
from sklearn.model_selection import train_test_split  
from sklearn.metrics import accuracy_score  # 加载数据集  
iris = load_iris()  
X = iris.data  
y = iris.target  # 将多分类问题简化为二分类问题  
y = (y != 0) * 1  # 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 创建逻辑回归模型并训练  
model = LogisticRegression(max_iter=1000)  
model.fit(X_train, y_train)  # 预测测试集并计算准确率  
y_pred = model.predict(X_test)  
accuracy = accuracy_score(y_test, y_pred)  
print(f"Accuracy: {accuracy}")

C++算法示例

在C++中,我们可以使用mlpack库可以从mlpack - Home官网获取哦(一个C++机器学习库)来实现逻辑回归。以下是一个简化的示例:

#include <mlpack/core.hpp>  
#include <mlpack/methods/logistic_regression/logistic_regression.hpp>  
#include <mlpack/methods/logistic_regression/logistic_regression_function.hpp>  using namespace mlpack;  
using namespace mlpack::regression;  
using namespace mlpack::optimization;  int main() {  // 假设你已经有了一些训练数据X_train和y_train  arma::mat X_train; // 特征数据,大小为N x D(N个样本,D个特征)  arma::Row<size_t> y_train; // 标签数据,大小为1 x N  // 创建并训练逻辑回归模型  LogisticRegressionFunction<> lrf(X_train, y_train, 0.01); // 0.01是正则化参数  LBFGS<LogisticRegressionFunction<> > optimizer;  arma::vec parameters; // 模型参数将被存储在这里  optimizer.Optimize(lrf, parameters); // 训练模型  // 使用训练好的模型进行预测  LogisticRegression<> model(parameters);  arma::Row<size_t> predictions;  model.Predict(X_train, predictions); // 对训练集进行预测,仅作为示例  // 计算准确率等性能指标...  // ...  return 0;  
}

注意:上述C++示例代码是一个简化的模板,用于说明如何在C++中使用逻辑回归。在实际应用中,你可能需要处理数据加载、预处理、模型评估等多个方面。此外,mlpack库可能需要单独安装和配置。

4.3. 决策树(Decision Tree)

  • 基础概念:决策树是一种基于树状结构的分类和回归算法,通过对数据集进行递归分割来形成决策规则。
  • 算法示例:风险评估。游戏中可以用来评估玩家继续游戏的欲望程度,采取降低难度、给与奖励或激励,或提升难度,给与更大奖励刺激,以及及时给出充值付费买道具等等措施。

决策树(Decision Tree)是一种基本的分类与回归方法,它可以被认为是一个树形结构,每个内部节点表示一个属性上的判断条件,每个分支代表一个判断结果的输出,每个叶子节点代表一种分类结果。决策树学习通常包括三个步骤:特征选择、决策树生成和决策树剪枝。

4.3.1. 特征选择

特征选择在于选取对训练数据具有分类能力的特征,常用的准则有信息增益(如ID3算法)、信息增益比(如C4.5算法)和基尼指数(如CART算法)。

4.3.2. 决策树生成

根据选择的特征评估准则,从上至下递归地生成子节点,直到数据集不可分则停止。

4.3.3. 决策树剪枝

决策树容易过拟合,一般通过剪枝来简化决策树,防止过拟合。剪枝有预剪枝和后剪枝两种方法。

4.3.4. 算法示例

Python算法示例

在Python中,我们可以使用scikit-learn库中的DecisionTreeClassifier来实现决策树分类:

from sklearn.datasets import load_iris  
from sklearn.model_selection import train_test_split  
from sklearn.tree import DecisionTreeClassifier  
from sklearn.metrics import accuracy_score  # 加载数据集  
iris = load_iris()  
X = iris.data  
y = iris.target  # 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 创建决策树模型并训练  
clf = DecisionTreeClassifier(random_state=42)  
clf.fit(X_train, y_train)  # 预测测试集并计算准确率  
y_pred = clf.predict(X_test)  
accuracy = accuracy_score(y_test, y_pred)  
print(f"Accuracy: {accuracy}")

C++算法示例

在C++中,实现决策树算法通常比较复杂,因为需要手动处理数据的加载、预处理、特征选择、树的构建和剪枝等步骤。不过,有一些库如mlpack也提供了决策树的实现。以下是一个使用mlpack的简化示例:

#include <mlpack/methods/decision_tree/decision_tree.hpp>  
#include <mlpack/core/data/load.hpp>  using namespace mlpack;  
using namespace mlpack::tree;  
using namespace mlpack::data;  int main()  
{  // 加载数据集(假设数据集是CSV格式,且最后一列是标签)  arma::mat data;  arma::Row<size_t> labels;  Load("dataset.csv", data, true); // 假设数据集文件名为dataset.csv  labels = data.row(data.n_rows - 1);  data.shed_row(data.n_rows - 1);  // 划分训练集和测试集(这里简化为只使用前80%作为训练集)  size_t trainSize = data.n_cols * 0.8;  arma::mat trainData = data(:, arma::span(0, trainSize - 1));  arma::Row<size_t> trainLabels = labels(arma::span(0, trainSize - 1));  // 创建并训练决策树模型  const size_t numClasses = 3; // 假设是3分类问题  const size_t minimumLeafSize = 10;  DecisionTree<> dt(trainData, trainLabels, numClasses, minimumLeafSize);  // 使用训练好的模型进行预测(这里简化为对训练集自身进行预测)  arma::Row<size_t> predictions;  dt.Classify(trainData, predictions);  // 计算准确率等性能指标...  // ...  return 0;  
}

请注意,C++示例代码是一个高度简化的模板,用于说明如何在C++中使用决策树。在实际应用中,数据集的加载、预处理、模型评估和性能度量等步骤可能更加复杂。另外,mlpack库可能需要单独安装和配置。如果你打算在生产环境中使用C++实现决策树,可能需要考虑更多细节和异常处理。

如果你希望完全从底层实现决策树算法,那么你需要手动编写代码来处理决策树的构建、特征选择、树的遍历以及剪枝等操作,这通常需要对算法和数据结构有深入的理解。

4.4. 支持向量机(Support Vector Machine, SVM)

  • 基础概念:支持向量机是一种二分类和多分类的监督学习算法,通过构建超平面或超曲面来实现分类。
  • 算法示例:图像识别。在图像处理领域,SVM 可以用于识别手写数字、人脸识别等任务。

支持向量机(Support Vector Machine, SVM)是一种非常流行的监督学习算法,主要用于分类和回归分析。SVM 的主要思想是在高维空间中寻找一个最优超平面,这个超平面能够将不同类别的数据点分隔开,并且使得两侧距离超平面最近的点(即支持向量)到超平面的间隔最大化。

4.4.1. SVM 的主要概念
  1. 支持向量:是数据集中距离决策边界(超平面)最近的点,这些点对确定决策边界起到了关键作用。

  2. 间隔(Margin):是指支持向量到决策边界的距离,SVM 的目标是最大化这个间隔。

  3. 核函数:当数据不是线性可分的时候,可以通过核函数将数据映射到更高维的空间,使其在新的空间中线性可分。

  4. 软间隔与硬间隔:硬间隔是指所有数据点都必须严格分类正确,不允许有错误分类;而软间隔则允许一些数据点被错误分类,通过引入惩罚项来控制错误分类的程度。

4.4.2. SVM 的优点
  • 在高维空间中表现良好。
  • 只使用部分训练数据(支持向量)来做决策,使得模型更加高效。
  • 可以使用不同的核函数来处理非线性问题。
4.4.3. 算法示例

Python 算法示例

在 Python 中,通常使用 scikit-learn 库来应用 SVM 算法。

from sklearn import svm  
from sklearn.datasets import load_iris  
from sklearn.model_selection import train_test_split  
from sklearn.metrics import accuracy_score  # 加载数据集  
iris = load_iris()  
X = iris.data  
y = iris.target  # 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 创建 SVM 分类器  
clf = svm.SVC(kernel='linear', C=1.0, random_state=42)  # 训练模型  
clf.fit(X_train, y_train)  # 预测测试集  
y_pred = clf.predict(X_test)  # 计算准确率  
accuracy = accuracy_score(y_test, y_pred)  
print(f"Accuracy: {accuracy}")

C++ 算法示例

在 C++ 中,可以使用一些机器学习库,如 mlpack 或 OpenCV,来实现 SVM。以下是一个使用 OpenCVOpenCV - Open Computer Vision Library 的 SVM 示例:

#include <opencv2/opencv.hpp>  
#include <opencv2/ml/ml.hpp>  
#include <iostream>  int main() {  // 加载数据(这里只是一个示例,实际数据需要自行准备)  cv::Mat_<float> trainingData(4, 2); // 4个样本,每个样本2个特征  cv::Mat_<int> labels(4, 1); // 4个标签  // 填充数据和标签(仅为示例)  trainingData << 501, 10, 255, 10, 501, 255, 10, 501;  labels << 1, -1, -1, 1;  // 创建 SVM 对象  cv::Ptr<cv::ml::SVM> svm = cv::ml::SVM::create();  svm->setType(cv::ml::SVM::C_SVC);  svm->setC(0.1);  svm->setKernel(cv::ml::SVM::LINEAR);  svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::MAX_ITER, 100, 1e-6));  // 训练 SVM  svm->train(trainingData, cv::ml::ROW_SAMPLE, labels);  // 预测  cv::Mat_<float> sample(1, 2);  sample << 400, 150; // 测试样本  float response = svm->predict(sample)[0];  std::cout << "Prediction for sample [" << sample << "] is: " << response << std::endl;  return 0;  
}

在这个 C++ 示例中,我们使用了 OpenCV 库来创建和训练一个 SVM 模型。需要注意的是,OpenCV 中的 SVM 实现与 scikit-learn 略有不同,特别是在参数设置和接口方面。你需要根据你的具体数据和任务来调整这些参数

在使用这些代码之前,请确保你已经正确安装了所需的库(如 scikit-learn 或 OpenCV),并根据你的环境和数据集调整代码。

4.5. 朴素贝叶斯(Naive Bayes)

  • 基础概念:朴素贝叶斯算法是基于贝叶斯定理和特征条件独立性假设的分类算法。
  • 算法示例:垃圾邮件过滤。通过分析邮件内容中的关键词,使用朴素贝叶斯模型来判断一封邮件是否为垃圾邮件。
4.5.1. 算法介绍

朴素贝叶斯算法基于以下两个核心思想:

  1. 贝叶斯定理:用于计算后验概率,即在已知某些特征的情况下,样本属于某个类别的概率。

  2. 特征条件独立假设:朴素贝叶斯假设各个特征之间相互独立,这是算法“朴素”之名的由来。尽管这个假设在实际应用中往往不成立,但朴素贝叶斯算法在很多情况下仍然表现良好。

算法步骤如下:

  1. 数据准备:准备训练数据集,包括特征和对应的类别标签。

  2. 计算先验概率:计算每个类别在训练数据中出现的概率。

  3. 计算条件概率:对于每个特征,计算它在每个类别中出现的概率。

  4. 应用贝叶斯定理:对于新的数据样本,使用贝叶斯定理和前面计算得到的先验概率及条件概率,计算该样本属于每个类别的后验概率。

  5. 分类决策:将样本分类到后验概率最大的类别中。

4.5.2. 算法示例

Python算法示例

在Python中,可以使用scikit-learn库中的GaussianNB(适用于连续特征)或MultinomialNB(适用于离散特征)等实现朴素贝叶斯分类器。以下是一个使用GaussianNB的示例:

from sklearn.datasets import load_iris  
from sklearn.model_selection import train_test_split  
from sklearn.naive_bayes import GaussianNB  
from sklearn.metrics import accuracy_score  # 加载数据集  
iris = load_iris()  
X, y = iris.data, iris.target  # 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 创建并训练朴素贝叶斯分类器  
gnb = GaussianNB()  
gnb.fit(X_train, y_train)  # 预测测试集并计算准确率  
y_pred = gnb.predict(X_test)  
accuracy = accuracy_score(y_test, y_pred)  
print(f"Accuracy: {accuracy}")

C++算法示例

在C++中实现朴素贝叶斯算法通常需要手动编写更多的代码,因为C++标准库没有直接提供机器学习算法。以下是一个简化的朴素贝叶斯分类器的C++示例,仅用于说明基本概念:

#include <iostream>  
#include <vector>  
#include <map>  // 假设特征只有一维,且为离散值  
struct DataPoint {  int feature;  int label;  
};  class NaiveBayesClassifier {  
private:  std::map<int, int> classCounts; // 类别计数  std::map<int, std::map<int, int>> featureCounts; // 特征在每个类别的计数  std::map<int, int> totalFeatureCounts; // 每个类别的总特征计数  public:  void train(const std::vector<DataPoint>& data) {  for (const auto& point : data) {  // 更新类别计数  classCounts[point.label]++;  // 更新特征计数  featureCounts[point.label][point.feature]++;  // 更新每个类别的总特征计数  totalFeatureCounts[point.label]++;  }  }  int predict(int feature) {  int bestClass = -1;  double maxProbability = 0.0;  for (const auto& classCount : classCounts) {  int classLabel = classCount.first;  int classTotalCount = classCount.second;  int featureCountInClass = featureCounts[classLabel][feature];  double probability = static_cast<double>(featureCountInClass + 1) / (totalFeatureCounts[classLabel] + 2); // 使用拉普拉斯平滑  if (probability > maxProbability) {  maxProbability = probability;  bestClass = classLabel;  }  }  return bestClass;  }  
};  int main() {  NaiveBayesClassifier classifier;  std::vector<DataPoint> trainingData = {  {1, 0}, {2, 0}, {1, 1}, {2, 1}, {3, 1}, {2, 0}  };  classifier.train(trainingData);  int prediction = classifier.predict(2);  std::cout << "Predicted class for feature 2: " << prediction << std::endl;  return 0;  
}

请注意,这个C++示例非常简化,仅用于教学目的。在实际应用中,朴素贝叶斯分类器可能需要处理多维特征和连续特征,这会增加实现的复杂性。此外,为了提高性能和准确性,可能还需要进行特征选择、特征转换和模型评估等步骤。

4.6. k-近邻算法(K-Nearest Neighbors, KNN)

  • 基础概念:KNN 是一种基于实例的学习算法,通过计算新数据与训练数据集中数据点之间的距离来找到最近的 k 个邻居,并根据这些邻居的类别来确定新数据的类别。
  • 算法示例:手写数字识别。可以使用 KNN 算法来识别手写数字图像。
4.6.1. k-近邻算法介绍

k-近邻算法(k-Nearest Neighbors,简称k-NN)是一种基于实例的学习算法,它的基本思想是通过测量不同数据点之间的距离进行分类。在k-NN中,一个对象的分类是由其邻居的“多数表决”确定的,k个最近邻居(k为正整数,通常较小)中最常见的分类决定了赋予该对象的类别。若k=1,则该对象的类别直接由最近的一个节点赋予。

4.6.2. k-近邻算法步骤
  1. 计算距离:对于未知分类的数据,计算它到每个已知分类数据之间的距离。
  2. 寻找邻居:按照距离的递增关系进行排序,然后选择距离最小的k个点。
  3. 确定类别:确定前k个点所在类别的出现频率,返回前k个点出现频率最高的类别作为预测分类。
4.6.3. 算法示例

Python算法示例

在Python中,我们可以使用scikit-learn库中的KNeighborsClassifier来实现k-NN算法。以下是一个简单的示例:

from sklearn import datasets  
from sklearn.model_selection import train_test_split  
from sklearn.preprocessing import StandardScaler  
from sklearn.neighbors import KNeighborsClassifier  
from sklearn.metrics import accuracy_score  # 加载iris数据集  
iris = datasets.load_iris()  
X = iris.data  
y = iris.target  # 划分训练集和测试集  
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)  # 数据标准化  
scaler = StandardScaler()  
X_train = scaler.fit_transform(X_train)  
X_test = scaler.transform(X_test)  # 创建k-NN分类器,并设置邻居数为3  
knn = KNeighborsClassifier(n_neighbors=3)  # 训练模型  
knn.fit(X_train, y_train)  # 预测测试集  
y_pred = knn.predict(X_test)  # 计算准确率  
accuracy = accuracy_score(y_test, y_pred)  
print(f"Accuracy: {accuracy}")

C++算法示例

在C++中实现k-NN算法需要手动编写距离计算、排序和分类的逻辑。以下是一个简化的k-NN分类器的C++示例:

#include <iostream>  
#include <vector>  
#include <algorithm>  
#include <cmath>  
#include <limits>  struct Point {  std::vector<double> features;  int label;  
};  double euclideanDistance(const std::vector<double>& a, const std::vector<double>& b) {  double sum = 0.0;  for (size_t i = 0; i < a.size(); ++i) {  sum += pow(a[i] - b[i], 2);  }  return sqrt(sum);  
}  int kNearestNeighbors(const std::vector<Point>& dataset, const std::vector<double>& point, int k) {  std::vector<std::pair<double, int>> distances; // 存储距离和对应的标签索引  for (size_t i = 0; i < dataset.size(); ++i) {  double dist = euclideanDistance(dataset[i].features, point);  distances.push_back(std::make_pair(dist, i));  }  // 按距离排序  std::sort(distances.begin(), distances.end());  // 统计k个最近邻居的标签  std::map<int, int> labelCounts;  for (int i = 0; i < k; ++i) {  int label = dataset[distances[i].second].label;  labelCounts[label]++;  }  // 找到出现次数最多的标签  int maxCount = 0;  int majorityLabel = -1;  for (const auto& entry : labelCounts) {  if (entry.second > maxCount) {  maxCount = entry.second;  majorityLabel = entry.first;  }  }  return majorityLabel;  
}  int main() {  std::vector<Point> dataset = {  {{1, 2}, 1}, {{1, 4}, 1}, {{3, 4}, 2}, {{4, 2}, 2}, {{2, 3}, 1}  };  std::vector<double> queryPoint = {2, 2};  int k = 3; // 设置k值  int predictedLabel = kNearestNeighbors(dataset, queryPoint, k);  std::cout << "Predicted label for point (" << queryPoint[0] << ", " << queryPoint[1] << "): " << predictedLabel << std::endl;  return 0;  
}

这个C++示例中,我们定义了一个Point结构体来存储数据点的特征和标签。euclideanDistance函数用于计算两个点之间的欧几里得距离。kNearestNeighbors函数实现了k-NN算法的核心逻辑,包括计算距离、排序、统计标签和确定多数类别。在main函数中,我们创建了一个简单的数据集,并设置了一个查询点和k值来演示算法的使用。

4.7. k-平均算法(K-Means)

  • 基础概念:K-Means 是一种无监督学习算法,用于将数据集中的样本划分为 k 个类别或簇。
  • 算法示例:市场细分。通过分析消费者的购买行为等数据,使用 K-Means 算法将消费者划分为不同的群体,以便制定更精准的营销策略。算法可以运用于游戏中游戏世界内商城控制、交易类金额控制,但真的不建议做在真银子换游戏币中,会有被惩罚的可能性哦
4.7.1. k-平均算法介绍

k-平均算法(k-means clustering)是一种非常流行的无监督学习算法,用于将数据点划分为K个集群。该算法的目标是使得每个数据点与其所属集群的中心点之间的距离之和最小。

4.7.2. k-平均算法步骤
  1. 初始化:选择K个点作为初始集群中心(这些点可以是数据集中的随机点)。
  2. 分配数据点到最近的集群中心:对于数据集中的每个点,计算它到每个集群中心的距离,并将其分配给最近的集群。
  3. 重新计算集群中心:对于每个集群,计算所有数据点的平均值,并将这个平均值设为新的集群中心。
  4. 迭代:重复步骤2和3,直到集群中心不再发生显著变化,或者达到预定的迭代次数。
4.7.3. 算法示例

Python算法示例

在Python中,我们可以使用scikit-learn库中的KMeans类来实现k-means算法。以下是一个简单的示例:

from sklearn.cluster import KMeans  
from sklearn.datasets import make_blobs  
import matplotlib.pyplot as plt  # 生成模拟数据  
X, y = make_blobs(n_samples=300, centers=4, cluster_std=0.60, random_state=0)  # 创建KMeans实例,并设置集群数量为4  
kmeans = KMeans(n_clusters=4)  # 训练模型  
kmeans.fit(X)  # 预测集群标签  
labels = kmeans.predict(X)  # 绘制结果  
plt.scatter(X[:, 0], X[:, 1], c=labels, s=50, cmap='viridis')  
plt.scatter(kmeans.cluster_centers_[:, 0], kmeans.cluster_centers_[:, 1], s=300, c='red', marker='x')  
plt.show()

C++算法示例

在C++中实现k-means算法需要手动编写距离计算、集群中心更新和数据点分配的逻辑。以下是一个简化的k-means算法的C++示例:

#include <iostream>  
#include <vector>  
#include <cmath>  
#include <limits>  
#include <ctime>  
#include <cstdlib>  struct Point {  double x, y;  int cluster;  
};  double distance(const Point& a, const Point& b) {  return std::sqrt(std::pow(a.x - b.x, 2) + std::pow(a.y - b.y, 2));  
}  void kMeansClustering(std::vector<Point>& data, int K, int maxIterations) {  srand(time(0)); // 使用当前时间作为随机数生成器的种子  // 初始化集群中心  std::vector<Point> centers(K);  for (int i = 0; i < K; ++i) {  centers[i] = data[rand() % data.size()]; // 随机选择数据点作为初始中心  centers[i].cluster = i; // 设置集群标签  }  bool changed;  int iteration = 0;  do {  changed = false;  // 分配数据点到最近的集群中心  for (auto& point : data) {  double minDist = std::numeric_limits<double>::max();  int closestCenter = -1;  for (int i = 0; i < K; ++i) {  double dist = distance(point, centers[i]);  if (dist < minDist) {  minDist = dist;  closestCenter = i;  }  }  if (point.cluster != closestCenter) {  point.cluster = closestCenter;  changed = true;  }  }  // 重新计算集群中心  if (changed || iteration == 0) {  for (int i = 0; i < K; ++i) {  double sumX = 0, sumY = 0;  int count = 0;  for (const auto& point : data) {  if (point.cluster == i) {  sumX += point.x;  sumY += point.y;  count++;  }  }  if (count > 0) {  centers[i].x = sumX / count;  centers[i].y = sumY / count;  }  }  }  iteration++;  } while (changed && iteration < maxIterations);  
}  int main() {  // 示例数据点(在实际应用中,这些数据通常是从文件或数据库中读取的)  std::vector<Point> data = { /* 填充数据点 */ };  const int K = 3; // 集群数量  const int maxIterations = 100; // 最大迭代次数  kMeansClustering(data, K, maxIterations);  // 输出集群结果或进行其他后续处理...  return 0;  
}

注意:上述C++示例代码是一个框架性的实现,你需要填充实际的数据点以及可能的其他逻辑来完成k-means算法的实现。在实际应用中,通常还需要添加更多的错误处理和优化。

4.8. 庆祝下

看到这里的小伙伴是壮士,写这些我自己也头秃,下一步加油,这只是刚开始哦~~~~

相关文章:

游戏AI的创造思路-技术基础-机器学习(2)

本篇存在大量的公式&#xff0c;数学不好的孩子们要开始恶补数学了&#xff0c;尤其是统计学和回归方程类的内容。 小伙伴们量力而行~~~~~ 游戏呢&#xff0c;其实最早就是数学家、元祖程序员编写的数学游戏&#xff0c;一脉相承传承至今&#xff0c;囊括了更多的设计师、美术…...

【深度学习】记录为什么没有调用GPU

排查CLIP为什么评测推理没有调用GPU&#xff0c;主要是这个代码&#xff1a;https://github.com/OFA-Sys/Chinese-CLIP/blob/master/cn_clip/eval/extract_features.py 第一次认为&#xff1a;因为model并没有to.cuda()。 但是又发现&#xff0c;model.cuda(args.gpu) # 已经加…...

vite 创建vue3项目 集成 ESLint、Prettier、Sass等

在网上找了一大堆vue3脚手架的东西&#xff0c;无非就是vite或者vue-cli,在vue2时代&#xff0c;vue-cli用的人挺多的&#xff0c;也很好用&#xff0c;然而vue3大多是和vite搭配搭建的&#xff0c;而且个人感觉vite这个脚手架并没有那么的好用&#xff0c;搭建项目时只能做两个…...

计算机系统基础知识(上)

目录 计算机系统的概述 计算机的硬件 处理器 存储器 总线 接口 外部设备 计算机的软件 操作系统 数据库 文件系统 计算机系统的概述 如图所示计算机系统分为软件和硬件&#xff1a;硬件包括&#xff1a;输入输出设备、存储器&#xff0c;处理器 软件则包括系统软件和…...

[深度学习]循环神经网络RNN

RNN&#xff08;Recurrent Neural Network&#xff0c;即循环神经网络&#xff09;是一类用于处理序列数据的神经网络&#xff0c;广泛应用于自然语言处理&#xff08;NLP&#xff09;、时间序列预测、语音识别等领域。与传统的前馈神经网络不同&#xff0c;RNN具有循环结构&am…...

【C++:list】

list概念 list是一个带头的双向循环链表&#xff0c;双向循环链表的特色&#xff1a;每一个节点拥有两 个指针进行维护&#xff0c;俩指针分别为prev和next,prev指该节点的前一个节点&#xff0c;next为该节点的后一个节点 list的底层实现中为什么对迭代器单独写一个结构体进行…...

解锁 Apple M1/M2 上的深度学习力量:安装 TensorFlow 完全指南

前言 随着 Apple M1 和 M2 芯片的问世&#xff0c;苹果重新定义了笔记本电脑和台式机的性能标准。这些强大的芯片不仅适用于日常任务&#xff0c;还能处理复杂的机器学习和深度学习工作负载。本文将详细介绍如何在 Apple M1 或 M2 芯片上安装和配置 TensorFlow&#xff0c;助你…...

Apache Iceberg:现代数据湖存储格式的未来

Apache Iceberg 是一个开源的表格式&#xff0c;用于在分布式数据湖中管理大规模数据集。它由 Netflix 开发&#xff0c;并捐赠给 Apache 基金会。Iceberg 的设计目标是解决传统数据湖存储格式&#xff08;如 Apache Hive 和 Apache Parquet&#xff09;在大规模数据管理中的一…...

【离散数学·图论】(复习)

一、基本概念 1.一些基本术语&#xff1a; 2.点u&#xff0c;v邻接&#xff08;或相邻&#xff09;: 边e称为关联顶点u和v,or e连接u和v; 3.G(V,E)中&#xff0c;顶点v所有邻居的集合&#xff1a;N(v), 成为v的邻域。 4.度 &#xff1a; deg(v) 5.悬挂点&#xff1a;度为1的…...

【ONLYOFFICE震撼8.1】ONLYOFFICE8.1版本桌面编辑器测评

随着远程工作的普及和数字化办公的发展&#xff0c;越来越多的人开始寻找一款具有强大功能和便捷使用的办公软件。在这个时候&#xff0c;ONLYOFFICE 8.1应运而生&#xff0c;成为了许多用户的新选择。ONLYOFFICE 8.1是一种办公套件软件&#xff0c;它提供了文档处理、电子表格…...

Shell 脚本编程保姆级教程(上)

一、运行第一个 Shell 脚本 1.1 Shell 脚本 Shell 脚本&#xff08;shell script&#xff09;&#xff0c;是一种为 shell 编写的脚本程序。 业界所说的 shell 通常都是指 shell 脚本&#xff0c;但读者朋友要知道&#xff0c;shell 和 shell script 是两个不同的概念。 由…...

凸优化相关文章汇总

深度学习/机器学习入门基础数学知识整理&#xff08;三&#xff09;&#xff1a;凸优化&#xff0c;Hessian&#xff0c;牛顿法_深度学习和凸优化-CSDN博客 深度学习/机器学习入门基础数学知识整理&#xff08;四&#xff09;&#xff1a;拟牛顿法、BFGS、L-BFGS、DFP、共轭梯…...

Java鲜花下单预约系统源码小程序源码

让美好触手可及 &#x1f338;一、开启鲜花新篇章 在繁忙的都市生活中&#xff0c;我们总是渴望那一抹清新与美好。鲜花&#xff0c;作为大自然的馈赠&#xff0c;总能给我们带来无尽的惊喜与愉悦。但你是否曾因为工作繁忙、时间紧张而错过了亲自挑选鲜花的机会&#xff1f;今…...

网络变压器和RJ45接线的方法

网络变压器在以太网硬件电路设计中扮演着重要的角色&#xff0c;它主要用于信号电平耦合、隔离外部干扰、实现阻抗匹配以及增加传输距离。而RJ45接口则是以太网连接的标准化接口&#xff0c;它提供了与网络电缆的连接点。 网络变压器与RJ45的接线方法通常遵循以下步骤&#xf…...

Matlab/simulink三段式电流保护

电流1段仿真波形如下所示 电流2段仿真波形如下所示 电流3段仿真波形如下所示...

OOXML入门学习

进入-飞入 <par> <!-- 这是一个并行动画序列的开始。"par"代表并行&#xff0c;意味着在这个标签内的所有动画将同时开始。 --><cTn id"5" presetID"2" presetClass"entr" presetSubtype"4" fill"hold&…...

k8s集群node节点加入失败

出现这种情况&#xff1a; [preflight] FYI: You can look at this config file with kubectl -n kube-system get cm kubeadm-config -o yaml [kubelet-start] Writing kubelet configuration to file "/var/lib/kubelet/config.yaml" [kubelet-start] Writing kub…...

layui+jsp项目中实现table单元格嵌入下拉选择框功能,下拉选择框可手动输入内容或选择默认值,修改后数据正常回显。

需求 table列表中的数据实现下拉框修改数据&#xff0c;当默认的下拉框不符合要求时&#xff0c;可手动输入内容保存。内容修改后表格显示修改后的值同时表格不刷新。 实现 layui框架下拉框组件只能选择存在的数据&#xff0c;不支持将输入的内容显示在input中的功能&#x…...

2024年客户体验的几个预测

数字化转型、以客户为中心的理念、数字技术的发展和产品的不断创新&#xff0c;都为客户体验带来了巨大的改变。 目前&#xff0c;我们看到很多公司都在致力于塑造一种以客户为中心的商业模式。企业开始用更多技术、更多数据和更多产品来强化自己在客户体验方面的能力。 那么&a…...

【C++】动态内存管理new和delete

文章目录 一、C的内存管理方式二、new和delete的用法1.操作内置类型2.操作自定义内置类型 三、new和delete的底层实现1.operator new和operator delete函数2.new和delete的实现原理 四、定位new表达式五、malloc/free和new/delete的区别 一、C的内存管理方式 之前在C语言的动态…...

Java面向对象特性

Java继承&#xff1a; 继承的概念&#xff1a; 在Java中&#xff0c;继承&#xff08;inheritance&#xff09;是面向对象编程的一个重要概念&#xff0c;它允许一个类&#xff08;子类&#xff09;继承另一个类&#xff08;父类&#xff09;的属性和方法。通过继承&#xff0c…...

odoo17 tree视图添加按钮

需求描述 点击下图中tree视图上的同步退货单按钮,弹出相应的form视图进行退货单同步,然后点击同步按钮调用后端python代码处理。 实现步骤 主要文件目录结构 js文件的创建 /** @odoo-module **/ import {registry } from "@web/core/registry"; import {listVie…...

PreparedStatement 与Statement 的区别,以及为什么推荐使用 PreparedStatement ?

在Java中&#xff0c;PreparedStatement和Statement都是用于执行SQL语句的重要接口&#xff0c;但它们在功能、安全性和性能上有着显著的差异。理解这些差异对于编写高效且安全的数据库应用程序至关重要。 Statement&#xff1a;基本的SQL执行者 首先&#xff0c;让我们从Sta…...

wsl ubuntu 安装Anaconda3步骤

如何在Ubuntu上安装Anaconda3呢?本章记录整个安装过程。 1、下载脚本 https://mirrors.bfsu.edu.cn/anaconda/archive/Anaconda3-2023.09-0-Linux-x86_64.sh 下载之后,将脚本上传到Ubuntu里。 2、安装脚本 bash Anaconda3-2021.11-Linux-x86_64.sh根据提示进行安装,提示输…...

Vue3响应式 ref全家桶

<template><div>{{ man.name }}<hr><button click"change">修改</button></div> </template> <script setup lang"ts"> const man {name:"cc"} const change () >{man.name "大cc&q…...

Mac(M1芯片)安装多个jdk,Mac卸载jdk

1.jdk下载 oracle官方链接&#xff1a;oracle官方下载链接 2.安装 直接下一步&#xff0c;下一步就行 3.查看是否安装成功 出现下图内容表示安装成功。 4.配置环境变量 open -e .bash_profile 路径建议复制过去 #刷新环境变量 source ~/.bash_profile 5.切换方法 6.jdk…...

Warning message:package ‘ggplot2’ is not available (for R version 3.2.3)

install.packages(ggplot2) Installing package into ‘/usr/local/lib/R/site-library’ (as ‘lib’ is unspecified) Warning message: package ‘ggplot2’ is not available (for R version 3.2.3) 根据你提供的信息&#xff0c;警告消息表明在你的R版本&#xff08;3.2.3…...

Spring Boot 过滤器和拦截器详解

目录 Spring Boot 过滤器1.什么是过滤器2.工作机制3.实现过滤器 Spring Boot 拦截器1. 什么是拦截器2. 工作原理3.实现4.拓展&#xff08;MethodInterceptor 拦截器&#xff09;实现 过滤器和拦截器区别过滤器和拦截器应用场景过滤器拦截器 Spring Boot 过滤器 1.什么是过滤器 …...

Eureka介绍与使用

Eureka是一个开源的服务发现框架&#xff0c;由Netflix开发并在2015年成为Apache的顶级项目。Eureka的核心功能是服务注册与发现&#xff0c;它允许微服务应用在启动时将自己注册到Eureka服务器&#xff0c;并能通过Eureka服务器来发现其他已注册的服务。 使用Eureka有以下几个…...

JVM专题九:JVM分代知识点梳理

今天开始&#xff0c;咱们开始剖析JVM内存划分的原理细节&#xff0c;以及我们创建的那些对象在JVM中到底是如何分配&#xff0c;如何流动的&#xff0c;首先解决第一个问题&#xff1a;JVM内存的一个分代模型:年轻代、老年代、永久通过之前的专题我们知道&#xff0c;那就是我…...

wireshark常用过滤命令

wireshark常用过滤命令 wireshark抓包介绍单机单点&#xff1a;单机多点&#xff1a;双机并行&#xff1a; wireshark界面认识默认布局调整布局(常用)显示FCS错误 wireshark常见列Time回包数据报对应网络模型 wireshark基本操作结束抓包再次开始抓包 **wireshark常用过滤命令**…...

「全新升级,性能更强大——ONLYOFFICE 桌面编辑器 8.1 深度评测」

文章目录 一、背景二、界面设计与用户体验三、主要新功能亮点3.1 高效协作处理3.2 共同编辑&#xff0c;毫无压力3.3 批注与提及3.4 追踪更改3.5 比较与合并3.6 管理版本历史 四、性能表现4.1 集成 AI 工具4.2 插件强化 五、用户反馈与使用案例 一、背景 Ascensio System SIA -…...

线程版服务器实现(pthread_server)

用到的所有方法所需要的参数可以在wrap.c文件中查询&#xff0c;wrap中找不到的直接通过man手册查询 1.首先介绍一下我自己写的包裹文件&#xff0c;里面有各种在可能要用到的方法 wrap.c: #include <stdlib.h> #include <stdio.h> #include <unistd.h> #…...

js异常处理方案

文章目录 异常处理方案同步代码的异常处理Promise 的异常处理async await 的异常处理 感谢阅读&#xff0c;觉得有帮助可以点点关注点点赞&#xff0c;谢谢&#xff01; 异常处理方案 在JS开发中&#xff0c;处理异常包括两步&#xff1a;先抛出异常&#xff0c;然后捕获异常。…...

C++文件路径处理2 - 路径拼接路径解析

1. 关键词2. filesystem.h3. filepath.cpp6. 测试代码7. 运行结果8. 源码地址 1. 关键词 关键词&#xff1a; C 文件路径处理 路径拼接 获取父目录的路径 获取文件名 获取拓展名 跨平台 应用场景&#xff1a; 路径的拼接路径的解析 2. filesystem.h #pragma once#include…...

数据结构5---矩阵和广义表

一、矩阵的压缩存储 特殊矩阵:矩阵中很多值相同的元素并且它们的分布有一定的规律。 稀疏矩阵:矩阵中有很多零元素。压缩存储的基本思想是: (1)为多个值相同的元素只分配一个存储空间; (2)对零元素不分配存储空间。 1、特殊矩阵的压缩存储 &#xff08;1&#xff09;对称矩…...

jquery使用infinitescroll无线滚动+自定义翻页

jquery版本 jquery-1.8.3.js infinitescroll版本 2.0.0 如果infinitescroll版本最新的jquery版本也要用新的 接口用nodejs jquery.infinitescroll.js官网地址 前端代码《接口返回JSON数据》 <!DOCTYPE html> <html lang"en"> <head><meta cha…...

【漏洞复现】锐捷统一上网行为管理与审计系统——远程命令执行漏洞

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 锐捷统一上网行为管理与审计系统naborTable/static_convert.php…...

通义灵码上线 Visual Studio 插件市场啦!

通义灵码&#xff0c;是阿里云出品的一款基于通义大模型的智能编码辅助工具&#xff0c;提供行级/函数级实时续写、自然语言生成代码、单元测试生成、代码优化、注释生成、代码解释、研发智能问答、异常报错排查等能力&#xff0c;提供代码智能生成、研发智能问答能力。 通义灵…...

GESP 四级急救包(2):客观题真题集

客观题真题集 一、选择题1. 真题梳理2. 真题答案3. 重难点点播(1) 指针和地址(2) 时间复杂度 二、判断题1. 真题梳理2. 真题答案 一、选择题 1. 真题梳理 若函数声明为 void f(int &a, int b, const int &c)&#xff0c;且在主函数内已经声明了 x , y , z x,y,z x,y,…...

VERYCLOUD睿鸿股份确认参展2024年ChinaJoy BTOB商务洽谈馆,期待与你相聚

作为在全球数字娱乐领域兼具知名度与影响力的年度盛会&#xff0c;2024年第二十一届ChinaJoy将于7月26日至7月29日在上海新国际博览中心盛大召开&#xff0c;本届展会主题为&#xff1a;初心“游”在&#xff0c;精彩无限&#xff01;&#xff08;Stay True, Game On.&#xff…...

Java面试题:讨论Spring框架的核心组件,如IoC容器、AOP、事务管理等

Spring框架是一个功能强大且灵活的Java企业级应用开发框架&#xff0c;其核心组件包括以下几个主要部分&#xff1a; 1. IoC容器&#xff08;Inversion of Control Container&#xff09; IoC容器是Spring框架的核心部分&#xff0c;用于管理应用程序的依赖注入&#xff08;D…...

【方案】基于5G智慧工业园区解决方案(PPT原件)

5G智慧工业园区整体解决方案旨在通过集成5G通信技术、物联网、大数据和云计算等先进技术&#xff0c;实现园区的智能化、高效化和绿色化。 该方案首先构建高速、稳定的5G网络&#xff0c;确保园区内设备、人员与物流的实时连接和高效沟通。其次&#xff0c;通过工业物联网技术&…...

使用System.currentTimeMillis获取当前时间

使用System.currentTimeMillis获取当前时间 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来探讨Java中如何使用System.currentTimeMillis()方法来获取…...

手机远程控制另一台手机的全新使用教程(安卓版)

看完这篇文章&#xff0c;你可以了解到安卓手机如何远程控制安卓手机&#xff0c;以及苹果手机如何远程控制安卓手机。 如果想要用安卓手机远程管控苹果手机&#xff0c;或者苹果手机远程管控另一台苹果手机&#xff0c;请点击查看视频《手机远程管控另一台手机的全新使用教程…...

商城积分系统的代码实现(上)-- 积分账户及收支记录

一、背景 上一系列文章&#xff0c;我们说了积分的数模设计及接口设计&#xff0c;接下里&#xff0c;我们将梳理一下具体的代码实现。 使用的语言的java&#xff0c;基本框架是spring-boot&#xff0c;持久化框架则是Jpa。 使用到的技术点有&#xff1a; 分布式锁&#xf…...

【C++进阶9】异常

一、C语言传统的处理错误的方式 终止程序&#xff0c;如assert 如发生内存错误&#xff0c;除0错误时就会终止程序返回错误码 需要程序员自己去查找对应的错误 z如系统的很多库的接口函数都是通 过把错误码放到errno中&#xff0c;表示错误 二、C异常概念 异常&#xff1a;函…...

RecyclerVIew->加速再减速的RecyclerVIew平滑对齐工具类SnapHelper

XML文件 ItemView的XML文件R.layout.shape_item_view <?xml version"1.0" encoding"utf-8"?> <FrameLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"100dp"android:layout_heig…...

突破SaaS产品运营困境:多渠道运营如何集中管理?

随着数字化时代的到来&#xff0c;SaaS&#xff08;软件即服务&#xff09;产品已成为企业日常运营不可或缺的工具。然而&#xff0c;在竞争激烈的市场环境下&#xff0c;SaaS产品运营越来越重视多渠道、多平台布局&#xff0c;以更广泛地触及潜在用户&#xff0c;然而&#xf…...

智能语音热水器:置入NRK3301离线语音识别ic 迈向智能家居新时代

一、热水器语音识别芯片开发背景 在科技的今天&#xff0c;人们对于生活品质的追求已不仅仅满足于基本的物质需求&#xff0c;更渴望通过智能技术让生活变得更加便捷、舒适。热水器作为家庭生活中不可或缺的一部分&#xff0c;其智能化转型势在必行。 在传统热水器使用中&#…...

解析Kotlin中扩展函数与扩展属性【笔记摘要】

1.扩展函数 1.1 作用域&#xff1a;扩展函数写的位置不同&#xff0c;作用域就也不同 扩展函数可以写成顶层函数&#xff08;Top-level Function&#xff09;&#xff0c;此时它只属于它所在的 package。这样你就能在任何类里使用它&#xff1a; package com.rengwuxianfun …...

沃尔核材:价值重估

当英伟达这个曾经的GPU行业龙头&#xff0c;伴随AI的发展成为AI芯片架构的供应商时&#xff0c;他就跳出了原本行业的竞争格局&#xff0c;曾经还能与之一战的超威半导体被远远甩在身后&#xff0c;成为宇宙第一公司。 这说的就是一家公司价值的重估。今天给大家聊的也是这样一…...

探索 Java 8 中的 Stream API

探索 Java 8 中的 Stream API Java 8 引入了 Stream API&#xff0c;极大地简化了对集合&#xff08;如 List、Set&#xff09;的操作。Stream 提供了一种声明式的方式来处理数据&#xff0c;允许我们使用类似 SQL 的操作来操作集合。本文将详细介绍 Java 中的 Stream API&…...

Pytorch实战(一):LeNet神经网络

文章目录 一、模型实现1.1数据集的下载1.2加载数据集1.3模型训练1.4模型预测 LeNet神经网络是第一个卷积神经网络&#xff08;CNN&#xff09;&#xff0c;首次采用了卷积层、池化层这两个全新的神经网络组件&#xff0c;接收灰度图像&#xff0c;并输出其中包含的手写数字&…...

微服务-网关Gateway

个人对于网关路由的理解&#xff1a; 网关就相当于是一个项目里面的保安&#xff0c;主要作用就是做一个限制项。&#xff08;zuul和gateway两个不同的网关&#xff09; 在路由中进行配置过滤器 过滤器工厂&#xff1a;对请求或响应进行加工 其中filters&#xff1a;过滤器配置…...

SPI通信精粹:STM32微控制器驱动W25Q64存储器实战技巧

摘要 在嵌入式开发中&#xff0c;SPI通信是一种高效、灵活的串行通信方式&#xff0c;广泛应用于微控制器与外设之间的数据交换。W25Q64作为一种高性能的SPI Flash存储器&#xff0c;提供了8Mbit的存储容量&#xff0c;非常适合STM32微控制器使用。本文将分享使用STM32微控制器…...

夜读朱大建:海菜花,清水的精灵

海菜花不光美丽,还是美味。去年6月5日世界环境日当天,我写的生态纪实文学《海菜花开》,由上海交通大学出版社召开出版座谈会,全国有十多家媒体刊发报道或书评。当月,该书就印了三次。去年9月,由上海交大创作、学生主演的校园话剧《海菜花开》在闵行校区菁菁堂演出。今年3…...

新车凯美瑞买什么配置性价比最高,全新第九代:B级车市场新标杆

全新凯美瑞买什么配置性价比最高**广汽丰田第九代凯美瑞:B级车市场的璀璨明星**3月30日,广汽丰田第九代凯美瑞震撼上市,以其卓越的智能电混技术、智能座舱、智驾安全及无与伦比的驾乘质感,重新定义了中高级轿车市场的标杆。这款车型不仅价格亲民,介于17.18万元至20.68万元之…...

ffmpeg3.1.1版本连接ftp服务器失败

发现这个问题是在ffmpeg4之后修复的&#xff1a; 原因在于libavformat文件下的ftp.c文件&#xff1a; 修改方法&#xff1a;加入在TCP控制连接时加入应答代码202&#xff1a; static int ftp_features(FTPContext *s) {static const char *feat_command "FEAT\r\…...

如何恢复被盗的加密货币?

本世纪&#xff0c;网络犯罪的首要目标是加密货币。 这要归功于加密货币的日益普及和价值&#xff0c;网络犯罪分子已经认识到经济收益的潜力&#xff0c;并将重点转向利用这种数字资产中的漏洞。 在今天的文章中&#xff0c;我们将讨论加密货币恢复和被盗加密货币恢复。 我们…...

在Spring中自定义事件及发布与监听

在Spring框架中&#xff0c;自定义事件及其发布与监听是一个涉及Spring事件机制的过程。Spring提供了一个基于观察者模式的事件发布和监听机制&#xff0c;允许在Spring容器中的组件之间进行松耦合的通信。以下是如何自定义事件以及如何发布和监听这些事件的步骤&#xff1a; …...

ESP32 - Micropython ESP-IDF 双线教程 WIFI (1)

ESP32 - Micropython ESP-IDF 双线教程 WIFI ESP32-WIFI介绍1. 工作模式2. 主要功能3. 编程接口总结 ESP32 - Micropython WIFIESP32-MicroPython Wi-Fi 功能示例代码代码解释注意事项 ESP32中的Wi-Fi功能是其核心特性之一&#xff0c;它基于IEEE 802.11标准&#xff0c;提供了…...