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')