0%

Python数据科学_16_案例:垃圾短信识别【简单自然语言处理】

1
import pandas as pd

数据读取

1
data = pd.read_csv('message80W1.csv', header=None, index_col=0)
1
data.columns = ['类别', '文本内容']
1
data.head()

数据集下载

类别 文本内容
0
1 0 商业秘密的秘密性那是维系其商业价值和垄断地位的前提条件之一
2 1 南口阿玛施新春第一批限量春装到店啦   春暖花开淑女裙、冰蓝色公主衫 ...
3 0 带给我们大常州一场壮观的视觉盛宴
4 0 有原因不明的泌尿系统结石等
5 0 23年从盐城拉回来的麻麻的嫁妆
1
data.shape
(800000, 2)

数据探索

查看数据分布

1
data['类别'].value_counts()
0    720000
1     80000
Name: 类别, dtype: int64
  1. 数据集太大,不便于模型的训练,需要简化数据
  2. 数据集类别不平衡,非垃圾短信占90%

查看数据集的缺失值情况

1
data.isna().sum()
类别      0
文本内容    0
dtype: int64

无缺失值

查看数据集是否有重复值

1
data.shape
(800000, 2)
1
data.drop_duplicates().shape
(786576, 2)

存在大量重复数据

查看垃圾短信的具体内容

1
data['文本内容'][:10]
0
1                         商业秘密的秘密性那是维系其商业价值和垄断地位的前提条件之一
2     南口阿玛施新春第一批限量春装到店啦         春暖花开淑女裙、冰蓝色公主衫  ...
3                                      带给我们大常州一场壮观的视觉盛宴
4                                         有原因不明的泌尿系统结石等
5                                       23年从盐城拉回来的麻麻的嫁妆
6                                         感到自减肥、跳减肥健美操、
7     感谢致电杭州萧山全金釜韩国烧烤店,本店位于金城路xxx号。韩式烧烤等,价格实惠、欢迎惠顾【全...
8                                 这款UVe智能杀菌机器人是扫地机的最佳伴侣
9     一次价值xxx元王牌项目;可充值xxx元店内项目卡一张;可以参与V动好生活百分百抽奖机会一次...
10                                     此类皮肤特别容易招惹粉刺、黑头等
Name: 文本内容, dtype: object

文本中存在大量的空格和x序列,这些x序列可能表示各种各样的意义。

  1. 表示电话号码、银行卡号、姓名、地名等比较隐私的数据
  2. 表示价格、时间等数据

    采取删除空格和x字符处理

数据预处理

重复值处理

1
data.drop_duplicates(inplace=True)
1
data.shape
(786576, 2)

删除空字符和x序列

1
2
3
4
5
6
7
8
def delete_space(str_):
str_ = str_.replace(' ', '')\
.replace('\ue310', '')\
.replace('\t', '')\
.replace('\ue006', '')\
.replace('\ue319', '')\
.replace('x', '')
return str_
1
data['文本内容'] = data['文本内容'].apply(delete_space)
1
data.head(10)
类别 文本内容
0
1 0 商业秘密的秘密性那是维系其商业价值和垄断地位的前提条件之一
2 1 南口阿玛施新春第一批限量春装到店啦春暖花开淑女裙、冰蓝色公主衫气质粉小西装、冰丝女王长半裙、皇
3 0 带给我们大常州一场壮观的视觉盛宴
4 0 有原因不明的泌尿系统结石等
5 0 23年从盐城拉回来的麻麻的嫁妆
6 0 感到自减肥、跳减肥健美操、
7 1 感谢致电杭州萧山全金釜韩国烧烤店,本店位于金城路号。韩式烧烤等,价格实惠、欢迎惠顾【全金釜韩...
8 0 这款UVe智能杀菌机器人是扫地机的最佳伴侣
9 1 一次价值元王牌项目;可充值元店内项目卡一张;可以参与V动好生活百分百抽奖机会一次!预约电话:
10 0 此类皮肤特别容易招惹粉刺、黑头等

类别均衡化

由于原始数据的类别非常不平衡,所以需要将其处理成垃圾短信和非垃圾短信数量一样的样本

采用的方法是在垃圾短信和非垃圾短信中各抽取1W条,作为样本

1
data['类别'].value_counts()
0    707452
1     79124
Name: 类别, dtype: int64
1
2
data0 = data[data['类别'] == 0].sample(10000)
data1 = data[data['类别'] == 1].sample(10000)
1
new_data = data0.append(data1)
1
new_data.head()
类别 文本内容
0
416852 0 一大波眼镜娘高能袭来你的菜吗
112013 0 微软Xbo欧洲部75%的员工也将卷铺盖走人
546066 0 84909超气质防晒蕾丝花朵网纱系腰带上衣¥119
780143 0 政府官员的悲哀/中国又立功苹果AppStore7月销售额超17亿美元
546893 0 第27届广州番禺莲花山旅游文化节昨日开幕

分词和去停用词

1
import jieba
1
str1 = '今天星期五,明天中秋节/教师节。'
1
jieba.lcut(str1)
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\ming_log\AppData\Local\Temp\jieba.cache
Loading model cost 0.952 seconds.
Prefix dict has been built successfully.





['今天', '星期五', ',', '明天', '中秋节', '/', '教师节', '。']
1
2
3
4
# 读取停用词典
with open('stopword.txt', 'r') as f:
data = f.readlines()
data = [i.strip() for i in data]
1
2
3
4
5
6
7
8
9
10
11
12
# 读取停用词典
with open('stopword.txt', 'r') as f:
data = f.readlines()
# 去除停用词典后面的换行符
data = [i.strip() for i in data]

def cut_message(str_):
# 分词
res = jieba.lcut(str_)
# 去停用词
res = [i for i in res if i not in data]
return res
1
new_data['切分结果'] = new_data['文本内容'].apply(cut_message)
1
2
# 使用空格将分词后的结果拼接起来
new_data['拼接结果'] = new_data['切分结果'].apply(lambda x: ' '.join(x))

分离训练集和测试集

1
2
x = new_data.iloc[:, -1]
y = new_data['类别']
1
2
3
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2)
1
2
print(x_train.shape)
print(x_test.shape)
(16000,)
(4000,)

绘制词云图

1
from wordcloud import WordCloud

将所有的词语放入一个列表中

1
2
all_words = []
_ = [all_words.extend(i) for i in new_data['切分结果']]

统计词频

1
2
from collections import Counter
import matplotlib.pyplot as plt
1
count_word = Counter(all_words)

绘制词云图

1
2
3
4
5
6
7
8
9
# 导入词云模板
mask = plt.imread('duihuakuang.jpg')

# 创建词云图
wc = WordCloud(mask=mask,
background_color='white',
font_path=r'C:\Windows\Fonts\simhei.ttf',
max_font_size=100,
max_words=300)
1
2
# 训练词云图
wc.fit_words(count_word)
<wordcloud.wordcloud.WordCloud at 0x193c34402e0>
1
2
3
4
5
6
7
8
# 绘制词云图
import matplotlib.pyplot as plt

plt.figure(figsize=(5,5), dpi=500)
# 删除坐标轴
plt.axis('off')
plt.imshow(wc)
plt.show()

output_55_0_202303092119

文本数据序列化

词袋模型

1
2
3
4
5
6
7
# '今天', '星期五', ',', '明天', '中秋节', '/', '教师节', '。
# 今天:0
# 星期五:1
# 明天:2
# 中秋节:3
# 教师节:4
# 原数据序列化结果:0,1,2,3,4
1
from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer
1
2
3
4
5
# 构建词袋模型
# max_features: 最大特征数,默认为None表示无最大数量限制
countVectorizer = CountVectorizer(max_features=10000)
# 训练词袋模型
x_train = countVectorizer.fit_transform(x_train)

利用词袋模型将数据集转化为TFIDF值

1
2
# 使用词袋模型将数据转化为TFIDF值
X_tr = TfidfTransformer().fit_transform(x_train.toarray()).toarray()
1
2
x_test = CountVectorizer(vocabulary=countVectorizer.vocabulary_).fit_transform(x_test)
X_te = TfidfTransformer().fit_transform(x_test.toarray()).toarray()

模型的训练和测试

1
from sklearn.naive_bayes import GaussianNB
1
model = GaussianNB()
1
model.fit(X_tr, y_train)
GaussianNB()
1
model.score(X_te, y_test)
0.93325
-------------本文结束感谢您的阅读-------------