tf_dome1.py
9.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
import tensorflow as tf
from sklearn.model_selection import train_test_split
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
import psycopg2
import pandas as pd
"""
一个简单的文本分类模型,用于预测商品是否与圣诞节相关
文本: ASIN、站点、标题、描述、卖点
子文本(买家评论):
图片/视频:ASIN、站点、首图、子图、A+、视频
大数据模型训练流程
1.处理大量数据,使用 hadoop、spark 等计算框架来处理、分析、挖掘这些数据。 涉及到:存储、清洗、分析、等方面
2.下面的案例更侧重于机器学习和深度学习的应用,以及使用TensorFlow和Keras构建文本分类模型
"""
#用于判断产品是否与圣诞相关。
def is_christmas_product(row):
keywords = ['christmas', 'christmas tree', 'christmas gifts', 'christmas decorations', 'christmas celebration',
'santa claus', 'winter holiday', 'christmas shopping', 'holiday party']
title = str(row['title']).lower() if pd.notna(row['title']) else ''
describe = str(row['describe']).lower() if pd.notna(row['describe']) else ''
product_description = str(row['product_description']).lower() if pd.notna(row['product_description']) else ''
return any((keyword in title or keyword in describe or keyword in product_description) for keyword in keywords)
#用于判断产品是否包含圣诞装饰相关关键词
def has_christmas_decorations(row):
keywords = ['decorations', 'ornaments', 'festive decor', 'holiday decor', 'christmas adornments']
return any(keyword in str(row['title']).lower() or keyword in str(row['describe']).lower() or keyword in str(row['product_description']).lower() for keyword in keywords)
# 定义判断条件的函数
def is_condition_met(row):
return 'keyword' in str(row['title']) and 'keyword' in str(row['product_description']) and 'keyword' in str(row['describe'])
# 连接 PostgreSQL 数据库
connection = psycopg2.connect(
host="192.168.10.223",
port="5432",
database="selection",
user="postgres",
password="fazAqRRVV9vDmwDNRNb593ht5TxYVrfTyHJSJ3BS"
)
# 从数据库读取数据
query = "select asin,title,product_description,describe from us_asin_detail_month_2023_12 where date_info ='2023-12' and spider_int = 1 and product_description !='' limit 1000"
df = pd.read_sql(query, connection)
# 关闭数据库连接
connection.close()
# 过滤掉空数据:通过筛选,保留 title、product_description 或 describe 字段中不为空的数据。
df = df[(df['title'].notna() & (df['title'] != '')) |
(df['product_description'].notna() & (df['product_description'] != '')) |
(df['describe'].notna() & (df['describe'] != ''))]
# 将满足条件的数据标记为 True
df['meets_condition'] = df.apply(is_condition_met, axis=1)
#添加新的特征列
df['is_christmas'] = df.apply(is_christmas_product, axis=1)
#划分训练集和测试集
train_df, test_df = train_test_split(df, test_size=0.2, random_state=42)
train_df['is_christmas'] = train_df.apply(is_christmas_product, axis=1).fillna(False)
# 在数据集中添加特征列
df['has_christmas_decorations'] = df.apply(has_christmas_decorations, axis=1)
# 使用训练集的一部分作为测试集
test_df = train_df.sample(frac=1, random_state=42)
test_df['is_christmas'] = test_df.apply(lambda row: is_christmas_product(row) if pd.notna(row['title']) or pd.notna(row['product_description']) or pd.notna(row['describe']) else False, axis=1)
# 合并文本字段
train_texts = train_df['describe'] + ' ' + train_df['title'] + ' ' + train_df['product_description']
test_texts = test_df['describe'] + ' ' + test_df['title'] + ' ' + test_df['product_description']
train_texts = train_texts.fillna('') # 将 NaN 值替换为空字符串
train_texts = train_texts.dropna()
test_texts = test_texts.astype(str)
# 使用Tokenizer构建词汇表
tokenizer = Tokenizer()
tokenizer.fit_on_texts(train_texts)
# 将文本序列转化为数字序列
train_sequences = tokenizer.texts_to_sequences(train_texts)
test_sequences = tokenizer.texts_to_sequences(test_texts)
# 填充序列保证长度一致
max_length = 150 # 你可以根据实际情况调整
train_padded = pad_sequences(train_sequences, maxlen=max_length, padding='post', truncating='post')
test_padded = pad_sequences(test_sequences, maxlen=max_length, padding='post', truncating='post')
#构建模型: 使用TensorFlow和Keras构建一个简单的深度学习文本分类模型
#包括Embedding层:是一种用于将高纬度数据(如文本、图片、音频)映射到低维度空间的机器学习方法。这种模型通过创建一个由实数构成的多维向量来表示输入数据,使得每个数据点都对应于一个连续数值空间中的一个具体位置。
# Embedding向量可以用于捕捉数据的结构化信息,尤其是在自然语言处理(NLP)和计算机视觉、等领域,它们帮助算法理解不同类型数据之间的相互关系
# GlobalAveragePooling1D 层:
# Dense层:是一个全连接层
model = tf.keras.Sequential([
#input_dim: 表示词汇表中的单词数目,加 1 是因为词汇表的索引是从 1 开始的,而不是从 0。
#output_dim:表示嵌入向量的维度,即每个单词将被映射为一个具有维度的向量
#input_length:表示输入序列的长度。指定的文本序列的最大长度
tf.keras.layers.Embedding(input_dim=len(tokenizer.word_index) + 1, output_dim=100, input_length=max_length),
#GlobalAveragePooling1D:用于将每个时间步的输出平均汇聚成一个固定长度的向量。在文本分类任务中,它通常用于处理变长序列,将不同长度的文本转换为固定长度的表示
tf.keras.layers.GlobalAveragePooling1D(),
#tf.keras.layers.Dense(128, activation='relu'), # 调整神经元数量和激活函数
#是一个全连接层,其中包含 128 个神经元,并使用双曲正切(tanh)作为激活函数
tf.keras.layers.Dense(128, activation='tanh'),
#tf.keras.layers.Dense(128, activation='relu', kernel_regularizer=regularizers.l2(0.01)), # 添加 L2 正则化
# Dense:这是神经网络的输出层,包含一个神经元。激活函数选择了 sigmoid。在二分类问题中,sigmoid 函数常用于输出层,因为它将输出值映射到 0 到 1 之间,可以看作是概率值,表示样本属于正类别的概率。
#这两层分开定义的目的是为了能够更灵活地定制神经网络的架构。如果需要对中间层进行调整,添加更多的隐藏层或者更改神经元数量,可以在这两层之间插入新的全连接层。最后一层的选择和设置是根据问题类型和模型的输出进行调整的
# 因为该案例:是一个二分类问题,因此使用了 sigmoid 激活函数。
tf.keras.layers.Dense(1, activation='sigmoid')
])
# 调整学习率
optimizer = tf.keras.optimizers.Adam(learning_rate=0.001)
# 编译模型: optimizer优化器, adam是一种常用的优化算法, 该算法就是综合其他优化算法的优点
#loss(损失函数): 用于衡量模型在训练过程中预测值与真实值之间的差异。在二分类问题中,一般使用 'binary_crossentropy' 作为损失函数。对于多分类问题,可能会选择 'categorical_crossentropy'。
#metrics(评估指标): 用于在训练和评估过程中监控模型性能的指标。在这里,我们使用 'accuracy',表示模型在训练和评估过程中将准确率作为一个监测指标。
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# 训练模型
model.fit(train_padded, train_df['is_christmas'], epochs=5, validation_data=(test_padded, test_df['is_christmas']))
#保存模型结构和权重
model.save('text_classification_model.h5')
#使用模型进行预测
predictions = model.predict(test_padded)
#设置阈值
threshold = 0.5
# 存储匹配的 ASIN 和字段信息
matching_asins_info = []
# 遍历测试集中的每个样本
for i in range(len(test_df)):
# 获取测试样本的信息
asin = test_df["asin"].iloc[i]
is_christmas_label = test_df["is_christmas"].iloc[i]
# 如果模型预测为与圣诞节相关
if predictions[i][0] > threshold:
print('asin:',asin)
# 记录匹配的 ASIN 和字段信息
matching_asins_info.append({
'ASIN': asin,
'IsChristmasLabel': is_christmas_label,
'PredictedLabel': 1, # 1 表示预测为相关
'Probabilities': predictions[i],
'MatchingFields': {
'Title': test_df['title'].iloc[i],
'Description': test_df['describe'].iloc[i],
'ProductDescription': test_df['product_description'].iloc[i]
}
})
output_file_path = 'E:/BaiduNetdiskDownload/选品大数据/推荐系统/matching_asins_info.txt'
with open(output_file_path, 'w', encoding='utf-8') as output_file:
for info in matching_asins_info:
output_file.write(f"ASIN: {info['ASIN']}\n")
output_file.write(f"Is Christmas Label: {info['IsChristmasLabel']}\n")
matched_field = 'Title' # 默认为 Title
if info['MatchingFields']['Description']:
matched_field = 'Description'
elif info['MatchingFields']['ProductDescription']:
matched_field = 'Product Description'
output_file.write(f"Matched Field: {matched_field}\n")
output_file.write(f"Matched Content: {info['MatchingFields'][matched_field]}\n")
output_file.write('-' * 50 + '\n')