python数据挖掘第三篇-垃圾短信文本分类
数据挖掘第三篇-文本分类
文本分类总体上包括8个步骤。数据探索分析-》数据抽取-》文本预处理-》分词-》去除停用词-》文本向量化表示-》分类器-》模型评估.重要python库包括numpy(数组),pandas(用于处理结构化数据),matplotlib(绘制词云,便于直观表示),sklearn(提供大量分类聚类算法库).
1.数据探索分析
(1)获取大量未经过处理的文档,且标记好文档所属类型。
(2)给各个文档分配唯一的Id,并将之前用文字标记的分类类别用离散数字代替。例如 分类标记为[‘正常短信’,‘垃圾短信’],将其离散表示为[0,1].
(3)将Id,文档内容,标记 作为列,样本个数作为行,将这些文档读入一个数组中。形式为:[ [Id1,content1,label1], ...,[Id_n,content_n,label_n] ]
代码示例:
import pandas as pd
data = pd.read_csv(csv文件名,header=None) # 读入csv文件,不读入列名
data.columns = ['Id','Content','Label']
1.1DataFrame中获取数据的一些方法:
- data.loc[] # 通过字符串索引的方式获取指定行列数据 例如:
data.loc[0:2,'content'] # 获取第0,1,2行的content列 的数据,【注意】:0:2获取的是0,1,2行,这一点和一般的切片不相同
data.loc[[0,2],['content','label']] # 通过列表指定行列 - data.iloc[] # 通过数字索引方式,用法和数组的一模一样
data['label'] # 获取label列的数据,结果是一维数组
data[['content','label']] # 结果是 content,label列的所有数据1.2统计不同label出现频率,绘制饼图
data['label'].value_counts() # 获取label这一列数据中各个标记出现次数,结果以series的形式返回
1.2.1绘制饼图
num=data['label'].value_counts()
import matplotlib.pyplot as plt
plt.figure(figsize=(3,3)) # 将画布设置为3*3的正方形
plt.pie(num,labels=['正常','垃圾']) # 绘制饼图,num是一个series ,series是一个带索引的数组,和字典使用类似。
plt.show()
2.数据抽取
当不同标记的比例不平衡时,需要分层抽样,例如0标记出现72000次,而1标记出现8000次,则此时会产生模型偷懒问题。
data_normal = data.loc[data['label']==1].sample(1000,random_state=123) #在label为1的所有数据里挑选1000个随机样本
data_bad = data.loc[data['label']==0].sample(1000,random_state=123) #在label为0的所有数据里挑选1000个随机样本
data_new = pd.contat([data_normal,data_bad],axis=0) # 默认行拼接,所以axis可不写
3.文本预处理
如下图所示,content一项中包含了xxx,以及一些特殊编码字符,以及逗号句号等等的标点符号,这些东西都是无意义字符,需要删除掉
删除这些特殊非中文字符,需要用到正则表达式,正则表达式是爬虫中必不可少的一个知识点,是一个条件表达式,用这个构造的条件表达式所指定的规则在一个指定字符串中检索匹配出符合规则的句子。
import re
afterDeleteSpecialWord=data_new['content'].apply(lambda x:re.sub('[^\u4E00-\u9FD5]+','',string))
这里的apply表示对这个series数组中的每一个元素(即文档的内容字符串)都执行这个匿名函数x,string是传进来的参数,re.sub 表示 将前面指定的正则表达式'[^\u4E00-\u9FD5]+'所匹配的字符串(即非中文特殊字符)用''代替。这里的正则表达式'[^\u4E00-\u9FD5]+':
[]是一个原子列表,^表示非,\u4E00-\u9FD5中文字符的正则表示,前面加上^则表示非中文字符,[]+表示这个原子列表中的字符可以匹配1次或多次。具体正则表达式的用法网上资源很多,这里不详细解释.
处理完后,标点符号,以及特殊字符都不见了,如下所示:
4.分词,去除停用词
第一步先将之前的content中的内容进行分词,分词后content列的元素是一个列表,比如之前的content列中的元素'我来到北京清华大学计算机学院',执行分词后结果为:['我','来到','北京','清华大学','计算机','学院']
第二步是去除停用词,首先加载停用词文件,里面存储了N个停用词,然后对第一步中的分词结果进行去除存在于停用词列表中的词.
代码如下:
import jieba # 分词库
with open('stopList.txt','r') as f:
stop=f.read() # 获取的结果是一个大的字符串,其中换行符之类的特殊字符也存在于其中
stop = stop.split() # 按照空格,换行符进行分割,获取停用词列表
stop = [' ']+stop # 由于之前的stop里没有空格,而空格是停用词,所以重新加回空格
jieba.load_userdic(path) # 加载指定路径path里的用户自定义词典
after_segement = afterDeleteSpecialWord.apply(jieba.lcut) # 进行分词
data_after = after_segement.apply(lambda x:[i for i in x if i not in stop]) # 去除停用词
4.1绘制词云
绘制词云是文本分类里对词频的一个直观图像表示,以图像形式呈现,频率高的词汇字体更大,频率小的,字体小。
import matplotlib.pyplot as plt # 画图工具
from wordcloud import WordCloud # 词云工具库
import itertools # 将二维数据压缩为一维数据
pic = plt.imread(picturePath) # 这里picturePath为具体图片所在路径,这里没有指定.这行代码是加载画板的一个背景图片
'''
wc = WordCloud(font_path=r'C:\Windows\Fonts\字体名称',background_color='white',mask=pic) # 生成一个词云对象 ,windows系统中的字体存放在c盘Windows文件夹下的Fonts文件夹中。因为这里统计的都是中文,所以不要选英文字体,而是选择中文字体,右键,属性,如图,为具体的字体名称 '''
num = pd.Series(list(itertools.chain(*list(data_after)))).value_counts() # 统计词频
wc.fit_words(num) # 将统计好的词频放进去
plt.imshow(wc)
plt.show()
文本向量化表示
文本向量化表示的含义为:由于我们目前得到的是一个分词结果,是中文,而计算机不能直接将中文作为分类的输入数据,必须将其用数字来表示,那么如何将一个文档用一个数字化的向量表示呢,这就是文本向量化。
常用的向量化表示有词袋模型,词频,TF-IDF,以及考虑上下文的词嵌入。
词袋模型是指,一个文档中出现了的词则该词置1,词库中其他词置0,而不考虑出现次数的多少。一个文档则可以表示成一个N维的0,1向量,N的大小取决于词库的大小。
词频:在词袋模型的基础上,考虑出现词的次数,而不是只要出现了就是1。
TF-IDF:考虑一个词的词频以及逆文档频率,逆文档频率是指该词在所有文档里的稀有程度,该词在所有文档里出现的文档数越少,则该词越稀有,区分度就越高,逆文档频率就越高,逆文档频率=log(所有文档数/(出现该词的文档数+1)),而TF-IDF则=TF*IDF。
在sklearn 中的feature_extraction.text包中有CountVectorizer,TfidfVectorizer直接可以做文本向量化工作,一个是根据词频,一个是TF-IDF。
tmp = data_after.apply(lambda x:' '.join(x)) # 由于谷歌开发的向量化工具仅支持按空格统计,所以之前的列表存放的单词需要转换成一个以空格分隔开的一个大字符串。
cv=CountVectorizer().fit(tmp) # 加载字典,以及需要向量化的文本数据
vector_data = cv.transform(tmp) # 向量化,结果是一个迭代器
vector_array = vector_data.toarray() # 将迭代器转为数组
文本分类
接下来的步骤和一般机器学习分类问题是一模一样的,不多做介绍。已经得到结构化数据vector_array,以及相应的标签label,可以用sklearn的各种训练模型进行训练,测试,模型评估等等。
python数据挖掘第三篇-垃圾短信文本分类的更多相关文章
- 使用Python 2.7实现的垃圾短信识别器
最近参加比赛,写了一个垃圾短信识别器,在这里做一下记录. 官方提供的数据是csv文件,其中训练集有80万条数据,测试集有20万条数据,训练集的格式为:行号 标记(0为普通短信,1为垃圾短信) 短信内容 ...
- python实现摇骰子猜大小函数升级没把加注及三大运行商短信验证过滤
摇骰子游戏升级 此次更改增加下注功能,启动资金1000元,每次赔率都是一倍,钱输光退出. 源码: #!/user/bin/env python #-*-coding:utf-8 -*- #Author ...
- 利用python库twilio来免费发送短信
大家好,我是四毛,最近开通了个人公众号“用Python来编程”,欢迎大家“关注”,这样您就可以收到优质的文章了. 今天跟大家分享的主题是利用python库twilio来免费发送短信. 先放一张成品图 ...
- 新出台的治理iMessage垃圾短信的规则
工信部拟制定<通信短信息服务管理规定>,为治理垃圾短信提供执法根据.当中,对于苹果iMessage垃圾信息泛滥现象,工信部也将跟踪研究技术监測和防范手段.这意味着长期以来处于监管" ...
- ML.NET 示例:二元分类之垃圾短信检测
写在前面 准备近期将微软的machinelearning-samples翻译成中文,水平有限,如有错漏,请大家多多指正. 如果有朋友对此感兴趣,可以加入我:https://github.com/fei ...
- [Python笔记]第三篇:深浅拷贝、函数
本篇主要内容:深浅拷贝,自定义函数,三目运算,lambda表达式, 深浅拷贝 一.数字和字符串 对于 数字 和 字符串 而言,赋值.浅拷贝和深拷贝无意义,因为其永远指向同一个内存地址. import ...
- python 【第三篇】:函数及参数
函数背景 在学习函数之前,一直遵循:面向过程编程: 根据业务逻辑从上到下实现功能,其往往用一长段代码来实现指定功能,开发过程中最常见的操作就是粘贴复制,也就是将之前实现的代码块复制到现需功能处,如下: ...
- 用python twilio模块实现发手机短信的功能
前排提示:这个模块不是用于对陌生人进行短信轰炸和电话骚扰的,这个模块也没有这个功能,如果是抱着这个心态来的,可以关闭网页了 语言:python 步骤一:安装twilio模块 pip install t ...
- 短信文本pdu模式解析
来源于互联网 年代较长 如有侵犯 请联系删除 text模式主要发送字符集(有限的),不能用来发送中文,但是hex moder可以发送所有字符. pdu moder被所有手机支持,主要分为7bit 8b ...
随机推荐
- PHP基于Redis实现轻量级延迟队列
延迟队列,顾名思义它是一种带有延迟功能的消息队列. 那么,是在什么场景下我才需要这样的队列呢? 一.背景 先看看一下业务场景: 1.会员过期前3天发送召回通知 2.订单支付成功后,5分钟后检测下游环节 ...
- Python下定义输出日志
# 话不多说,直接看代码,,, # -*- coding:UTF-8 -*- # python version: 2.7.15 #脚本名, 日志名,日志路径 import os import sys ...
- 【10分钟学Spring】:(一)初识Spring框架
简介 Spring是一个轻量级的企业级的Java开发框架.主要是用来替代原来更加重量级的企业级Java技术,比如EJB(Enterprise JavaBean).Java数据对象(Java Data ...
- KNN学习笔记
简单地说,KNN算法就是通过测量不同特征值之间的距离来对特征进行分类的一种算法. 优点:精度高.对异常值不敏感.无数据输入假定. 缺点:计算复杂度高.空间复杂度高. 适用数据范围:数值型和标称型. 工 ...
- Python基础之第三方库gevent安装
安装gevent库: 想要安装gevent库,我们需要确定pip版本: 使用 pip3 list: 我们可以发现pip版本为19.3.1,如果你们的pip版本不是最新版可以使用命令python -m ...
- JavaEE基础(02):Servlet核心API用法详解
本文源码:GitHub·点这里 || GitEE·点这里 一.核心API简介 1.Servlet执行流程 Servlet是JavaWeb的三大组件之一(Servlet.Filter.Listener) ...
- std::unique_ptr的用法
std::ofstream("demo.txt") << 'x'; // 准备要读的文件 { std::unique_ptr<std::FILE, decltyp ...
- luogu P3939 数颜色 |vector
题目描述 小 C 的兔子不是雪白的,而是五彩缤纷的.每只兔子都有一种颜色,不同的兔子可能有 相同的颜色.小 C 把她标号从 1 到 n 的 n 只兔子排成长长的一排,来给他们喂胡萝卜吃. 排列完成后, ...
- luogu P1327 数列排序
题目描述 给定一个数列{an},这个数列满足ai≠aj(i≠j),现在要求你把这个数列从小到大排序,每次允许你交换其中任意一对数,请问最少需要几次交换? 输入格式 第一行,正整数n (n<=10 ...
- MongoDB第三天(正则,管道,聚合,字符串,算术,日期,java连接MongoDB)
部分正则表达式: i:忽略大小写 m:多行查找 x:设置 x 选项后,正则表达式中的非转义的空白字符将被忽略. s:允许点字符(即.)匹配包括换行符在内的所有字符. w:匹配包括下划线的任何单词字 ...