今日to do list:
- 做kaggle上面的流量預測項目??
- 學習時不刷手機🤡
okkkkkkkkkkkkkk
開始👍🍎
0、我在干什么?
我在預測一個名字叫做elborn基站的下行鏈路流量,用過去29天的數據預測未來10天的數據
1、import libararies
一般必須都要導入的庫有
- import pandas as pd : data processing, like pd.read.csv…
- import numpy as np :線性代數
- import matplotlib.pyplot as plt :畫圖
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)
import numpy as np # linear algebra
import warnings
warnings.filterwarnings('ignore') # 忽略警告信息
import matplotlib.pyplot as plt
2、加載數據load data
對csv數據使用pandas.read_csv函數讀取
一些參數:
- filepath_or_buffer: 文件路徑或緩沖區。可以是本地文件路徑,也可以是文件對象、URL等
- header: 列名索引。指定數據文件中列名的索引。默認為None,表示沒有列名。取值可以是整數,表示第幾行為列名;也可以是None,表示自動檢測列名;還可以是列表,表示指定列名的位置。
- na_values: 缺失值。指定用于替換缺失值的字符或列表。默認為[‘NA’, ‘null’, ‘NaN’]。
- index_col: 索引列。指定數據文件中用于索引的列。默認為None,表示沒有索引列。取值可以是整數,表示第幾列用于索引;也可以是列名,表示指定列用于索引。
- sep: 分隔符。用于分隔數據行的字段。默認為逗號,。
- delimiter: 分隔符。與sep類似,但它是更通用的參數,可以用于其他類型的分隔符,如制表符\t等。
elborn_df = pd.read_csv('dataset/ElBorn.csv')
elborn_test_df = pd.read_csv('dataset/ElBorn_test.csv')
3、獨家觀察數據函數 💓
💥basic_eda💥
- 前五行
- 顯示DataFrame的詳細信息,包括列名、數據類型、缺失值
- 顯示DataFrame的統計摘要信息,包括每列的平均值、標準差、最小值、最大值等
- 顯示列名
- 各列的數據類型
- 是否有缺失值
- 是否有NULL值
- 數據的形狀
def basic_eda(df):print("-------------------------------TOP 5 RECORDS-----------------------------")print(df.head(5))print("-------------------------------INFO--------------------------------------")print(df.info())print("-------------------------------Describe----------------------------------")print(df.describe())print("-------------------------------Columns-----------------------------------")print(df.columns)print("-------------------------------Data Types--------------------------------")print(df.dtypes)print("----------------------------Missing Values-------------------------------")print(df.isnull().sum())print("----------------------------NULL values----------------------------------")print(df.isna().sum())print("--------------------------Shape Of Data---------------------------------")print(df.shape)print("============================================================================ \n")
basic_eda(elborn_df)
basic_eda(elborn_test_df)
然后畫圖看一下💥
# 我現在想把elborn_df畫出來,橫坐標是時間,縱坐標是down,并且橫坐標的標簽要旋轉45度書寫
plt.plot(elborn_df.index, elborn_df.down)
plt.xlabel('Time')
plt.ylabel('Down')
plt.title('Down')
# 我想把橫坐標的日期標簽旋轉45
plt.xticks(rotation=45)
在這里面的Python小知識總結(純小白哈🌸)
- DataFrame.index:將得到DataFrame的索引(日期),作為Series對象
- 如果DataFrame的index是整數,則返回一個從0開始的整數序列
- 0 0
1 1
2 2
3 3
4 4
5 5
6 6
7 7
8 8
9 9
Name: index, dtype: int64
- plt.plot():繪制折線的基本函數
以下是一些參數- x: x軸數據,可以是列表、元組、NumPy數組等。
- y: y軸數據,可以是列表、元組、NumPy數組等。
- fmt: 折線圖的樣式和顏色。
- 例如,'ro-'表示紅色圓圈加短橫線,
- 'b–'表示藍色虛線。
- label:為折線圖添加一個標簽,可以在plt.legend()函數中使用該標簽(用于顯示圖例)。
- linewidth: 折線圖的寬度。
- color: 折線圖的顏色。
- marker: 折線圖的標記形狀,例如圓圈、叉號等。
- markeredgecolor: 標記的邊緣顏色。
- markerfacecolor: 標記的填充顏色。
- markevery: 標記的間隔,例如每隔10個數據點標記一次。
- plt.xticks(rotation=45):設置x軸刻度標簽的位置和顯示方式
4、數據預處理pre-processing
(1)將時間戳轉換為一個日期時間索引
elborn_df.set_index(pd.DatetimeIndex(elborn_df["time"]), inplace=True)
elborn_df.drop(["time"], axis=1, inplace=True)
(2)填充所有缺失的值
不填充的話后續fit模型的時候會出現loss全部為NAN的情況
elborn_df.down.fillna(elborn_df.down.mean(), inplace=True)
print(elborn_df.isna().sum())
(3)將時間序列數據轉換成監督學習數據
在訓練監督學習(深度學習)模型前,要把time series數據轉化成samples的形式
那什么是sample?有一個輸入組件 X X X和一個輸出組件 y y y
深度學習模型就是一個映射函數: y = f ( X ) y=f(X) y=f(X)
對于一個單變量的one-step預測:輸入組件就是前一個時間步的滯后數據,輸出組件就是當前時間步的數據,如下:
X, y
[1, 2, 3], [4]
[2, 3, 4], [5]
[3, 4, 5], [6]
…
這里就是手動轉換啦,之前寫過使用TimeseriesGenerator自動轉換的方法,看看對比
手動轉換
def series_to_supervised(data, window=3, lag=1, dropnan=True):cols, names = list(), list()# Input sequence (t-n, ... t-1)for i in range(window, 0, -1):cols.append(data.shift(i))names += [('%s(t-%d)' % (col, i)) for col in data.columns]# Current timestep (t=0)cols.append(data)names += [('%s(t)' % (col)) for col in data.columns]# Target timestep (t=lag)cols.append(data.shift(-lag))names += [('%s(t+%d)' % (col, lag)) for col in data.columns]# Put it all togetheragg = pd.concat(cols, axis=1)agg.columns = namesreturn agg
window =29
lag = 10
elborn_df_supervised = series_to_supervised(elborn_df, window, lag)
(4)數據集劃分(split)為訓練集和驗證集
-
訓練集和測試集的區別
- 使用驗證集是為了快速調參,也就是用驗證集選擇超參數(網絡層數,網絡節點數,迭代次數,學習率這些)。另外用驗證集還可以監控模型是否異常(過擬合啦什么的),然后決定是不是要提前停止訓練。
- 驗證集的關鍵在于選擇超參數,我們手動調參是為了讓模型在驗證集上的表現越來越好,如果把測試集作為驗證集,調參去擬合測試集,就有點像作弊了。
- 而測試集既不參與參數的學習過程,也不參與參數的選擇過程,僅僅用于模型評價。
-
訓練集在建模過程中會被大量經常使用,驗證集用于對模型少量偶爾的調整,而測試集只作為最終模型的評價出現,因此訓練集,驗證集和測試集所需的數據量也是不一致的,在數據量不是特別大的情況下一般遵循6:2:2的劃分比例
-
為了使模型“訓練”效果能合理泛化至“測試”效果,從而推廣應用至現實世界中,因此一般要求訓練集,驗證集和測試集數據分布近似。但需要注意,三個數據集所用數據是不同的。
from sklearn.model_selection import train_test_split
label_name = 'down(t+%d)' % (lag)
label = elborn_df_supervised[label_name]
elborn_df_supervised = elborn_df_supervised.drop(label_name, axis=1)
X_train, X_valid, Y_train, Y_valid = train_test_split(elborn_df_supervised, label, test_size=0.4, random_state=0)
print('Train set shape', X_train.shape)
print('Validation set shape', X_valid.shape)
4、創建MLP模型
(1)設置超參數
epochs = 40
batch = 256
lr = 0.0003
adam = optimizers.Adam(lr)
(2)創建模型(keras)
model_mlp = Sequential()
model_mlp.add(Dense(100, activation='relu', input_dim=X_train.shape[1]))
model_mlp.add(Dense(1))
model_mlp.compile(loss='mse', optimizer=adam)
model_mlp.summary()
(3)訓練模型
mlp_hitstory = model_mlp.fit(X_train.values, Y_train, epochs=epochs, batch_size=batch, validation_data=(X_valid.values, Y_valid), verbose=2)
(4)畫隨epoch變化的loss圖
# 畫圖,橫坐標是epochs,縱坐標是loss,分別畫出train loss和validation loss
import matplotlib.pyplot as pltplt.plot(mlp_hitstory.history['loss'])
plt.plot(mlp_hitstory.history['val_loss'])
plt.title('model loss')
plt.ylabel('loss')
plt.xlabel('epoch')
plt.legend(['train', 'validation'], loc='upper left')
plt.show()
(5)計算預測值和實際值之間的均方誤差
from sklearn.metrics import mean_squared_error
mlp_train_pred = model_mlp.predict(X_train.values)
mlp_valid_pred = model_mlp.predict(X_valid.values)
print('Train rmse:', np.sqrt(mean_squared_error(Y_train, mlp_train_pred)))
print('Validation rmse:', np.sqrt(mean_squared_error(Y_valid, mlp_valid_pred)))
接寫到這里吧,今天效率太低了,明天繼續