全文目录:
1. 从三体运动到太阳黑子变化预测
2. 数据导入
3. 读取数据
4. 将数据集划分为训练集和测试集
5. 定义 1DConv+LSTM 神经网络模型
6. 使用训练好的模型预测 MSSN
7. 与真实值对比的可视化结果
分享嘉宾|彭靖田 Google Developer Expert
出品社区|DataFun
从三体运动到太阳黑子变化预测

2. 太阳黑子变化观测数据集简介

02
Filename: SN_m_tot_V2.0.csvFormat: Comma Separated values (adapted for import in spreadsheets)The separator is the semicolon ';'.Contents:Column 1-2: Gregorian calendar date- Year- MonthColumn 3: Date in fraction of year.Column 4: Monthly mean total sunspot number.Column 5: Monthly mean standard deviation of the input sunspot numbers.Column 6: Number of observations used to compute the monthly mean total sunspot number.Column 7: Definitive/provisional marker. '1' indicates that the value is definitive. '0' indicates that the value is still provisional.
我们使用 pandas 进行文件加载和预览:
import pandas as pddf = pd.read_csv("SN_m_tot_V2.0.csv", sep=";", header=None)df.columns = ["year", "month", "date_fraction", "mssn", "standard_deviation", "observations", "marker"]# convert year and month to stringsdf["year"] = df["year"].astype(str)df["month"] = df["month"].astype(str)# concatenate year and monthdf["date"] = df["year"] + "-" + df["month"]df.head()

import matplotlib.pyplot as pltdf["Date"] = pd.to_datetime(df["date"], format="%Y-%m")plt.plot(df["Date"], df["mssn"])plt.xlabel("Date")plt.ylabel("MSSN")plt.title("Sunspot Activity Over Time")plt.show()

1. 使用时序数据库 CnosDB 存储 MSSN 数据
Official Website: http://www.cnosdb.com Github Repo: https://github.com/cnosdb/cnosdb
(base) root@ecs-django-dev:~# docker run --restart=always --name cnosdb -d --env cpu=2 --env memory=4 -p 31007:31007 cnosdb/cnosdb:v2.0.2.1-beta(base) root@ecs-django-dev:~# docker exec -it cnosdb sh sh# cnosdb-cliCnosDB CLI v2.0.0Input arguments: Args { host: "0.0.0.0", port: 31007, user: "cnosdb", password: None, database: "public", target_partitions: None, data_path: None, file: [], rc: None, format: Table, quiet: false }
为了简化分析,我们只需存储数据集中观测时间和太阳黑子数。因此,我们将年(Col 0)和月(Col 1)拼接作为观测时间(date, 字符串类型),月均太阳黑子数(Col 3)可以不作处理直接存储。
public ❯ CREATE TABLE sunspot (date STRING,mssn DOUBLE,);Query took 0.002 seconds.public ❯ SHOW TABLES;+---------+| Table |+---------+| sunspot |+---------+Query took 0.001 seconds.public ❯ SELECT * FROM sunspot;+------+------+------+| time | date | mssn |+------+------+------++------+------+------+Query took 0.002 seconds.
2. 使用 CnosDB Python Connector 连接和读写 CnosDB 数据库
# 安装 Python Connectorpip install -U cnos-connector
from cnosdb_connector import connectconn = connect(url="http://127.0.0.1:31001/", user="root", password="")cursor = conn.cursor()
# 创建 tf_demo databaseconn.create_database("tf_demo")# 使用 tf_demo databaseconn.switch_database("tf_demo")print(conn.list_database())cursor.execute("CREATE TABLE sunspot (date STRING, mssn DOUBLE,);")print(conn.list_table())
[{'Database': 'tf_demo'}, {'Database': 'usage_schema'}, {'Database': 'public'}][{'Table': 'sunspot'}]
### df 为pandas的dataframe,"sunspot"为CnosDB中的表名,['date', 'mssn']为需要写入的列的名字### 如果写入的列不包含时间列,将会根据当前时间自动生成conn.write_dataframe(df, "sunspot", ['date', 'mssn'])
参考论文:程术, 石耀霖, 张怀. 基于神经网络预测太阳黑子变化 (2022).
链接: http://journal.ucas.ac.cn/CN/10.7523/j.ucas.2021.0068

使用 CnosDB 读取数据
df = pd.read_sql("select * from sunspot;", conn)print(df.head())

04
import numpy as np# Convert the data values to numpy for better and faster processingtime_index = np.array(df['date'])data = np.array(df['mssn'])# ratio to split the dataSPLIT_RATIO = 0.8# Dividing into train-test splitsplit_index = int(SPLIT_RATIO * data.shape[0])# Train-Test Splittrain_data = data[:split_index]train_time = time_index[:split_index]test_data = data[split_index:]test_time = time_index[split_index:]

import tensorflow as tf## required parametersWINDOW_SIZE = 60BATCH_SIZE = 32SHUFFLE_BUFFER = 1000## function to create the input featuresdef ts_data_generator(data, window_size, batch_size, shuffle_buffer):'''Utility function for time series data generation in batches'''ts_data = tf.data.Dataset.from_tensor_slices(data)ts_data = ts_data.window(window_size + 1, shift=1, drop_remainder=True)ts_data = ts_data.flat_map(lambda window: window.batch(window_size + 1))ts_data = ts_data.shuffle(shuffle_buffer).map(lambda window: (window[:-1], window[-1]))ts_data = ts_data.batch(batch_size).prefetch(1)return ts_data# Expanding data into tensors# Expanding data into tensorstensor_train_data = tf.expand_dims(train_data, axis=-1)tensor_test_data = tf.expand_dims(test_data, axis=-1)## generate input and output features for training and testing settensor_train_dataset = ts_data_generator(tensor_train_data, WINDOW_SIZE, BATCH_SIZE, SHUFFLE_BUFFER)tensor_test_dataset = ts_data_generator(tensor_test_data, WINDOW_SIZE, BATCH_SIZE, SHUFFLE_BUFFER)
定义 1DConv+LSTM 神经网络模型
model = tf.keras.models.Sequential([tf.keras.layers.Conv1D(filters=128, kernel_size=3, strides=1, input_shape=[None, 1]),tf.keras.layers.MaxPool1D(pool_size=2, strides=1),tf.keras.layers.LSTM(128, return_sequences=True),tf.keras.layers.LSTM(64, return_sequences=True),tf.keras.layers.Dense(132, activation="relu"),tf.keras.layers.Dense(1)])
## compile neural network modeloptimizer = tf.keras.optimizers.Adam(learning_rate=1e-3)model.compile(loss="mse",optimizer=optimizer,metrics=["mae"])## training neural network modelhistory = model.fit(tensor_train_dataset, epochs=20, validation_data=tensor_test_dataset)

# summarize history for lossplt.plot(history.history['loss'])plt.plot(history.history['val_loss'])plt.title('model loss')plt.ylabel('loss')plt.xlabel('epoch')plt.legend(['train', 'test'], loc='upper left')plt.show()

def model_forecast(model, data, window_size):ds = tf.data.Dataset.from_tensor_slices(data)ds = ds.window(window_size, shift=1, drop_remainder=True)ds = ds.flat_map(lambda w: w.batch(window_size))ds = ds.batch(32).prefetch(1)forecast = model.predict(ds)return forecastrnn_forecast = model_forecast(model, data[..., np.newaxis], WINDOW_SIZE)rnn_forecast = rnn_forecast[split_index - WINDOW_SIZE:-1, -1, 0]# Overall Errorerror = tf.keras.metrics.mean_absolute_error(test_data, rnn_forecast).numpy()print(error)
101/101 [==============================] - 2s 18ms/step24.676455
plt.plot(test_data)plt.plot(rnn_forecast)plt.title('MSSN Forecast')plt.ylabel('MSSN')plt.xlabel('Month')plt.legend(['Ground Truth', 'Predictions'], loc='upper right')plt.show()

1. CnosDB快速上手指南: https://docs.cnosdb.com
2. CnosDB官网: https://www.cnosdb.com
今天的分享就到这里,谢谢大家。

分享嘉宾
INTRODUCTION

彭靖田

Google Developer Expert

谷歌加速器创业导师,《深入理解TensorFlow》,《TensorFlow快速入门与实战》作者,品览 联合创始人兼CTO。
参与CnosDB社区交流群:
扫描下方二维码,加入CC进入CnosDB社区进入社区交流,CC也会在群内分享直播链接哒




视频号开张啦:
戳一下👇二维码,关注CnosDB视频号,CC不久将会在视频号里🆙新的视频哦~



👇点击阅读原文前往CnosDB官网




