快速生成一组环形数据

  sklearn是一个开源的机器学习库,支持不同种类的机器学习算法,并且提供了许多质量良好的数据集。假如我们想要得到一组环形数据集,借助sklearn的包很轻易就可以实现,不过换个角度思考,我们自己动手是否也可以生成一组数据,使之在散点图上环状分布;借助C++的random头文件以及一点高中数学知识,我们很快也可以打造属于自己的数据集。

快速生成一组环形数据

  简单回顾一下,ρ与x和y之间的关系,y=ρsin(θ),x=ρcos(θ)。这是第一象限的情况,对于其它象限,只需要注意角度和符号的关系便可。

#include <iostream> #include <fstream> #include <random> #include <string> #include <utility> #include <cmath>  std::random_device rd; std::mt19937 g(rd()); std::uniform_real_distribution dis(0.0, M_PI * 2);  std::pair<double, double> circleData(double radius) {     double tolerance = radius / (30.0 + dis(g));     int n;     double d = dis(g);     if (d < M_PI)         n = 1;     else          n = -1;      double r = radius + n * tolerance * dis(g);     double x, y;     double sita = dis(g);     double mapping = sita / (M_PI / 2);      if (mapping < 1.0) {         x = r * cos(sita);         y = r * sin(sita);     } else if (mapping < 2.0) {         x = -r * cos(M_PI - sita);         y = r * sin(M_PI - sita);     } else if (mapping < 3.0) {         x = -r * cos(sita - M_PI);         y = -r * sin(sita - M_PI);     } else {         x = r * cos(2 * M_PI - sita);         y = -r * sin(2 * M_PI - sita);     }      return std::pair<double, double>{x, y}; }  void generateData(const std::string& path, std::size_t n = 1000, double radius = 1000.0) {     std::ofstream out{path};      out << "X,Yn";     for (std::size_t i{}; i < n; ++i) {         std::pair<double, double> pii = circleData(radius);         std::string str = std::to_string(pii.first) + ',' + std::to_string(pii.second) + 'n';         out << str;     } }  int main() {     std::string str{};     std::cin >> str;     generateData(str); }

  需要额外补充几点:1.生成的数据并不必完全呈环状,有稍微的偏差更加符合随机性,所以这里定义了tolerance变量,允许在半径范围内有一定的误差。2.生成的数据会写入csv格式的文件当中,而csv格式下的数据说白了就是一堆以逗号作为分割界限的字符串,后面用借助Python的pandas库便能很容易地对csv格式文件进行解析。3.为了确定随机生成的角度属于哪一象限,只需要除以(pi/2)即可判断,浮点数比较带来的精度丢失可接受。

  接下来打开Python的编辑器,只需要写入下列代码:

import pandas as pd import matplotlib.pyplot as plt   def f():     file = 'data.csv'     data = pd.read_csv(file)      x = data['X']     y = data['Y']      plt.scatter(x, y)     plt.title('Circle Data')     plt.xlabel('X')     plt.ylabel('Y')     plt.show()  if __name__ == '__main__':     f()

快速生成一组环形数据

  这是在半径为10000时的效果,为了多作几组对比,我们分别选取半径为100,1000的图片进行测试。

快速生成一组环形数据

快速生成一组环形数据

  总结:效果看上去都还不错,不过并不一定任何时候都能满足需求,可以对代码当中的参数进行一定的调整,生成更符合预期的数据集。

发表评论

评论已关闭。

相关文章