159
社区成员
发帖
与我相关
我的任务
分享| 这个作业属于那个课程 | 自然语言处理 |
| 这个作业要求在哪里 | https://bbs.csdn.net/topics/615901519 |
| 我在这个课程的目标是 | 实现基于文本内容的垃圾短信识别 |
| 1.设计目的 | |
| 通过课程设计的练习,加深学生对所学自然语言处理的理论知识与操作技能的理解和掌握,使得学生能综合运用所学理论知识和操作技能进行实际工程项目的设计开发,让学生真正体会到自然语言处理算法在实际工程项目中的具体应用方法,为今后能够独立或协助工程师进行人工智能产品的开发设计工作奠定基础。通过综合应用项目的实施,培养学生团队协作沟通能力,培养学生运用现代工具分析和解决复杂工程问题的能力;引导学生深刻理解并自觉实践职业精神和职业规范;培养学生遵纪守法、爱岗敬业、诚实守信、开拓创新的职业品格和行为习惯。 | |
| 2.设计要求 | |
| 2.1 实验仪器及设备 | |
| (1)使用64位Windows操作系统的电脑。 | |
| (2)使用3.8.5版本的Python。 | |
| (3)使用PyCharm Community Edition编辑器。 | |
| (4)使用 jieba,PyTorch,Tensorflow…… | |
| 2.2 设计要求 | |
| 课程设计的主要环节包括课程设计作品和课程设计报告的撰写。课程设计作品的完成主要包含方案设计、计算机编程实现、作品测试几个方面。课程设计报告主要是将课程设计的理论设计内容、实现的过程及测试结果进行全面的总结,把实践内容上升到理论高度。 |
3.设计内容
3.1 云图显示以及贝叶斯分类
老师给的模型是直接用panda和plt来完成的,将数据集导入,对数据预处理,然后用一些panda里面的方法来处理数据字符,导入jieba库来进行基于规则分词,统计其词语出现次数,最后将其绘图表现出来
Sklearn更加复杂一些,将数据预处理后划分成训练集和测试集,对其处理加工,引用MultiLabelBinarizer(),OneVsRestClassifier(LinearSVC())函数对其进行分类与转化,并生成性能报告以及混淆矩阵来评估预测结果,定义一个模型,将处理好的数据放入其中进行训练,用model.score函数得到其分数
3.2 Tensorflow,LSTM
导入数据集,将训练集与测试集4:1划分,用Tokenizer对其文本处理,用 pad_sequences对整数序列进行填充和截断,生成固定长度的序列,按照顺序加入Embedding层、LSTM层和Dense层,编译模型,指定优化器adam、损失函数binary_crossentropy和评估指标
4.设计过程
很多注释在了代码之间,设计过程中主要是以老师给的模型,贝叶斯分类,然后自己添加卷积神经网络,LSTM,来训练模型,达到了一个不错的效果用于识别,其准确率也较高,卷积神经网络的完成查询了很多资料,包括在csdn中,百度上等地方查询,最后得以实现,下面是一些大体分类的步骤,作简单说明。
4.1 云图显示以及贝叶斯分类
定义一个数据处理函数,在后面对数据处理中用很大作用,这里用到了自定义的字典,停用词,包括自己新添加的一些停用词,对数据进行预处理并封装好函数,以便于后续处理使用
这里用到一个哈希表(字典)来遍历,用来统计所有词的词频
设置好云图的参数包括停表,字体,最大词数等,遍历0,1标签并生成一个云图,关闭显示轴
用到两个函数分别将其转化为词频矩阵,以及tf-idf向量矩阵(以表示重要程度)
用到一个多标签转化二进制分类器,以及线性支持向量机的一对多的分类器,以用来后续生成性能报告的模型进行训练,生成混淆矩阵分别对每一个标签进行遍历,可以查看到每个词的预测负样本 正样本等标签以矩阵形式打印出来。
4.2 用Tensorflow,LSTM
用tokenizer对矩阵进行预处理,并将其对应的训练集测试集转化为整数序列,用到一个pad-sequences函数对其进行截断和填充,以完成对文本的处理,方便后续使用
卷积神经网络,嵌入层用来将其转化为密集向量,使用一维卷积核卷积,最大池化操作降低其数据维度,并将其展平为一维,全连接层输出64个隐藏层单元,激活函数Relu,Dropout,再来一个全连接层,输出一个单元用于二分类预测结果,将其编译 优化器威adam,损失函数设置好,评估指标为accuracy。
5.设计总结
本次设计出了很多问题,主要在环境的安装上,如tensorflow与numpy版本不匹配这个问题我查了很久才查出来,本次实验主要以两个模型来做,两个模型各有各的特色,从多个角度来考量,其中用卷积神经网络的最麻烦,因为很多识别器以及函数还有卷积层我都不会用,都是我没看见过的,难的同时也能学习到新的内容,其精准度也较高,几次测试都达到了0.94左右。
设计体会
本次实验历时两个周末,我选取了一个比较容易一点的垃圾短信内容识别,其中模型采用了卷积神经网络和深度学习的一个模型,每一行代码都将其理解并且明白其本质,是我这一次最大的收获,在彭老师的要求下,我在这次实验中得到了巨大的提升,本次也学会了很多东西,在之前从未用过这种类似的东西,才发现原来做一个垃圾短信识别也不是一件容易的事,这些都是需要我们一步一步打磨。实践出真知。一周的实训下来,让我体会颇深,想要实现脑子里的想法,看似简单,但是真正去实现他的时候,却总是力不从心。哪怕最后没有实现自己的目标,但从中获得的诸多收获,也是难能可贵的。通过实际操作,我们可以更深入地理解和掌握所学的知识和技能。在实训过程中,我们相互合作,共同完成任务,锻炼我们的协作和沟通能力。我们可能会遇到各种问题和挑战,在解决问题的过程中,我们可以发挥自己的创新思维和解决问题的能力。对于我来说这不仅仅是一次实训,更是一次试炼,在不断的完善中才能呈现一个好一点的作品,本次的实验最有意思的地方主要在卷积神经网络,运用多层卷积,用一维卷积核进行卷积,添加进去嵌入层,全连接层,lstm,以及最大池化操作来降低数据维度等这些都是一些新的体验,之前只在神经网络的课程中看见过,并不知道如何使用,并且不知道其原理是啥,通过本次实训让我明白了卷积的魅力,这是一次非常棒的学习过程。最后这次课程设计不仅是对新知识的学习,更是一次温故而知新的过程,在彭老师的指导下,我对现有知识获得了更加深刻的理解和新的认识。总而言之,本次课程设计让我受益匪浅,非常感谢彭老师的耐心指导和同学们对我的热心帮助,让我学有所得,受益匪浅。我非常喜欢这种在不断学习中完善自己的感觉,希望在以后的实训中能够再接再厉,保持求知欲,能够将实训项目吸收绝大部分,使其真正的变为自己的东西,而不只是一次应付式的任务交付。
import matplotlib.pyplot as plt
import pandas as pd
import re
message= pd.read_csv('message80W1.csv', header=None, index_col=0)
message.columns = ['label', 'message']
message.head()
fracs = [message['label'].value_counts()[0], message['label'].value_counts()[1]]
fracs
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
labels = ' 非垃圾短信', ' 垃圾短信'
plt.axes(aspect=1)
explode = [0, 0.1]
plt.title(' 垃圾短信与非垃圾短信数量分布情况')
plt.pie( x=fracs,labels=labels,explode=explode,autopct='%1.1f %%',shadow=True,
labeldistance=1.1,
startangle = 90,
pctdistance = 0.6,
radius = 1)
plt.show()
plt.close()
import pandas as pd
import re
pos= message[message['label']==0].sample(1000,random_state=123)
neg= message[message['label']==1].sample(1000,random_state=123)
new_data = pd.concat([pos, neg], axis=0)
data_drop = new_data.drop_duplicates()
print(data_drop.shape)
print(new_data.shape)
import jieba
jieba.load_userdict('newdic1.txt')
data_cut = data_clean.astype('str').apply(lambda x : list(jieba.cut(x)))
data_cut.tail()
stopword_file = 'stopword.txt'
stopword = pd.read_csv(stopword_file, sep='bingrong', encoding='gbk',
header=None)
stopword = [' ',',', ' 会', ' 的', ' 】', ' 【', ' 月', ' 日'] + list(stopword[0])
data_delstop = data_cut.apply(lambda x: [i for i in x if i not in stopword])
data_delstop.head()
import pandas as pd
import re
import jieba
def data_process(file='message80W1.csv'):
message= pd.read_csv('message80W1.csv', header=None, index_col=0)
message.columns = ['label', 'message']#列名赋值->标签 内容
pos= message[message['label']==0].sample(1000,random_state=123) # 抽取部分反例
neg= message[message['label']==1].sample(1000,random_state=123) # 抽取部分正例
new_data = pd.concat([pos, neg], axis=0) # 将样本集拼接
data_clean = data_drop['message'].astype('str').apply(lambda x:
re.sub('x|[^\u4E00-\u9FD5]|[0-9]|\\s|\\t', '', x))
jieba.load_userdict('newdic1.txt') #将自定义的词典加入
data_cut = data_clean.astype('str').apply(lambda x : list(jieba.cut(x))) #data去敏的句子进行分词操作,返回列表
#去除停用词
stopword_file = 'stopword.txt'
stopword = pd.read_csv(stopword_file, sep='bingrong', encoding='gbk', header=None) # 读取停用词
# 添加自定义的停用词
stopword = [' ',',', ' 会', ' 的', ' 】', ' 【', ' 月', ' 日'] +list(stopword[0]) # 去除停用词
data_delstop = data_cut.apply(lambda x: [i for i in x if i not in stopword])
#数据预处理函数封装
labels = new_data.loc[data_delstop.index, 'label'] #标签
adata = data_delstop.apply(lambda x: ' '.join(x)) #将列表进行拼接
return adata, data_delstop, labels
import numpy as np
from PIL import Image
from wordcloud import WordCloud,STOPWORDS
adata, data_delstop, labels= data_process()
def words_count(label=0):
word_dict = {}
for item in list(data_delstop[labels==label]):
for i in item:
if i not in word_dict:
word_dict[i] = 1
else:
word_dict[i] += 1
return word_dict
print(words_count())
def WordCloud_plot(mask_picture='duihuakuan.jpg'):
p1 = plt.figure(figsize=(16,8),dpi=80)
image= Image.open(mask_picture)
graph = np.array(image)
wc =WordCloud(background_color='white',
mask=graph,
max_words = 2000,
stopwords = STOPWORDS,
font_path = 'simhei.ttf',
random_state = 30)
for i in [0,1]:
p1.add_subplot(1,2,i+1)
wc.generate_from_frequencies(words_count(i))
plt.imshow(wc)
plt.axis("off")
plt.show()
WordCloud_plot()
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.model_selection import train_test_split
from sklearn.svm import LinearSVC
dataAlready, labels, _ = data_process()
train_data, test_data, train_y, test_y = train_test_split(dataAlready,
labels, test_size=0.2)
vectorizer = CountVectorizer()
transformer = TfidfTransformer()
# 训练集的处理
train_cv = vectorizer.fit_transform(train_data)
tfidf_train = transformer.fit_transform(train_cv.toarray())
print(' 词频结果:\n',train_cv)
print('TF-IDF 结果:\n',tfidf_train)
import numpy as np
from sklearn.preprocessing import MultiLabelBinarizer
from sklearn.multiclass import OneVsRestClassifier
from sklearn.svm import LinearSVC
from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
from sklearn.metrics import multilabel_confusion_matrix
mlb = MultiLabelBinarizer()
train_y = mlb.fit_transform(train_y)
clf = OneVsRestClassifier(LinearSVC())
clf.fit(tfidf_train, train_y)
res = clf.predict(tfidf_train)
print('模型训练正确率',clf.score(tfidf_train, train_y))
res_labels = mlb.inverse_transform(res)
#print('预测结果:', res_labels)
print('性能报告:', classification_report(train_y, res))
#混淆矩阵------------------------------------------------
cm = multilabel_confusion_matrix(train_y, res)
for i, label in enumerate(mlb.classes_):
print('混淆矩阵:', label)
print(pd.DataFrame(cm[i], columns=['预测负样本', '预测正样本'], index=['实际负样本', '实际正样本']))
adata, data_after_stop, lables = data_process()
data_tr, data_te, labels_tr, labels_te = train_test_split(adata, lables, test_size=0.2)
countVectorizer = CountVectorizer()
data_tr = countVectorizer.fit_transform(data_tr)
X_tr = TfidfTransformer().fit_transform(data_tr.toarray()).toarray()
data_te = CountVectorizer(vocabulary=countVectorizer.vocabulary_).fit_transform(data_te)
X_te = TfidfTransformer().fit_transform(data_te.toarray()).toarray()
model = GaussianNB()
model.fit(X_tr, labels_tr)
print(' 模型训练正确率:',model.score(X_te, labels_te))
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.layers import Embedding, LSTM, Dense, Dropout
from tensorflow.keras.models import Sequential, Model
# 加载数据
data = pd.read_csv('message80W1.csv', header=None, index_col=0)
data.columns = ['label', 'message']
train_data = data.sample(frac=0.8, random_state=42)
test_data = data.drop(train_data.index)
# 对文本进行处理
tokenizer = Tokenizer(num_words=10000, oov_token='<OOV>')
tokenizer.fit_on_texts(train_data['message'])
train_sequences = tokenizer.texts_to_sequences(train_data['message'])
test_sequences = tokenizer.texts_to_sequences(test_data['message'])
train_padded = pad_sequences(train_sequences, maxlen=100, padding='post', truncating='post')
test_padded = pad_sequences(test_sequences, maxlen=100, padding='post', truncating='post')
# 构建模型
model = Sequential()
model.add(Embedding(input_dim=10000, output_dim=100, input_length=100))
model.add(LSTM(units=64, dropout=0.5, recurrent_dropout=0.5))
model.add(Dense(units=1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.summary()
# 训练模型
model.fit(train_padded, train_data['label'], epochs=1, batch_size=32, validation_split=0.2)
# 评估模型
test_loss, test_acc = model.evaluate(test_padded, test_data['label'])
print('Test accuracy:', test_acc)
import numpy as np
import pandas as pd
import tensorflow as tf
from tensorflow.keras.preprocessing.text import Tokenizer
from tensorflow.keras.preprocessing.sequence import pad_sequences
from tensorflow.keras.layers import Embedding, Conv1D, MaxPooling1D, Flatten, Dense, Dropout
from tensorflow.keras.models import Sequential
data= pd.read_csv('message80W1.csv', header=None, index_col=0)
data.columns = ['label', 'message']
train_data = data.sample(frac=0.8, random_state=42)
test_data = data.drop(train_data.index)
tokenizer = Tokenizer(num_words=10000, oov_token='<OOV>')
tokenizer.fit_on_texts(train_data['message'])
train_sequences = tokenizer.texts_to_sequences(train_data['message'])
test_sequences = tokenizer.texts_to_sequences(test_data['message'])
train_padded = pad_sequences(train_sequences, maxlen=100, padding='post', truncating='post')
test_padded = pad_sequences(test_sequences, maxlen=100, padding='post', truncating='post')
model = Sequential()
model.add(Embedding(input_dim=10000, output_dim=32, input_length=100))
model.add(Conv1D(filters=32, kernel_size=3, activation='relu'))
model.add(MaxPooling1D(pool_size=2))
model.add(Flatten())
model.add(Dense(units=64, activation='relu'))
model.add(Dropout(rate=0.5))
model.add(Dense(units=1, activation='sigmoid'))
model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
model.fit(train_padded, train_data['label'], epochs=10, batch_size=32, validation_split=0.2)
test_loss, test_acc = model.evaluate(test_padded, test_data['label'])
print('Test accuracy:', test_acc)