目录

前言

一、数据加载

1.加载包

2.读取数据

二、文本处理

1.去除无用字符

2.文本分词

3.去除停用词

4.去除低频词

5.划分训练集和测试集

三、把文本转换成向量的形式

1.把文本转换成tf-idf向量

2.把文本转换成word2vec向量

3.把文本转换成bert向量

四、训练模型以及评估

1.使用tf-idf向量训练

2.使用word2vec向量训练

3.使用Bert向量训练

总结


前言

该实战任务是对豆瓣评分的预测。在这个项目中,我们通过豆瓣评论预测该电影的评分。给定的输入为一段文本,输出为具体的评分。实际上就是一个文本分类任务。在这个项目中,我们需要做:

  • 文本的预处理,如停用词的过滤,低频词的过滤,特殊符号的过滤等
  • 文本转化成向量,将使用三种方式,分别为tf-idf, word2vec以及BERT向量。
  • 逻辑回归模型训练,并做交叉验证
  • 评估模型的准确率

一、数据加载

1.加载包

首先是加载库,具体这些库函数的作用会在下文使用到的时候说明。

#导入数据处理的基础包
import numpy as np
import pandas as pd#导入用于计数的包
from collections import Counter#导入tf-idf相关的包
from sklearn.feature_extraction.text import TfidfTransformer
from sklearn.feature_extraction.text import CountVectorizer#导入模型评估的包
from sklearn import metrics#导入与word2vec相关的包
from gensim.models import KeyedVectors#导入与bert embedding相关的包,关于mxnet包下载的注意事项参考实验手册
from bert_embedding import BertEmbedding
import mxnet#包tqdm是用来对可迭代对象执行时生成一个进度条用以监视程序运行过程
from tqdm import tqdm#导入其他一些功能包
import requests
import os

2.读取数据

接下来是通过pd.read_csv函数读取数据,该函数是用来读取csv格式的文件,将表格数据转化成dataframe格式。由于我们仅需要评论和评分这两列,所以通过索引取出对应的数据。

#读取数据
data = pd.read_csv('data/DMSC.csv')
#观察数据格式
data.head()
#输出数据的一些相关信息
data.info()
#只保留数据中我们需要的两列:Comment列和Star列
data = data[['Comment','Star']]
#观察新的数据的格式
data.head()

输出结果:

  ID Movie_Name_EN Movie_Name_CN Crawl_Date Number Username Date Star Comment Like
0 0 Avengers Age of Ultron 复仇者联盟2 2017-01-22 1 然潘 2015-05-13 3 连奥创都知道整容要去韩国。 2404
1 10 Avengers Age of Ultron 复仇者联盟2 2017-01-22 11 影志 2015-04-30 4 “一个没有黑暗面的人不值得信任。” 第二部剥去冗长的铺垫,开场即高潮、一直到结束,会有人觉... 381
2 20 Avengers Age of Ultron 复仇者联盟2 2017-01-22 21 随时流感 2015-04-28 2 奥创弱爆了弱爆了弱爆了啊!!!!!! 120
3 30 Avengers Age of Ultron 复仇者联盟2 2017-01-22 31 乌鸦火堂 2015-05-08 4 与第一集不同,承上启下,阴郁严肃,但也不会不好看啊,除非本来就不喜欢漫威电影。场面更加宏大... 30
4 40 Avengers Age of Ultron 复仇者联盟2 2017-01-22 41 办公室甜心 2015-05-10 5 看毕,我激动地对友人说,等等奥创要来毁灭台北怎么办厚,她拍了拍我肩膀,没事,反正你买了两份... 16
  Comment Star
0 连奥创都知道整容要去韩国。 3
1 “一个没有黑暗面的人不值得信任。” 第二部剥去冗长的铺垫,开场即高潮、一直到结束,会有人觉... 4
2 奥创弱爆了弱爆了弱爆了啊!!!!!! 2
3 与第一集不同,承上启下,阴郁严肃,但也不会不好看啊,除非本来就不喜欢漫威电影。场面更加宏大... 4
4 看毕,我激动地对友人说,等等奥创要来毁灭台北怎么办厚,她拍了拍我肩膀,没事,反正你买了两份... 5

二、文本处理

1.去除无用字符

通过正则匹配,去除表情和其他字符、残留冒号和符号以及空格。

# TODO1: 去掉一些无用的字符,自行定一个字符几何,并从文本中去掉
#    your to do
#去除字母数字表情和其它字符
import redef clear_character(sentence):pattern1='[a-zA-Z0-9]'pattern2 = re.compile(u'[^\s1234567890::' + '\u4e00-\u9fa5]+')pattern3='[’!"#$%&\'()*+,-./:;<=>?@[\\]^_`{|}~]+'line1=re.sub(pattern1,'',sentence)   #去除英文字母和数字line2=re.sub(pattern2,'',line1)   #去除表情和其他字符line3=re.sub(pattern3,'',line2)   #去除去掉残留的冒号及其它符号new_sentence=''.join(line3.split()) #去除空白return new_sentence
data["comment_processed"]=data['Comment'].apply(clear_character)data.head()

输出结果:

  Comment Star comment_processed
0 连奥创都知道整容要去韩国。 3 连奥创都知道整容要去韩国
1 “一个没有黑暗面的人不值得信任。” 第二部剥去冗长的铺垫,开场即高潮、一直到结束,会有人觉... 4 一个没有黑暗面的人不值得信任第二部剥去冗长的铺垫开场即高潮一直到结束会有人觉得只剩动作特技不...
2 奥创弱爆了弱爆了弱爆了啊!!!!!! 2 奥创弱爆了弱爆了弱爆了啊
3 与第一集不同,承上启下,阴郁严肃,但也不会不好看啊,除非本来就不喜欢漫威电影。场面更加宏大... 4 与第一集不同承上启下阴郁严肃但也不会不好看啊除非本来就不喜欢漫威电影场面更加宏大单打与团战又...
4 看毕,我激动地对友人说,等等奥创要来毁灭台北怎么办厚,她拍了拍我肩膀,没事,反正你买了两份... 5 看毕我激动地对友人说等等奥创要来毁灭台北怎么办厚她拍了拍我肩膀没事反正你买了两份旅行保险惹

2.文本分词

通过jieba分词,对输入的文本进行分词。

# TODO2: 导入中文分词包jieba, 并用jieba对原始文本做分词
import jieba
def comment_cut(content):# TODO: 使用结巴完成对每一个comment的分词
#     seg = jieba.lcut(content)seg = list(jieba.cut(content.strip()))return seg# 输出进度条
tqdm.pandas(desc='apply')
data['comment_processed'] = data['comment_processed'].progress_apply(comment_cut)
# 观察新的数据的格式
data.head()

输出结果:

  Comment Star comment_processed
0 连奥创都知道整容要去韩国。 3 [连, 奥创, 都, 知道, 整容, 要, 去, 韩国]
1 “一个没有黑暗面的人不值得信任。” 第二部剥去冗长的铺垫,开场即高潮、一直到结束,会有人觉... 4 [一个, 没有, 黑暗面, 的, 人, 不, 值得, 信任, 第二部, 剥去, 冗长, 的,...
2 奥创弱爆了弱爆了弱爆了啊!!!!!! 2 [奥创, 弱, 爆, 了, 弱, 爆, 了, 弱, 爆, 了, 啊]
3 与第一集不同,承上启下,阴郁严肃,但也不会不好看啊,除非本来就不喜欢漫威电影。场面更加宏大... 4 [与, 第一集, 不同, 承上启下, 阴郁, 严肃, 但, 也, 不会, 不, 好看, 啊,...
4 看毕,我激动地对友人说,等等奥创要来毁灭台北怎么办厚,她拍了拍我肩膀,没事,反正你买了两份... 5 [看毕, 我, 激动, 地, 对, 友人, 说, 等等, 奥创, 要, 来, 毁灭, 台北,...

3.去除停用词

载入停用词表,并将停用词去除。

# TODO3: 设定停用词并从文本中去掉停用词# 下载中文停用词表至data/stopWord.json中,下载地址:https://github.com/goto456/stopwords/
if not os.path.exists('data/stopWord.json'):stopWord = requests.get("https://raw.githubusercontent.com/goto456/stopwords/master/cn_stopwords.txt")with open("data/stopWord.json", "wb") as f:f.write(stopWord.content)# 读取下载的停用词表,并保存在列表中
with open("data/stopWord.json","r",encoding='utf-8') as f:stopWords = f.read().split("\n")  # 去除停用词
def rm_stop_word(wordList):# your code, remove stop words# TODOfiltered_words = [word for word in wordList if word not in stopWords]return filtered_words
#这行代码中.progress_apply()函数的作用等同于.apply()函数的作用,只是写成.progress_apply()函数才能被tqdm包监控从而输出进度条。
data['comment_processed'] = data['comment_processed'].progress_apply(rm_stop_word)
# 观察新的数据的格式
data.head()

输出结果:

  Comment Star comment_processed
0 连奥创都知道整容要去韩国。 3 [奥创, 知道, 整容, 韩国]
1 “一个没有黑暗面的人不值得信任。” 第二部剥去冗长的铺垫,开场即高潮、一直到结束,会有人觉... 4 [一个, 没有, 黑暗面, 值得, 信任, 第二部, 剥去, 冗长, 铺垫, 开场, 高潮,...
2 奥创弱爆了弱爆了弱爆了啊!!!!!! 2 [奥创, 弱, 爆, 弱, 爆, 弱, 爆]
3 与第一集不同,承上启下,阴郁严肃,但也不会不好看啊,除非本来就不喜欢漫威电影。场面更加宏大... 4 [第一集, 不同, 承上启下, 阴郁, 严肃, 不会, 好看, 本来, 喜欢, 漫威, 电影...
4 看毕,我激动地对友人说,等等奥创要来毁灭台北怎么办厚,她拍了拍我肩膀,没事,反正你买了两份... 5 [看毕, 激动, 友人, 说, 奥创, 毁灭, 台北, 厚, 拍了拍, 肩膀, 没事, 反正...

4.去除低频词

通过pandas索引循环comment列,将所有词合并到一个列表里。然后通过Counter统计词频数,并将词频小于10的词去除。

# TODO4: 去除低频词, 去掉词频小于10的单词,并把结果存放在data['comment_processed']里import jieba
import re
import pandas as pd
from collections import Counterdata.head()list_set = []for i in range(len(data)):for j in data.iloc[i]['comment_processed']: list_set.extend(j)words_count = Counter(list_set)min_threshold=10
my_dict = {k: v for k, v in words_count.items() if v < min_threshold}
filteredA = Counter(my_dict)# 去除低频词
def rm_low_frequence_word(wordList):# your code, remove stop words# TODOfiltered_words = [word for word in wordList if word not in filteredA]return filtered_words#这行代码中.progress_apply()函数的作用等同于.apply()函数的作用,只是写成.progress_apply()函数才能被tqdm包监控从而输出进度条。
data['comment_processed'] = data['comment_processed'].progress_apply(rm_low_frequence_word)
data.head()

5.划分训练集和测试集

选择语料库中的20%作为测试数据,剩下的作为训练数据。把数据分为训练集和测试集。 comments_train(list)保存用于训练的文本,comments_test(list)保存用于测试的文本。 y_train, y_test是对应的标签(1,2,3,4,5)

from sklearn.model_selection import train_test_split
X = data['comment_processed']
y = data['Star']
test_ratio = 0.2
comments_train, comments_test, y_train, y_test = train_test_split(X, y, test_size=test_ratio, random_state=0)
print(comments_train.head(),y_train.head)

输出结果:

104861    [没, 看过, 小说, 真的, 电影, 折服, 两大, 女主, 美, 演技, 超棒, 可能,...
190626    [继宫, 老, 之后, 一个, 期待, 导演, 剧情, 画面, 没得说, 最后, 哗哗, 流...
198677    [誉, 画面, 找不出, 赞点, 43, 岁, 新海, 诚, 应该, 做出, 更, 里子, 东西]
207320                                             [兔子, 好萌]
106219                                 [希望, 最后, 我能, 活成, 样子]
Name: comment_processed, dtype: object <bound method NDFrame.head of
104861    5
190626    4
198677    3
207320    5
106219    4..
176963    4
117952    2
173685    3
43567     5
199340    4
Name: Star, Length: 170004, dtype: int64>

三、把文本转换成向量的形式

在这个部分我们会采用三种不同的方式将文本转化为向量:

  • 使用tf-idf向量
  • 使用word2vec
  • 使用bert向量

转换成向量之后,再进行模型的训练。

1.把文本转换成tf-idf向量

通过sklearn的feature_extraction.text.TfidfTransformer模块把训练文本和测试文本转换成tf-idf向量。由于TfidfTransformer模块输出的词列表用空格连接,而不是逗号连接,所以需要先转化下列表形式。

from sklearn.feature_extraction.text import TfidfTransformercomments_train1 = [' '.join(i) for i in comments_train]
comments_test1 = [' '.join(i) for i in comments_test]print(comments_train[0:5])
print(comments_train1[0:5])tfidf2 = TfidfTransformer()
counter = CountVectorizer(analyzer='word')
# counts = counter.fit_transform(comments_train1)
tfidf_train = tfidf2.fit_transform(counter.fit_transform(comments_train1))
tfidf_test=tfidf2.transform(counter.transform(comments_test1))
print(tfidf_train.shape,tfidf_test.shape)

输出结果:

104861    [没, 看过, 小说, 真的, 电影, 折服, 两大, 女主, 美, 演技, 超棒, 可能,...
190626    [继宫, 老, 之后, 一个, 期待, 导演, 剧情, 画面, 没得说, 最后, 哗哗, 流...
198677    [誉, 画面, 找不出, 赞点, 43, 岁, 新海, 诚, 应该, 做出, 更, 里子, 东西]
207320                                             [兔子, 好萌]
106219                                 [希望, 最后, 我能, 活成, 样子]
Name: comment_processed, dtype: object
['没 看过 小说 真的 电影 折服 两大 女主 美 演技 超棒 可能 一个 女孩儿 一段 会 吃醋 深爱 友谊', '继宫 老 之后 一个 期待 导演 剧情 画面 没得说 最后 哗哗 流 眼泪 略显 尴尬 完 以后 终于 明白 日本 细腻 风格 电影界 占有 重要 一席之地 以前 知道 有人 推崇 日本 电影 现在 明白 治愈 系 目前 来看 无人 能出 其右', '誉 画面 找不出 赞点 43 岁 新海 诚 应该 做出 更 里子 东西', '兔子 好萌', '希望 最后 我能 活成 样子']
(170004, 87026) (42502, 87026)

2.把文本转换成word2vec向量

由于训练出一个高效的word2vec词向量往往需要非常大的语料库与计算资源,所以我们通常不自己训练Wordvec词向量,而直接使用网上开源的已训练好的词向量。sgns.zhihu.word是从Chinese-Word-Vectors下载到的预训练好的中文词向量文件。
通过KeyedVectors.load_word2vec_format()函数加载预训练好的词向量文件。

对于每个句子,生成句子的向量。具体的做法是对包含在句子中的所有单词的向量做平均。

model = KeyedVectors.load_word2vec_format('data/sgns.zhihu.word')
model['今天']
vocabulary = model.vocabvec_lem=model['鲁迅'].shape[0]
def comm_vec(c):vec_com=np.zeros(vec_lem)coun=0for w in c:if w in model:vec_com+=model[w]coun+=1return vec_com/counword2vec_train=np.vstack(comments_train.progress_apply(comm_vec))
word2vec_test=np.vstack(comments_test.progress_apply(comm_vec))

3.把文本转换成bert向量

transformers是huggingface提供的预训练模型库,可以轻松调用API来得到的词向量。

接下来主要介绍如何调用transformers库生成中文词向量。使用的预训练模型是Bert_mini,一个中文文本的预训练模型。通过BertTokenizer,BertModel函数将词转化为向量。

接下来就是通过process_word()函数将得到的字向量拼成词向量,然后再通过comm_vec()函数将词向量拼成句向量。

from transformers import BertTokenizer,BertModel
import torch
import logging# set cuda
gpu = 0
use_cuda = gpu >= 0 and torch.cuda.is_available()
print(use_cuda)
if use_cuda:torch.cuda.set_device(gpu)device = torch.device("cuda", gpu)
else:device = torch.device("cpu")
logging.info("Use cuda: %s, gpu id: %d.", use_cuda, gpu)bert_model_dir='bert-mini'
tokenizer=BertTokenizer.from_pretrained(bert_model_dir)
Bertmodel=BertModel.from_pretrained(bert_model_dir)word=['今天我']
input_id=tokenizer(word,padding=True,truncation=True,max_length=10,return_tensors='pt')
result=Bertmodel(input_id['input_ids'])
# print(result)
vec_len=len(result[0][0][1])
# vec_len=result[0,1,0].shape[0]
print(vec_len)def process_word(w):vec_com=np.zeros(vec_len)num=len(w)input_id=tokenizer(w,padding=True,truncation=True,max_length=10,return_tensors='pt')res=Bertmodel(input_id['input_ids'])k=len(res[0][0])for i in range(k):
#         print(res[0][0][i].detach().numpy())vec_com+=res[0][0][i].detach().numpy()return vec_com/kdef comm_vec(c):vec_com=np.zeros(vec_len)coun=0for w in c:if w in model:vec_com+=process_word(w)coun+=1break    return vec_com/counbert_train=np.vstack(comments_train.progress_apply(comm_vec))
bert_test=np.vstack(comments_test.progress_apply(comm_vec))print (tfidf_train.shape, tfidf_test.shape)
print (word2vec_train.shape, word2vec_test.shape)
print (bert_train.shape, bert_test.shape)

输出结果:

(170004, 87026) (42502, 87026)
(170004, 300) (42502, 300)
(170004, 256) (42502, 256)

四、训练模型以及评估

对如上三种不同的向量表示法,分别训练逻辑回归模型,需要做:

  • 搭建模型
  • 训练模型(并做交叉验证)
  • 输出最好的结果

导入逻辑回归以及交叉验证的包。

# 导入逻辑回归的包
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import GridSearchCV

1.使用tf-idf向量训练

clf=LogisticRegression()
param_grid = {'C': [0.01,0.1, 1.0, 2.0,10,100], 'penalty' : ['l1', 'l2']
}
grid_search = GridSearchCV(estimator=clf,param_grid=param_grid, scoring='accuracy',cv=5,n_jobs=-1)
grid_search.fit(tfidf_train, y_train)print(grid_search.best_params_)
print(grid_search.best_score_)lr_best=LogisticRegression(penalty='l2',C=2)
lr_best.fit(tfidf_train, y_train)
tf_idf_y_pred=lr_best.predict(tfidf_test)print('TF-IDF LR test accuracy %s' % metrics.accuracy_score(y_test, tf_idf_y_pred))
#逻辑回归模型在测试集上的F1_Score
print('TF-IDF LR test F1_score %s' % metrics.f1_score(y_test, tf_idf_y_pred,average="macro"))

输出结果:

{'C': 1.0, 'penalty': 'l2'}
0.4747594131314477
TF-IDF LR test accuracy 0.47851865794550846
TF-IDF LR test F1_score 0.43133900686271376

2.使用word2vec向量训练

clf=LogisticRegression()
param_grid = {'C': [0.01,0.1, 1.0, 2.0,10,100], 'penalty' : ['l1', 'l2'],'solver':['liblinear','lbfgs','sag','saga']
}
grid_search = GridSearchCV(estimator=clf,param_grid=param_grid, scoring='accuracy',cv=5,n_jobs=-1)
grid_search.fit(word2vec_train, y_train)print(grid_search.best_params_)
print(grid_search.best_score_)lr_best=LogisticRegression(penalty='l1',C=100,solver='saga')
lr_best.fit(word2vec_train, y_train)
word2vec_y_pred=lr_best.predict(word2vec_test)print('Word2vec LR test accuracy %s' % metrics.accuracy_score(y_test, word2vec_y_pred))
#逻辑回归模型在测试集上的F1_Score
print('Word2vec LR test F1_score %s' % metrics.f1_score(y_test, word2vec_y_pred,average="macro"))

输出结果:

{'C': 1.0, 'penalty': 'l2', 'solver': 'lbfgs'}
0.4425013587835652
Word2vec LR test accuracy 0.4447555409157216
Word2vec LR test F1_score 0.37275840165350765

3.使用Bert向量训练

clf=LogisticRegression()
param_grid = {'C': [0.01,0.1, 1.0, 2.0,10,100], 'penalty' : ['l1', 'l2'],'solver':['liblinear','lbfgs','sag','saga']
}
grid_search = GridSearchCV(estimator=clf,param_grid=param_grid, scoring='accuracy',cv=5,n_jobs=-1)
grid_search.fit(bert_train, y_train)print(grid_search.best_params_)
print(grid_search.best_score_)

输出结果:

{'C': 2.0, 'penalty': 'l2', 'solver': 'sag'}
0.4072104199357458
Bert LR test accuracy 0.4072090725142346
Bert LR test F1_score 0.3471216422860073

总结

通过不同方式获取的词向量进行训练,五分类的准确率都在百分之四十多,差距不大,可能是仅仅用到了逻辑回归模型,效果并没有多大提升。所以接下来可以从以下几个方面提升效果:

  • 句子向量融合方法改进
  • 解决类别不平衡问题
  • 词向量模型再训练
  • jieba分词效果改进
  • 用深度神经网络进行分类

以上就是文本分类史上最详细入门教程,码字不易,希望大家能够多多点赞收藏,如果需要代码或模型的朋友,可以在评论区留言或者私信。


参考:

贪心学院自然语言处理

NLP之文本分类实战入门超详细教程相关推荐

  1. 【K8S实战】-超详细教程(二)

    [K8S实战]-超详细教程(二) 环境这块的这里我就不过多描述了,需要了解的可以看这篇文章[k8s搭建(超详细,保姆级教程)]. 1.Deployment Deployment其他功能我上一篇文章已写 ...

  2. 【K8S实战】-超详细教程(三)

    [K8S实战]-超详细教程(三) 1.存储 1.1.nfs默认存储 我这里只演示nfs作为K8S的默认存储,其他的可以看这里[存储类]. 1.1.1.安装nfs服务 所有机器都安装nfs工具 所有机器 ...

  3. 【K8S实战】-超详细教程(一)

    [K8S实战]-超详细教程(一) 1.环境准备 K8S环境搭建可以看这篇文章[k8s搭建(超详细,保姆级教程)],这里就不过多赘述了,有疑问欢迎留言. 2.K8S资源创建 K8S的资源创建一般有2种: ...

  4. 【学习笔记】零基础入门NLP - 新闻文本分类实战

    赛题理解   首先要理解赛题的背景及描述--赛题以新闻数据为赛题数据,数据集报名后可见并可下载.赛题数据为新闻文本,并按照字符级别进行匿名处理.整合划分出14个候选分类类别:财经.彩票.房产.股票.家 ...

  5. selenium入门超详细教程——网页自动化操作

    文章目录 简介 一.环境安装 1.selenium安装 2.安装浏览器驱动 2.1 确定浏览器版本 2.2 下载驱动 二.基础用法 1.对页面进行操作 1.1 初始化浏览器对象 1.2 访问页面 1. ...

  6. Pandas入门超详细教程,看了超简单

    本文主要是对pandas新手入门详细介绍,通过本文你将系统性了解pandas为何会有数据分析界"瑞士军刀"的盛誉,下面请看内容如下: 01 关于pandas pandas,pyth ...

  7. 问题 U: 任务3-1:编程实现根据指定文本生成电子印章(超详细教程)

    hnuster!看了很多关于该题的解法但是我们发现,我们竟然下不了手!!!第一个问题:制作属于自己名字的txt(即xds.txt).这个都不会,可是网上的其他解法都一笔带过了,琢磨了半天弄清楚的. 下 ...

  8. 【NLP从零入门】预训练时代下,深度学习模型的文本分类算法(超多干货,小白友好,内附实践代码和文本分类常见中文数据集)

    如今NLP可以说是预训练模型的时代,希望借此抛砖引玉,能多多交流探讨当前预训练模型在文本分类上的应用. 1. 任务介绍与实际应用 文本分类任务是自然语言处理(NLP)中最常见.最基础的任务之一,顾名思 ...

  9. 【项目实战课】NLP入门第1课,人人免费可学,基于TextCNN的新闻文本分类实战...

    欢迎大家来到我们的项目实战课,本期内容是<基于TextCNN的新闻文本分类实战>. 所谓项目课,就是以简单的原理回顾+详细的项目实战的模式,针对具体的某一个主题,进行代码级的实战讲解,可以 ...

最新文章

  1. Spring事务管理3----声明式事务管理(1)
  2. amazon mws api 获取所有产品_致跨境电商新卖家 - 如何确定一个产品的市场容量?...
  3. 使用Servlet 3.0,Redis / Jedis和CDI的简单CRUD –第2部分
  4. java监控rabbitMq服务状态,SpringCloud-Turbine【RabbitMQ服务监控】
  5. 使用Javascript 实现类
  6. Web开发之三:前后端开发任务量分析与比较
  7. java 交集怎么写_Java里面如何求两个集合的交集
  8. oracle的一些常见问题及处理
  9. MongoDB多条件分组聚合查询
  10. Windows防火墙添加80端口,解决apache无法访问的问题
  11. 扣丁软件测试基础知识,总结钢筋工程266问,包你从入门到放弃,建议收藏
  12. 【数据库】SQL中的rollup() 函数的作用?
  13. 【手把手教程】uniapp + vue 从0搭建仿斗鱼虎牙直播App:腾讯云MLVB移动直播实践连麦PK+带货
  14. php 汉字拼音字典排序,按拼音排序的小技巧
  15. JavaJUC基础知识梳理
  16. 蓝牙音箱电路板原理图_一种蓝牙音箱电路板的制作方法
  17. 2022-2028年中国电子级醋酸行业市场调查研究及投资策略研究报告
  18. STM32在线烧录程序的开发
  19. Redis入门到实战(实战篇)缓存更新、穿透、雪崩、击穿!
  20. 层次分析法原理分析及Python实现层析分析法

热门文章

  1. 入门人工智能该读哪些书?五份AI经典书单
  2. Deep Biaffine Attention for Dependency Parsing
  3. 云原生爱好者周刊:美国国家安全局发布网络安全指南
  4. 阿里、华为、腾讯的“第二曲线”,大厂云们的成败得失如何评价?
  5. 2_嵌入式软件开发简介
  6. 发送邮件服务器连接错误什么意思,SMTP 错误(-1) :连接服务器失败
  7. 金融安全:谁忽略了移动应用加密?
  8. 【python】-- paramiko、跳板机(堡垒机)
  9. 牛啊!2小时复现顶会论文,他的秘诀是——
  10. 101个帮助你成为更好Web开发程序员的技巧