当前位置: 首页 > news >正文

网站新闻详细页面设计一个网站通常包含多个网页

网站新闻详细页面设计,一个网站通常包含多个网页,湖南建设人力资源网和报考平台,个人网站建设实验心得电影评论的情感分析 案例背景 很多同学对电影系列的数据都比较喜欢#xff0c;那我就补充一下这个最经典的文本分类数据集#xff0c;电影情感评论分析。用神经网络做。对国外的英文评论文本进行分类#xff0c;看是正面还是负面情感。 数据集介绍 数据集#xff1a;IMDb…电影评论的情感分析 案例背景 很多同学对电影系列的数据都比较喜欢那我就补充一下这个最经典的文本分类数据集电影情感评论分析。用神经网络做。对国外的英文评论文本进行分类看是正面还是负面情感。 数据集介绍 数据集IMDb网站的电影评论数据集. 这个数据集包含评论文本和标签标签表示该评论是“正面的”(positive)还是“负面的”(negative). 数据集包括两个独立文件夹一个是训练数据train, 另一个是测试数据test. 每个文件夹又都有两个子文件夹一个叫做pos, 另一个叫做neg。pos文件夹包含所有正面的评论, 每条评论都是一个单独的文本文件, neg文件夹与之类似。 说实话搞这么多文件夹和这么多txt文件看着麻烦我还是一样自己清洗和整理后直接用excel装起来了如下 两个excel文件一个训练集一个测试集每个里面有25000条评论其中又分为12500条正面和12500条负面是一个很平衡的样本。 需要这个数据的全部代码的同学可以参考电影数据 代码实现 预处理 导入包 import pandas as pd import numpy as np import matplotlib.pyplot as plt import seaborn as sns plt.rcParams[font.sans-serif] [KaiTi] #指定默认字体 SimHei黑体 plt.rcParams[axes.unicode_minus] False #解决保存图像是负号 读取数据合并展示前五行 df_trainpd.read_csv(train.csv) df_testpd.read_csv(test.csv) dfpd.concat([df_train,df_test]).reset_index(dropTrue) df.head() 可以看到里面有一些“b”这种二进制留下的解码前缀我们需要简单处理一下 import re def preprocess_text(s):# 解码字节字符串if isinstance(s, bytes):s s.decode(utf-8)# 替换转义字符s re.sub(r\\n, , s)s re.sub(r\\, , s)return s.strip().replace(b,).replace(b,) #应用预处理 df[text] df[text].apply(preprocess_text) df.head() 查看种类分布 df[label].value_counts().plot(kindbar) 0是负面文本评论1是正面可以看到很均衡。 词向量转化 英文词汇自带空格所以不需要向中文一样的去分词直接构建词表然后词向量化 from os import listdir from keras.preprocessing import sequence from keras.preprocessing.text import Tokenizer from tensorflow.keras.utils import to_categorical from sklearn.model_selection import train_test_split # 将文件分割成单字, 建立词索引字典 tok Tokenizer(num_words10000) tok.fit_on_texts(df[text].to_numpy()) print(样本数 : , tok.document_count) 查看词表前10 的词汇 print({k: tok.word_index[k] for k in list(tok.word_index)[:10]}) 将其变为数组然后查看其长度分布   X tok.texts_to_sequences(df[text].to_numpy()) #查看x的长度的分布 v_cpd.Series([len(i) for i in X]).value_counts() print(v_c[v_c150]) v_c[v_c150].plot(kindbar,figsize(12,5)) 可以看到大部分评论长度都在120左右我们选择将X统一到长度为200多的去掉少的用0补起来。 # 将序列数据填充成相同长度 X sequence.pad_sequences(X, maxlen200) Ydf[label].to_numpy() print(X.shape: , X.shape) print(Y.shape: , Y.shape)然后我们再将训练集和测试集分开前面是直接拼接的那这里我们直接顺序分割就行。 X_train, X_test, Y_train, Y_test train_test_split(X, Y, test_size0.5, shuffleFalse) X_train.shape,X_test.shape,Y_train.shape, Y_test.shape y进行独立热编码 Y_test_originalY_test.copy() Y_train to_categorical(Y_train) Y_test to_categorical(Y_test) Y to_categorical(Y) 查看X和y的其中三个 print(X_train[100:103]) print(Y_test[:3]) Y_test_original[:3] 数据没什么问题我们可以构建神经网络进行训练了。 构建神经网络 导入包自定义Transformer层和位置编码层。 from tensorflow.keras import layers import tensorflow as tf from tensorflow import keras class TransformerEncoder(layers.Layer):def __init__(self, embed_dim, dense_dim, num_heads, **kwargs):super().__init__(**kwargs)self.embed_dim embed_dimself.dense_dim dense_dimself.num_heads num_headsself.attention layers.MultiHeadAttention(num_headsnum_heads, key_dimembed_dim)self.dense_proj keras.Sequential([layers.Dense(dense_dim, activationrelu),layers.Dense(embed_dim),] )self.layernorm_1 layers.LayerNormalization()self.layernorm_2 layers.LayerNormalization()def call(self, inputs, maskNone):if mask is not None:mask mask[:, tf.newaxis, :]attention_output self.attention(inputs, inputs, attention_maskmask)proj_input self.layernorm_1(inputs attention_output)proj_output self.dense_proj(proj_input)return self.layernorm_2(proj_input proj_output)def get_config(self):config super().get_config()config.update({embed_dim: self.embed_dim,num_heads: self.num_heads,dense_dim: self.dense_dim, })return config class PositionalEmbedding(layers.Layer):def __init__(self, sequence_length, input_dim, output_dim, **kwargs):super().__init__(**kwargs)self.token_embeddings layers.Embedding(input_diminput_dim, output_dimoutput_dim)self.position_embeddings layers.Embedding(input_dimsequence_length, output_dimoutput_dim)self.sequence_length sequence_lengthself.input_dim input_dimself.output_dim output_dimdef call(self, inputs):length tf.shape(inputs)[-1]positions tf.range(start0, limitlength, delta1)embedded_tokens self.token_embeddings(inputs)embedded_positions self.position_embeddings(positions)return embedded_tokens embedded_positionsdef compute_mask(self, inputs, maskNone):return tf.math.not_equal(inputs, 0)def get_config(self):config super().get_config()config.update({output_dim: self.output_dim,sequence_length: self.sequence_length,input_dim: self.input_dim,})return config 导入层和定义一些参数 from keras.preprocessing import sequence from keras.models import Sequential,Model from keras.layers import Dense,Input, Dropout, Embedding, Flatten,MaxPooling1D,Conv1D,SimpleRNN,LSTM,GRU,Multiply,GlobalMaxPooling1D from keras.layers import Bidirectional,Activation,BatchNormalization,GlobalAveragePooling1D,MultiHeadAttention from keras.callbacks import EarlyStopping from keras.layers.merge import concatenate np.random.seed(0) # 指定随机数种子 #单词索引的最大个数10000单句话最大长度200 top_words10000 max_words200 #序列长度 embed_dim128 #嵌入维度 num_labels2 #2分类 构建模型构建了14种模型 def build_model(top_wordstop_words,max_wordsmax_words,num_labelsnum_labels,modeLSTM,hidden_dim[64]):if modeRNN:model Sequential()model.add(Embedding(top_words, input_lengthmax_words, output_dimembed_dim, mask_zeroTrue))model.add(Dropout(0.25))model.add(SimpleRNN(hidden_dim[0])) model.add(Dropout(0.25)) model.add(Dense(num_labels, activationsoftmax))elif modeMLP:model Sequential()model.add(Embedding(top_words, input_lengthmax_words, output_dimembed_dim))#, mask_zeroTruemodel.add(Flatten())model.add(Dropout(0.25))model.add(Dense(hidden_dim[0])) model.add(Dropout(0.25)) model.add(Dense(num_labels, activationsoftmax))elif modeLSTM:model Sequential()model.add(Embedding(top_words, input_lengthmax_words, output_dimembed_dim))model.add(Dropout(0.25))model.add(LSTM(hidden_dim[0]))model.add(Dropout(0.25)) model.add(Dense(num_labels, activationsoftmax))elif modeGRU:model Sequential()model.add(Embedding(top_words, input_lengthmax_words, output_dimembed_dim))model.add(Dropout(0.25))model.add(GRU(hidden_dim[0]))model.add(Dropout(0.25)) model.add(Dense(num_labels, activationsoftmax))elif modeCNN: #一维卷积model Sequential()model.add(Embedding(top_words, input_lengthmax_words, output_dimembed_dim, mask_zeroTrue))model.add(Dropout(0.25))model.add(Conv1D(filters32, kernel_size3, paddingsame,activationrelu))model.add(MaxPooling1D(pool_size2))model.add(Flatten())model.add(Dense(hidden_dim[0], activationrelu))model.add(Dropout(0.25)) model.add(Dense(num_labels, activationsoftmax))elif modeCNNLSTM:model Sequential()model.add(Embedding(top_words, input_lengthmax_words, output_dimembed_dim))model.add(Dropout(0.25)) model.add(Conv1D(filters32, kernel_size3, paddingsame,activationrelu))model.add(MaxPooling1D(pool_size2))model.add(LSTM(hidden_dim[0]))model.add(Dropout(0.25)) model.add(Dense(num_labels, activationsoftmax))elif modeBiLSTM:model Sequential()model.add(Embedding(top_words, input_lengthmax_words, output_dimembed_dim))model.add(Bidirectional(LSTM(64)))model.add(Dense(hidden_dim[0], activationrelu))model.add(Dropout(0.25))model.add(Dense(num_labels, activationsoftmax))#下面的网络采用Funcional API实现elif modeTextCNN:inputs Input(nameinputs,shape[max_words,], dtypefloat64)## 词嵌入使用预训练的词向量layer Embedding(top_words, input_lengthmax_words, output_dimembed_dim)(inputs)## 词窗大小分别为3,4,5cnn1 Conv1D(32, 3, paddingsame, strides 1, activationrelu)(layer)cnn1 MaxPooling1D(pool_size2)(cnn1)cnn2 Conv1D(32, 4, paddingsame, strides 1, activationrelu)(layer)cnn2 MaxPooling1D(pool_size2)(cnn2)cnn3 Conv1D(32, 5, paddingsame, strides 1, activationrelu)(layer)cnn3 MaxPooling1D(pool_size2)(cnn3)# 合并三个模型的输出向量cnn concatenate([cnn1,cnn2,cnn3], axis-1)x Flatten()(cnn) x Dense(hidden_dim[0], activationrelu)(x)output Dense(num_labels, activationsoftmax)(x)model Model(inputsinputs, outputsoutput)elif modeAttention:inputs Input(nameinputs,shape[max_words,], dtypefloat64)x Embedding(top_words, input_lengthmax_words, output_dimembed_dim, mask_zeroTrue)(inputs)x MultiHeadAttention(1, key_dimembed_dim)(x, x,x)x GlobalAveragePooling1D()(x)x Dropout(0.2)(x) x Dense(32, activationrelu)(x)output Dense(num_labels, activationsoftmax)(x)model Model(inputs[inputs], outputsoutput) elif modeMultiHeadAttention:inputs Input(nameinputs,shape[max_words,], dtypefloat64)x Embedding(top_words, input_lengthmax_words, output_dimembed_dim, mask_zeroTrue)(inputs)x MultiHeadAttention(8, key_dimembed_dim)(x, x,x)x GlobalAveragePooling1D()(x)x Dropout(0.2)(x) x Dense(32, activationrelu)(x)output Dense(num_labels, activationsoftmax)(x)model Model(inputs[inputs], outputsoutput) elif modeAttentionBiLSTM:inputs Input(nameinputs,shape[max_words,], dtypefloat64)x Embedding(top_words, input_lengthmax_words, output_dimembed_dim)(inputs)x MultiHeadAttention(2, key_dimembed_dim)(x, x,x)x Bidirectional(LSTM(hidden_dim[0]))(x) x Dense(64, activationrelu)(x)x Dropout(0.2)(x)output Dense(num_labels, activationsoftmax)(x)model Model(inputsinputs, outputsoutput) elif modeBiGRUAttention:inputs Input(nameinputs,shape[max_words,], dtypefloat64)x Embedding(top_words, input_lengthmax_words, output_dimembed_dim)(inputs)x Bidirectional(GRU(32,return_sequencesTrue))(x)x MultiHeadAttention(2, key_dimembed_dim)(x,x,x)x Bidirectional(GRU(32))(x)x Dropout(0.2)(x)output Dense(num_labels, activationsoftmax)(x)model Model(inputs[inputs], outputsoutput) elif modeTransformer:inputs Input(nameinputs,shape[max_words,], dtypefloat64)x Embedding(top_words, input_lengthmax_words, output_dimembed_dim, mask_zeroTrue)(inputs)x TransformerEncoder(embed_dim, 32, 4)(x)x GlobalMaxPooling1D()(x)x Dropout(0.25)(x)outputs Dense(num_labels, activationsoftmax)(x)model Model(inputs, outputs)elif modePositionalEmbeddingTransformer:inputs Input(nameinputs,shape[max_words,], dtypefloat64)x PositionalEmbedding(sequence_lengthmax_words, input_dimtop_words, output_dimembed_dim)(inputs)x TransformerEncoder(embed_dim, 32, 4)(x)x GlobalMaxPooling1D()(x)x Dropout(0.5)(x)outputs Dense(num_labels, activationsoftmax)(x)model Model(inputs, outputs)model.compile(losscategorical_crossentropy, optimizeradam, metrics[accuracy])return model 这里构建了“[MLP, CNN, RNN, LSTM, GRU, CNNLSTM, BiLSTM, TextCNN, Attention, MultiHeadAttention, AttentionBiLSTM, BiGRUAttention, Transformer, PositionalEmbeddingTransformer]”   14种模型大家还可以任意组合自己想要的模型。 定义评价函数和画损失图函数 #定义损失和精度的图,和混淆矩阵指标等等 from sklearn.metrics import confusion_matrix from sklearn.metrics import classification_report from sklearn.metrics import cohen_kappa_score def plot_loss(history):# 显示训练和验证损失图表plt.subplots(1,2,figsize(10,3))plt.subplot(121)loss history.history[loss]epochs range(1, len(loss)1)val_loss history.history[val_loss]plt.plot(epochs, loss, bo, labelTraining Loss)plt.plot(epochs, val_loss, r, labelValidation Loss)plt.title(Training and Validation Loss)plt.xlabel(Epochs)plt.ylabel(Loss)plt.legend() plt.subplot(122)acc history.history[accuracy]val_acc history.history[val_accuracy]plt.plot(epochs, acc, b-, labelTraining Acc)plt.plot(epochs, val_acc, r--, labelValidation Acc)plt.title(Training and Validation Accuracy)plt.xlabel(Epochs)plt.ylabel(Accuracy)plt.legend()plt.tight_layout()plt.show() def plot_confusion_matrix(model,X_test,Y_test_original):#预测概率probmodel.predict(X_test) #预测类别prednp.argmax(prob,axis1)#数据透视表混淆矩阵predpd.Series(pred)Y_test_originalpd.Series(Y_test_original)table pd.crosstab(Y_test_original, pred, rownames[Actual], colnames[Predicted])#print(table)sns.heatmap(table,cmapBlues,fmt.20g, annotTrue)plt.tight_layout()plt.show()#计算混淆矩阵的各项指标print(classification_report(Y_test_original, pred))#科恩Kappa指标print(科恩Kappastr(cohen_kappa_score(Y_test_original, pred)))def evaluation(y_test, y_predict):accuracyclassification_report(y_test, y_predict,output_dictTrue)[accuracy]sclassification_report(y_test, y_predict,output_dictTrue)[weighted avg]precisions[precision]recalls[recall]f1_scores[f1-score]#kappacohen_kappa_score(y_test, y_predict)return accuracy,precision,recall,f1_score #, kappa 定义训练函数 #定义训练函数 df_evalpd.DataFrame(columns[Accuracy,Precision,Recall,F1_score]) def train_fuc(max_wordsmax_words,modeBiLSTMAttention,batch_size64,epochs10,hidden_dim[64],show_lossTrue,show_confusion_matrixTrue):#构建模型modelbuild_model(max_wordsmax_words,modemode,hidden_dimhidden_dim)print(model.summary())es EarlyStopping(patience3)historymodel.fit(X_train, Y_train,batch_sizebatch_size,epochsepochs,validation_split0.1, verbose1,callbacks[es])print(——————————-----------------——训练完毕—————-----------------------------———————)# 评估模型#loss, accuracy model.evaluate(X_test, Y_test) ; print(测试数据集的准确度 {:.4f}.format(accuracy))probmodel.predict(X_test) ; prednp.argmax(prob,axis1)scorelist(evaluation(Y_test_original, pred))df_eval.loc[mode,:]scoreif show_loss:plot_loss(history)if show_confusion_matrix:plot_confusion_matrix(modelmodel,X_testX_test,Y_test_originalY_test_original) 我首先命名了一个df_eval的数据框用来存放模型预测的效果的评价指标。我们采用准确率精确值召回率F1值四个分类问题常用的指标来进行评价。 我这个训练函数里面包括了很多东西可以打印模型的信息然后展示模型的训练对模型训练过程的训练集和验证集的损失变化都画了图然后对于预测结果的混淆矩阵和其热力图都进行了展示还储存了评价指标。   初始化参数 top_words10000 max_words200 batch_size64 epochs10 hidden_dim[64] show_confusion_matrixTrue show_lossTrue 上面构建这么多函数是方便下面进行训练的下面的训练代码就很简单了一行代码就全有。 train_fuc(modeMLP,batch_sizebatch_size,epochsepochs) 训练其他模型只需要改mode参数就行 train_fuc(modeCNN,batch_sizebatch_size,epochsepochs) 这里太多了就不一一展示了直接一起训练然后看看所有模型的效果对比 train_fuc(modeRNN,batch_sizebatch_size,epochs8) train_fuc(modeLSTM,epochsepochs) train_fuc(modeGRU,epochsepochs) train_fuc(modeCNNLSTM,epochsepochs) train_fuc(modeBiLSTM,epochsepochs) train_fuc(modeTextCNN,epochs3) train_fuc(modeAttention,epochs4) train_fuc(modeMultiHeadAttention,epochs3) train_fuc(modeAttentionBiLSTM,epochs8) train_fuc(modeBiGRUAttention,epochs4) train_fuc(modeTransformer,epochs3) train_fuc(modePositionalEmbeddingTransformer,batch_sizebatch_size,epochs3) 模型评价 df_eval.assign(sdf_eval.sum(axis1))#[s].idxmax() 可以看到这个数据集上TextCNN模型效果较为优良。 多层感知机 (MLP) 的表现在所有指标上都是相对均衡的。卷积神经网络 (CNN) 在精确度和F1分数上稍微高于其他指标。递归神经网络 (RNN) 在所有指标上的表现都不是很好尤其是在准确度和召回率上。长短期记忆网络 (LSTM) 在准确度和F1分数上表现良好。门控循环单元 (GRU) 在所有指标上的表现都很均衡是性能较好的模型之一。CNNLSTM 组合模型在准确度和F1分数上表现较好。双向LSTM (BiLSTM) 的表现和单向的LSTM类似但是在所有指标上略有下降。TextCNN 在精确度和F1分数上表现出色说明它在分类正确的同时也保持了较高的相关性。Attention 机制的加入提供了相对较高的精确度但在其他指标上的提升不是很显著。MultiHeadAttention 相比单一的Attention机制在准确度和召回率上略有下降。AttentionBiLSTM 的组合模型在所有指标上均有较好的表现尤其是在F1分数上这表明它在精确度和召回率之间取得了很好的平衡。BiGRUAttention 在所有指标上也显示出良好的性能尤其是在准确度和F1分数上这表明它有效地结合了GRU的时序处理能力和Attention机制的聚焦能力。Transformer 模型在所有指标上都有不错的表现尤其是在F1分数上表明它在精确度和召回率之间取得了良好的平衡。PositionalEmbeddingTransformer 在所有指标上有较好的表现这可能表明它在捕捉长距离依赖和上下文信息方面非常有效。 画出对应的柱状图 bar_width 0.4 colors[c, b, g, tomato, m, y, lime, k,orange,pink,grey,tan,gold,r] fig, ax plt.subplots(2,2,figsize(10,8),dpi128) for i,col in enumerate(df_eval.columns):nint(str(22)str(i1))plt.subplot(n)df_coldf_eval[col]m np.arange(len(df_col))plt.bar(xm,heightdf_col.to_numpy(),widthbar_width,colorcolors)#plt.xlabel(Methods,fontsize12)namesdf_col.indexplt.xticks(range(len(df_col)),names,fontsize10)plt.xticks(rotation40)plt.ylabel(col,fontsize14)plt.tight_layout() #plt.savefig(柱状图.jpg,dpi512) plt.show() 其实模型们都差不了太多大概都在85%左右就RNN离谱一些。。。 模型预测 我们单独拿Transformer模型进行训练我们选择使用它单独拿出来在所有的数据集上进行训练然后对新来的新闻进行预测看看效果。然后去预测新文本。 modelbuild_model(max_wordsmax_words,modePositionalEmbeddingTransformer,hidden_dimhidden_dim) historymodel.fit(X,Y,batch_sizebatch_size,epochs3,verbose0) 再来一个新的电影评论的文本怎么预测呢 new_txtThis latest movie is a cinematic masterpiece! It brilliantly blends stunning visuals with a captivating storyline. The performances are exceptional, capturing the essence of each character beautifully. Its a rare film that not only entertains but also provokes deep thought and emotional engagement. A must-see for movie lovers! 这么多感叹号和love一看就是正面情感。。 我们来试试要先转化为和前面一样的向量。 自定义一个类别处理函数 def predict_newkind(new_txt,tokentok):dic{0: 负面, 1: 正面}new_text_seq tok.texts_to_sequences([new_txt])new_text_seq_padded sequence.pad_sequences(new_text_seq, maxlen200)predictions model.predict(new_text_seq_padded)predicted_class np.argmax(predictions, axis1)return dic[predicted_class[0]] 预测看看 predict_newkind(new_txt) 没问题很准确 再来个负面评论 看看 new_txtUnfortunately, this recent film falls short of expectations. Despite a promising premise, the plot is poorly executed and lacks depth. The performances feel forced and fail to connect with the audience. Additionally, the over-reliance on special effects over substance makes it a forgettable experience. Its a disappointing entry in what could have been an exciting film series.predict_newkind(new_txt) 不错 模型储存 可以把构建的模型和词表进行保存下次就不用再训练了可以直接用。 import pickle from tensorflow.keras.models import save_model # 保存Tokenizer with open(tokenizer.pickle, wb) as handle:pickle.dump(tok, handle, protocolpickle.HIGHEST_PROTOCOL) model.save(my_model.h5) # 保存模型到HDF5文件 下次要用的话直接载入 from tensorflow.keras.models import load_model import pickle with open(tokenizer.pickle, rb) as handle:tok pickle.load(handle) model load_model(my_model.h5, custom_objects{PositionalEmbedding: PositionalEmbedding,TransformerEncoder:TransformerEncoder}) 大家还可以用自己的想法构建更多的模型说不定可以得到更好的准确率。 我本人也测试过 KNN, 决策树逻辑回归这种传统机器学习学的方法效果比神经网络差多了....而且训练时间也长很多。 当然这是英文的案例不用分词什么的想做中文的评论情感分类就可以参考我上一篇文章新闻文本主题多分类 创作不易看官觉得写得还不错的话点个关注和赞吧本人会持续更新python数据分析领域的代码文章~(需要定制代码可私信)
http://www.pierceye.com/news/207267/

相关文章:

  • 网站建设就找奇思网络网站信息备案管理系统
  • wordpress 网站生成app互联网装修公司叫什么
  • 揭阳做网站哪个好黑群晖架设wordpress
  • 网站建设与维护经营范围pc官方网站
  • 龙岗网站建设多少钱设计工作室经营范围
  • 今天建设银行网站无法登录做网站菠菜什么意思
  • 网站伪静态如何配置文件设置网站首页
  • 太原网站建设模板站将电脑做的网站放到外网
  • 网站建设怎么用长尾做标题北京手机站建站
  • 什么是网站功能需求wap网页文字游戏
  • 网站开发者模式怎么保存网站建设3d插件
  • 域名备案网站要不要关景县有专业做网站人员吗
  • 门户网站建设方案ppt公司网站建设全包
  • 网站建站的流程网站建设服务那家好
  • 湖南平台网站建设制作企业网站关联优化
  • 优秀网站设计作品大连seo外包
  • 共享空间网站开发公司做网站 最好的开源cms
  • 免费图片素材网seo wordpress主题
  • ipad可以做网站推广吗wordpress主题中文
  • 自己做网站要会什么软件下载wordpress 小工具代码
  • 视频拍摄及制作培训网站优化有什么用
  • 沈阳网站排名公司网站开发专业怎么样
  • 电影院网站建设方案网络维护是什么职业
  • 网站建设需要的公司wordpress考试主题
  • 企业网站管理系统多站多语言版电子书推送网站怎么做
  • 海洋公司做网站推广安阳网站如何做优化
  • 南昌网站开发公司哪家公司好网站建设接单
  • 宁波网站制作哪家强调用wordpress的文章编辑器
  • 在线制作手机网站公司网站建设厂家
  • 在线分析网站一个小外贸公司怎么开