本文共 8660 字,大约阅读时间需要 28 分钟。
我又回来了,这次进行英文垃圾短信分类任务。下面将分别用机器学习
和深度学习
的方法进行操作,此外深度学习
的方法又分别用RNN
和CNN
的方法进行展示,Let’s go!!!
充满活力的冲啊!!!
这次的任务很简单,就是一个二分类的任务。不过属于nlp的二分类的任务。给出短信内容,判别该短信是否是垃圾短信。
那么,那么,那么,重点来了!既然要做本次实验,怎么能没有数据集呢?
数据集才是驱动力呀!
数据集是kaggle下载的,来判别短信内容是否为垃圾短信。
首先先读取数据集,我们先看一下数据集的模样。
不对,应该是这样的。
之后,统计一下,数据的分布情况。从图中我们看到短信的类别存在不平衡的情况。
# 以图方式表示sns.countplot(sms_data["label"])plt.xlabel("Label")plt.title("Number of ham of spam messages")
既然存在样本不平衡的情况,那么下面对数据预处理的时候,我们就需要对这情况进行处理,这里的处理在深度学习的部分。
a.分割数据
为了评估效果,我们需要对数据集进行分割,来划出一部分,用来测试。
b.文本特征提取
这里将短信的内容,将文本数据转为特征向量。
比较常用的文本特征表示法为词袋法
。
词袋法:
主要有两个api来实现CounterVectorizer
和TfidfVectorizer
CountVectorizer:
TfidfVectorizer:
这里给出TfidfVectorizer的部分代码,
a.模型满汉全席
将常见的模型,拿出来,进行评估,废话不多讲,直接上代码
models = { "SVC":SVC(kernel="linear"), "MultinomialNB":MultinomialNB(), "LogisticRegression":LogisticRegression(), "KNeighborsClassifier":KNeighborsClassifier(), "DecisionTreeClassifier":DecisionTreeClassifier(), "RandomForestClassifier":RandomForestClassifier(), "AdaBoostClassifier":AdaBoostClassifier(), "BaggingClassifier":BaggingClassifier(), "ExtraTreesClassifier":ExtraTreesClassifier()}prediction = dict()score_map = { }for model_name in models: model = models[model_name] model.fit(x_train_df,y_train) prediction[model_name]=model.predict(x_test_df) score=accuracy_score(y_test,prediction[model_name]) score_map[model_name]=score result = pd.DataFrame()result["model"] = score_map.keys()result["score" ]=score_map.values()result["score"]=result["score"].apply(lambda x : x*100)
最后让我们看一下结果,可以看到支持向量机的效果很好,而且这只是默认参数的情况下,下面调一下参,在看一下。
def plot_model_performace(result): sns.set_style("ticks") figsize=(22,6) ticksize=12 titlesize=ticksize+8 labelsize=ticksize+5 xlabel="Model" ylabel="Score" title="Model Performance" params={ "figure.figsize":figsize, "axes.labelsize":labelsize, "axes.titlesize":titlesize, "xtick.labelsize":ticksize, "ytick.labelsize":ticksize} plt.rcParams.update(params) col1="model" col2="score" sns.barplot(x=col1,y=col2,data=result) plt.title(title.title()) plt.xlabel(xlabel) plt.ylabel(ylabel) plt.xticks(rotation=90) plt.grid() plt.plot() plt.show() print(result)
b.超参数调参
现在就由最伟大的炼丹师出场了。
from sklearn.model_selection import GridSearchCVparam_grid = { "alpha":np.concatenate( [ np.arange(0.0001,0.001,0.0001), np.arange(0.001,0.01,0.001), np.arange(0.01,0.1,0.01), np.arange(0.1,1,0.1), np.arange(1,10,1), np.arange(10,100,5) ] )}model = MultinomialNB()grid_cv_model = GridSearchCV(model,param_grid,n_jobs=-1,verbose=3,cv=3)grid_cv_model.fit(x_train_df,y_train)#对指标评价print("{}{}".format("Best Estimator: ",grid_cv_model.best_estimator_))print("{}{}".format("Besr Params: ",grid_cv_model.best_params_))print("{}{}".format("Bset Scores: ",grid_cv_model.best_score_))
并用混淆矩阵来评价一下
# 混淆矩阵def plot_confusion_matrix(y_test,y_pred,title=""): conf_mat=confusion_matrix(y_test,y_pred) conf_mat_normalized=conf_mat.astype("float")/conf_mat.sum(axis=1)[:,np.newaxis] figsize=(22,5) ticksize=18 titlesize=ticksize+8 labelsize=ticksize+5 xlabel="Predicted label" ylabel="True label" params={ "figure.figsize":figsize, "axes.labelsize":labelsize, "axes.titlesize":titlesize, "xtick.labelsize":ticksize, "ytick.labelsize":ticksize} plt.rcParams.update(params) plt.subplot(121) sns.heatmap(conf_mat,annot=True) plt.title(title) plt.xlabel(xlabel) plt.ylabel(ylabel) plt.subplot(122) sns.heatmap(conf_mat_normalized,annot=True) plt.title(title) plt.xlabel(xlabel) plt.ylabel(ylabel) plt.show() print("Confusion Matrix:\n") print(conf_mat) print("\n\nConfusion Matrix Normalized:\n") print(conf_mat_normalized)
终于终于终于才写了一半,好想拆开,这样就能水两篇了。(其实这篇也是来水的)
在本节,将分别用CNN和RNN模型进行操作,准备好了么,让我们出发!
数据集可参照上部分,并没有多大变化,都是驱动力。
a.样本不均衡
我们在上述数据集的观察下,发现样本数据存在不均衡的情况,这里处理一下。
使用sklearn.utils.class_weight样本均衡操作。当我们的数据,有多个类别,每个类别的数据量有很大差距时,这时需要对每个类别的样本做一次均衡,这样会让每个类别的特征都在一定程度上被模型学习。
# 计算各个类别的weightsdef get_weight(y): class_weight_current = cw.compute_class_weight("balanced",np.unique(y),y) return class_weight_currentclass_weight = get_weight(y_train.flatten())
b.文本数据处理
使用分词器Tokenier进行文本数据处理。分词器Tokenizer Tokenizer是一个用于向量化文本,或将文本转换为序列(即单词在字典中的下标构成的列表,从1算起)的类方法
# 分词器Tokenizer Tokenizer是一个用于向量化文本,或将文本转换为序列(即单词在字典中的下标构成的列表,从1算起)的类方法 # fit_on_texts(texts) :texts用于训练的文本列表 # texts_to_sequences(texts):texts待转为序列的文本列表 返回值:序列的列表,列表中的每个序列对应于一段输入文本# 填充序列pad_sequences 将长为nb_smaples的序列转换为(nb_samples,nb_timesteps)2Dnumpy attay.如果提供maxlen,nb_timesteps=maxlen,否则其值为最长序列的长度。# 其它短于该长度的序列都会在后部填充0以达到该长度。长与nb_timesteps的序列会被阶段,以使其匹配该目标长度。#max_words = 1000#max_len = 150max_words = len(set(" ".join(x_train).split()))max_len = x_train.apply(lambda x:len(x)).max()tok = Tokenizer(num_words=max_words)tok.fit_on_texts(x_train)sequences = tok.texts_to_sequences(x_train)sequences_matrix = sequence.pad_sequences(sequences,maxlen=max_len)
c.超参数的设置
ModelCheckpoint:
EarlyStopping:
ReduceLROnPlateau:
print("Setting Callbacks")checkpoint = ModelCheckpoint("model.hdf5", monitor="val_acc", save_best_only=True, mode="max")early_stopping = EarlyStopping(monitor="val_loss", patience=2, verbose=1, restore_best_weights=True, mode="min")reduce_lr = ReduceLROnPlateau(monitor="val_loss", factor=0.6, patience=1, verbose=1, mode="min")callbacks=[checkpoint,early_stopping,reduce_lr]print("Set Callbacks at",date_time(1))
下面,分别定义一个CNN模型和RNN模型,然后进行训练和测试。
a.定义RNN模型
# 定义RNN模型def RNN(): model = Sequential() model.add(Embedding(max_words,50,input_length=max_len)) model.add(LSTM(64)) model.add(Dropout(0.5)) model.add(BatchNormalization()) model.add(Dropout(0.5)) model.add(Dense(256,activation="relu")) model.add(Dropout(0.5)) model.add(BatchNormalization()) model.add(Dropout(0.5)) model.add(Dense(1,activation="sigmoid")) model.summary() return model
给出最后的曲线结果图。
b.定义CNN模型
# 定义CNN模型def CNN(): model=Sequential() model.add(Embedding(max_words,50,input_length=max_len)) model.add(Conv1D(64,3,padding="valid",activation="relu",strides=1)) model.add(GlobalMaxPooling1D()) model.add(Dropout(0.5)) model.add(BatchNormalization()) model.add(Dropout(0.5)) model.add(Dense(256,activation="relu")) model.add(Dropout(0.5)) model.add(BatchNormalization()) model.add(Dropout(0.5)) model.add(Dense(1,activation="sigmoid")) model.summary() return model
效果的话,还是RNN更好一些。
好了,终于写完了,过一阵,再写一个关于音频分类的,最近找音频分类的代码,发现这类代码好少,不过我也不是做这方向,就随意水一水,好不好。
转载地址:http://cegbf.baihongyu.com/