plotly
设置x/y轴名称
yaxis_title=‘金额(元)’,xaxis_title=‘日期’
fig = px.line(df_grouped, x="Order_time", y="Money", title='日销图')
fig.update_layout(yaxis_title='金额(元)',xaxis_title='日期', xaxis_tickformat='%Y-%m-%d',yaxis_tickformat = '0.2f')
fig.show()
设置x/y轴范围
fig.update_layout(yaxis_title='loss',xaxis_title='epochs',yaxis_tickformat = '0.3f',
#全闭区间0-61
xaxis_range=[0,61]
)
调整日期格式
xaxis_tickformat='%Y-%m-%d
# 画图展示每日销量
fig = px.line(df_grouped, x="Order_time", y="Money", title='日销图')
fig.update_layout(yaxis_title='金额(元)',xaxis_title='日期', xaxis_tickformat='%Y-%m-%d',yaxis_tickformat = '0.2f')
fig.show()
设置数值保留小数
yaxis_tickformat = ‘0.2f’
# 画图展示每日销量
fig = px.line(df_grouped, x="Order_time", y="Money", title='日销图')
fig.update_layout(yaxis_title='金额(元)',xaxis_title='日期', xaxis_tickformat='%Y-%m-%d',yaxis_tickformat = '0.2f')
fig.show()
基础折线图
import plotly.express as px
# 画图展示每日销量
fig = px.line(df_final, x="Order_time", y="Money", title='日销图',hover_data=['count'])
fig.update_layout(yaxis_title='金额(元)',xaxis_title='日期', xaxis_tickformat='%Y-%m-%d',yaxis_tickformat = '0.2f')
fig.show()
去除网格
fig = go.Figure()
fig.update_layout(yaxis_title='loss',xaxis_title='epochs',yaxis_tickformat = '0.2f',xaxis_showgrid=False, yaxis_showgrid=False)
设置背景颜色
fig.update_layout(yaxis_title='loss',xaxis_title='epochs',yaxis_tickformat = '0.2f',xaxis_showgrid=False, yaxis_showgrid=False,paper_bgcolor='white',plot_bgcolor='rgb(243, 243, 243)')
一图多表
https://plotly.com/python/reference/scatter/
示例1
import plotly.graph_objects as go
fig = go.Figure()
fig.update_layout(yaxis_title='金额(元)',xaxis_title='日期', xaxis_tickformat='%Y-%m-%d',yaxis_tickformat = '0.2f')
fig.add_trace(go.Scatter(
x=df_final_no_index['Order_time'],
y=df_final_no_index['Money'],
name = 'Real Price',
# 设定图像的形式
mode = 'lines',
# 在marker中设置图像的颜色
# marker = dict(
# color = 'skyblue',
# size =5,
# symbol = 'circle/square/x'
# )
))
fig.add_trace(go.Scatter(
x=df_final_no_index['Order_time'][-(test_split-30):],
y=pred,
name = 'Predicted Price',
mode = 'lines'
))
fig.show()
示例2:
import plotly.graph_objects as go
fig = go.Figure()
fig.update_layout(yaxis_title='充值分数',xaxis_title='消费分数',yaxis_tickformat = '0.2f',title = '分类结果')
fig.add_trace(go.Scatter(
x=total_data['consume_score'],
y=total_data['recharge_score'],
name = '用户分数',
# 设定图像的形式
mode = 'markers',
marker = dict(
color = total_data['prediction'],
colorscale = 'Viridis'
)
))
fig.add_trace(go.Scatter(
x=centers['x'],
y=centers['y'],
name = '质心',
mode = 'markers',
marker = dict(
size = 10,
symbol = 'x'
)
))
fig.show()
显示额外数据
hover_data
fig = px.line(df_final, x="Order_time", y="Money", title='日销图',hover_data=['count'])
pandas
索引
删除索引
df_final.reset_index(drop=False,inplace=True)
添加索引
df_final.set_index('Order_time',inplace=True)
分组及聚合操作
求和
# 按照日期分组并求和,会对能够计算的列进行求和 numeric_only防止警告
df_grouped_sum = df_clear.groupby(by=df_clear['Order_time'].dt.date).sum(numeric_only = True)
计数
# 按照日期分组并计数 会对所有列进行计数
df_grouped_count = df_clear.groupby(by=df_clear['Order_time'].dt.date).count()
ndarray转dataframe
array_1 = np.array([1, 2, 3, 4])
df_1 = pd.DataFrame(array_1, columns=["Column 1"])
concat根据索引合并
import numpy as np
import pandas as pd
# Create two ndarrays
array_1 = np.array([1, 2, 3, 4])
array_2 = np.array([5, 6, 7, 8])
# Convert ndarrays to DataFrames
df_1 = pd.DataFrame(array_1, columns=["Column 1"])
df_2 = pd.DataFrame(array_2, columns=["Column 2"])
# Concatenate DataFrames along columns (axis=1)
df_merged = pd.concat([df_1, df_2], axis=1)
print(df_merged)
修改列类型
older['Order_time'] = older['Order_time'].astype('str')
按列赋值
# 其中pred是ndarray类型也可以 df类型就指定列即可
df_test_predict['Money'] = pred
merge根据字段合并
In [33]: left = pd.DataFrame(
....: {
....: "key": ["K0", "K1", "K2", "K3"],
....: "A": ["A0", "A1", "A2", "A3"],
....: "B": ["B0", "B1", "B2", "B3"],
....: }
....: )
....:
In [34]: right = pd.DataFrame(
....: {
....: "key": ["K0", "K1", "K2", "K3"],
....: "C": ["C0", "C1", "C2", "C3"],
....: "D": ["D0", "D1", "D2", "D3"],
....: }
....: )
....:
In [35]: result = pd.merge(left, right, on="key")
读取文件
excel
df=pd.read_excel("data/Data003_SelfOperate.xlsx",parse_dates=["Order_time"])
查看数据范围
df.describe().loc[['min', 'max']]
去除时分秒
df["Order_time"] = df["Order_time"].dt.date
过滤数据
# 过滤金额范围
df = df[(df['Money']>=5)&(df['Money']<=10000)]
# 过滤时间段为[2020-1-1:]
df['Order_time'] = pd.to_datetime(df['Order_time'])
df = df[(df['Order_time'] >= pd.Timestamp('2020-01-01'))]
选择多列
df_clear = df[['Order_time','Money']]
插入新列
df.insert(loc=2, column='c', value=3) # 在最后一列后,插入值全为3的c列
保留小数
df_merged['predicted_price'] = df_merged['predicted_price'].apply(lambda x: round(x, 2))
生成时间序列
pd_day = pd.date_range('20220708',periods=30,freq='D')
eg:
需求:在已有日期df_for_predict后加入新增的时间序列
# 创建空的数组
# empty = np.zeros((future_span,1))
# ndarray 转 pd
# future = pd.DataFrame(empty,columns = ['Money'])
# 生成时间序列
pd_day = pd.date_range('20220708',periods=future_span,freq='D')
# ndarray 转 pd
older = pd.DataFrame(pd_day,columns=['Order_time'])
# 时间类型转换成字符串
older['Order_time'] = older['Order_time'].astype('str')
# older.set_index('Order_time',inplace=True)
# 插入money列
older.insert(loc=1, column='Money', value=0)
# 按行连接两个表
df_for_predict = pd.concat([df_for_predict,older])
df_for_predict.set_index('Order_time',inplace=True)
df_for_predict.tail(20)
machine learning
激活函数 activation
作用
一个没有激活函数的神经网络将只不过是一个线性回归模型(Linear regression Model)罢了,它功率有限,并且大多数情况下执行得并不好。
将模型中一个节点的输入信号转换成一个输出信号,这使得模型可以学习和模拟其他复杂类型的数据。
比如逻辑回归中 z = w x + b z=wx+b z=wx+b
而激活函数的输入为z
:
f
(
z
)
=
s
i
g
m
o
i
d
f
u
n
c
t
i
o
n
=
1
1
+
e
−
z
f(z)=sigmoid function=\frac{1}{1+e^{-z}}
f(z)=sigmoidfunction=1+e−z1
如何选择
- 在深度学习的隐藏层中,一般使用
relu
- 在输出层,取决于
标签值y
- y=0/1 ——
sigmoid
- y可正可负——
linear
- y$>=$0——
relu
- y=0/1 ——
loss函数和cost函数
loss:用来计算预测值与真实值之间的差异,是单个样本的值
比如逻辑回归中使用的交叉熵函数
:
以及非逻辑回归的均方差函数
:
cost:整个训练集上loss的平均值
模型的最终目的就是尽可能使cost函数最小化
loss值和val_loss值
loss和val loss 的区别:
loss:训练集整体的损失值。
val loss:验证集(测试集)整体的损失值。
loss和val loss,两者之间的关系:
当loss下降,val_loss下降:训练正常,最好情况。
- 当loss下降,val_loss稳定:网络过拟合化。这时候可以添加Dropout和Max pooling。
- 当loss稳定,val_loss下降:说明数据集有严重问题,可以查看标签文件是否有注释错误,或者是数据集质量太差。建议重新选择。
- 当loss稳定,val_loss稳定:学习过程遇到瓶颈,需要减小学习率(自适应网络效果不大)或batch数量。
- 当loss上升,val_loss上升:网络结构设计问题,训练超参数设置不当,数据集需要清洗等问题,最差情况
梯度下降
梯度下降法(alpha 为学习率):
学习率
影响的是梯度下降的过程
过小:导致梯度下降过程缓慢
过大:可能永远达不到梯度的最小值
过拟合
解决方法
- 收集更多数据
- 不要使用太多特征
- 正则化
正则化
核心:尽可能地减小w(权重),与直接删除某些特征值的做法相比,他更加温和
原理
目的是最小化代价函数J(w,b)
- λ = 0 \lambda=0 λ=0:相当于没有正则化
- λ 过大 \lambda过大 λ过大:要使得J尽可能小,那么w就尽可能小,因为他前面的系数 λ \lambda λ很大,导致w近似为0,出现欠拟合
所以 λ \lambda λ需要有合理的取值范围,通常为[1,10]
tensorflow
一般步骤
以逻辑回归为例,使用tf构造神经网络的步骤和机器学习中的步骤一样
- 构造模型
- 选取loss函数
- 评估
举例
- 定义模型
- loss and cost
- fit
模型构造及loss观测
例:
model = Sequential()
model.add(LSTM(50, return_sequences=True,input_shape = (span,1)))
# model.add(LSTM(50))
model.add(Dropout(0.2))
model.add(Dense(1))
model.compile(loss = "mse",optimizer= "adam")
train_history =model.fit(trainX, trainY, epochs= 100, batch_size=50, validation_data=(testX, testY), verbose=1, shuffle=False)
# 画图
plt.figure()
plt.plot(train_history.history["loss"], label = "loss")
plt.plot(train_history.history["val_loss"], label = "val_loss")
plt.legend()
plt.show()
查看模型详情
model.summary()
sklearn
标准化处理
from sklearn.preprocessing import StandardScaler
# 标准化处理
scaler = StandardScaler()
df_for_training_scaled=scaler.fit_transform(df_for_training)
# 反标准化
scaler.inverse_transform(df_for_training)
归一化处理MinMaxScaler
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler(feature_range=(0,1))
df_for_training_scaled=scaler.fit_transform(df_for_training)
df_for_testing_scaled=scaler.transform(df_for_testing)
df_for_training_scaled
两个特征值 结果为:
GridSearchCV
参考博客
强烈推荐视频
例子
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM
from tensorflow.keras.layers import Dense, Dropout
from keras.wrappers.scikit_learn import KerasRegressor
from sklearn.model_selection import GridSearchCV
def build_model(optimizer):
grid_model = Sequential()
# 层数过少导致的问题就是预测的曲线会比较平滑
grid_model.add(LSTM(60,return_sequences=True,input_shape=(span,1)))
grid_model.add(LSTM(60))
# grid_model.add(Dense(64,activation="relu"))
# Dropout设置防止过拟合的参数,相当于正则化参数
grid_model.add(Dropout(0.2))
grid_model.add(Dense(1))
# 用均方差(mse)作为loss函数
grid_model.compile(loss = 'mse',optimizer = optimizer)
return grid_model
# verbose=1设置打印的等级
grid_model = KerasRegressor(build_fn=build_model,verbose=1,validation_data=(testX,testY))
parameters = {'batch_size' : [5],
# epochs为迭代次数
'epochs' : [20],
'optimizer' : ['adam'] }
grid_search = GridSearchCV(estimator = grid_model,
param_grid = parameters,
# cv默认值是5折交叉验证
)
训练集样本数量是675
每一轮的训练次数
=
108
=
675
×
(
c
v
−
1
=
4
c
v
=
5
)
b
a
t
c
h
_
s
i
z
e
=
5
每一轮的训练次数=108=\frac{675\times(\frac{cv-1=4}{cv=5})}{batch\_size=5}
每一轮的训练次数=108=batch_size=5675×(cv=5cv−1=4)
CV交叉验证参数
会将训练集
分成CV份,其中
C
V
−
1
C
V
\frac{CV-1}{CV}
CVCV−1份用来训练
,
1
C
V
\frac{1}{CV}
CV1用来验证
(注意不是测试!!!
)
eg:10折交叉验证
batch_size
会将CV之后的训练集在进行划分,每一份batch_size
个
分数
print('Best: {} using {}'.format(grid_search.best_score_, grid_search.best_params_))
最终的分数是在CV交叉验证时
针对验证集
的拟合情况
所以GridCV中分数高,只代表它在交叉验证环节的分数高,针对的是验证集
,但是如果将模型应用到测试集
上时,结果并不一定是最好的
batch_size和epoch
一般来说,在合理的范围之内,越大的 batch size 使下降方向越准确,震荡越小
batch取太大会陷入局部最小值,
batch取太小loss会抖动厉害,因为过度关注了每一个数据(包括噪音),所以容易导致过拟合而不是欠拟合
batch_size
:一次训练所选取的样本数; batch_size的大小影响内存的使用情况,同时也影响模型的优化程度和速度。
mongoDB
python + mongoDB
import json
# 连接MongoDB数据库
from pymongo import MongoClient
#连接Mongodb数据库
conn = MongoClient('192.168.10.1',27017)
def df2bson(df):
"""DataFrame类型转化为Bson类型"""
data = json.loads(df.T.to_json()).values()
return data
# df_data为要存储的数据 table为数据库中表的名称
def saveMongo(df_data,table):
# userdata为数据库名称
db = conn["userdata"]
table = db[table]
bson_data = df2bson(df_data)
result = table.insert_many(bson_data)
# 将数据保存到mongodb中
saveMongo(raise_df,"user_raise")
时间戳转日期
https://blog.csdn.net/qq_45366447/article/details/128617142
db.daily_consume.aggregate([
{
$project: {
"Order_time_formatted": {
$dateToString: {
format: '%Y-%m-%d',
date: {
$add: [
ISODate('1970-01-01T00:00:00.000Z'),
'$Order_time',
28800000
]
}
}
},
"_id": "$_id"
}
}
]).forEach(function(doc) {
db.daily_consume.update({
"_id": doc._id
}, {
"$set": {
"Order_time_formatted": doc.Order_time_formatted
}
});
});
在终端中输入上述命令,可以看到已经成功转变过来
regate([
{
$project: {
“Order_time_formatted”: {
$dateToString: {
format: ‘%Y-%m-%d’,
date: {
a
d
d
:
[
I
S
O
D
a
t
e
(
′
1970
−
01
−
01
T
00
:
00
:
00.000
Z
′
)
,
′
add: [ ISODate('1970-01-01T00:00:00.000Z'), '
add:[ISODate(′1970−01−01T00:00:00.000Z′),′Order_time’,
28800000
]
}
}
},
“_id”: “KaTeX parse error: Expected 'EOF', got '}' at position 14: _id" }̲ } ]).forEa…set”: {
“Order_time_formatted”: doc.Order_time_formatted
}
});
});
在终端中输入上述命令,可以看到已经成功转变过来
[外链图片转存中...(img-mUQrzypv-1696143131169)]