6.使用朴素贝叶斯进行社会媒体挖掘

# -*- coding: utf-8 -*-
"""
Created on Tue Oct  2 07:58:33 2018

@author: asus
"""
#6 使用朴素贝叶斯进行社会媒体挖掘
#朴素贝叶斯算法在计算用于分类的概率时,为简化计算,假定各特征之间是相互独立的,因此名
#字中含有朴素二字。

#6.1 消歧
#文本挖掘的一个难点来自于歧义,消除歧义常被称为消歧。一个词在文中的含义大不相同。
#实验目的,根据消息的内容,判断小西装的Python是不是指编程语言。

#6.1.1 从社交网站下载数据
#网址进不去,从别的地方下载了数据。
import twitter #设置授权令牌
consumer_key = "XXXX" #用户密匙
consumer_secret = "XXXX" #请求令牌
access_token = "XXXX" #这里的访问令牌
access_token_secret = "XXXX" #您的访问令牌在这里是秘密的
authorization = twitter.OAuth(access_token, access_token_secret,
                              consumer_key, consumer_secret)

#将用twitter库提供的搜索函数(search)查找包含单词"Python"的消息。创建阅读器对象,提
#供授权信息连接到Twitter,然后使用阅读器对象进行搜索。
#指定信息的存储位置
import os
import json
out_filename = os.path.join(
        "E:\books\Python数据挖掘入门与实践\使用朴素贝叶斯进行社会媒体挖掘",
        "python_tweets.json")
t = twitter.Twitter(auth=authorization)
#打开输入文件,等待写入数据,追加数据模式"a"。
with open(out_filename, 'a') as output_file:
    search_results = t.search.tweets(q="python", count=100)['statuss']
    for tweet in search_results:
        if 'text' in tweet:
            output_file.write(json.dumps(tweet))
            output_file.write("\n\n")

#6.1.2 加载数据集并对其分类
#完成消息采集后,要对原始数据集里面的消息逐条标注后,才能用于分类任务。
import json
#创建列表,用于存储从文件中读进来的每条信息
tweets = []
#遍历文件中的每一行数据,忽略空行。json.loads将JSON字符串转换为Python对象。
with open("python_tweets.json") as inf:
    for line in inf:
        if len(line.strip()) == 0:
            continue
        tweets.append(json.loads(line))
#我们现在想知道一条消息是否与我们相关(在这里,相关指的是编程语言Python).
#标注结果,保存,以后可直接加载。
tweet_sample = tweets
labels = []
if os.path.exists("python_classes.json"):
    with open("python_classes.json") as inf:
        labels = json.load(inf)
#创建函数,用来返回下一条需要标注的消息。我们找到并返回第一条没有标注类别的信息即可。
def get_next_tweet():
    return tweet_sample[len(labels)]['text']
#接着朱魔术方法,之间嵌入HTML和JavaScript代码,执行时,下面的JavaScript代码必须与魔术
#命令一起执行。
%%javascript
#函数的功能,向labels列表添加一条消息所属的类别。
function set_label(label){
        var kernel = IPython.notebook.kernel;
        kernel.execute("labels.append(" + label + ")");
        load_next_tweet(); #加载吓一跳未标注的消息
}
#回调函数
function load_next_tweet(){
        var code_imput = "get_next_tweet()";
        var kernel = IPython.notebook.kernel;
        var callbacks = { 'iopub' : {'output' : handle_output}};
        kernel.execute(code_input, callbacks, {silent:false});
}
function handle_output(out){
        var res = out.content.data["text/plain"];
        $("div#tweet_text").html(res);
}
#嵌入HTML代码
%%html
<div name="tweetbox">
    Instructions: Click in textbox. Enter a 1 if the tweet is
relevant, enter 0 otherwise.<br>
Tweet: <div id="tweet_text" value="text"></div><br>
<input type=text id="capture"></input><br>
</div>
<script>
$("input#capture").keypress(function(e){
if(e.ehich == 48) {
        set_label(0);
        $("input#capture").val("");
}else if (e.which == 49){
        set_label(1);
        $("input#capture").val("");
  }
});
load_next_tweet();
</script>

with open("python_classes.json", 'w') as outf:
    json.dump(labels, outf)

#6.1.3 Twitter数据集重建
#根据编号下载消息

#6.2 文本转换器
#很多测量方法能够帮上忙。比如,平均词长和平均字长可以用来预测文本的可读性。除此之外,
#还有很多其他类型的特征,比如我没接诶下来用到的单词是否出现。
    
#6.2.1 词袋
#一种最简单却非常搞笑的模型就是指统计数据集中每个单词的出现次数。我们来创建一个矩阵,
#每一行表示数据集中的一篇文档,每一列代表一个词。矩阵中的每一项为某个词在文档中的出现
#次数。
#可以用counter方法统计列表中个字符串出现次数。统计单词时,通常将所有字母转换为小写,
#因此定义字符串时顺便把它转换为小写形式。
s = """Therr ...
""".lower()
words = s.split()
from collections import Counter
c = Counter(words)
c.most_common(5) #输出出现次数最多的前5个词。

#词袋模型主要分为三种:第一章像上面使用词语书籍出现次数作为词频。缺点是当文档差异明显
#时,词频差距会非常大。第二章是使用归一化后的词频。每篇文档中所有词语的词频之和为1。这
#种做法优势明显,它规避了文档长度对词频的影响。第三章,直接使用二值特征来表示——单词在
#文档中出现值为1,不出现值为0。本章使用第三种。

#还有一种更通用的规范化方法叫词频-逆文档频率法(简写tf-idf),该加权方法用词频代替词的
#出现次数,然后用词频除以包含盖茨的文档的数量。

#Python有很多用于处理文本的库,将使用主流的NLTK库抽取特征。scikit-learn提供进行类似
#处理的CountVectorizer类。

#6.2.2 N元语法
#指由几个连续的词组成的子序列。

#6.3 朴素贝叶斯
#朴素贝叶斯概率模型是以贝叶斯统计方法的朴素解释为基础

#我们用C表示某种类别,用D表示数据集中一篇文档来计算贝叶斯公式所要用到的各种统计量,对
#于不好计算的,做出朴素假设,简化计算。
#P(C)为某一类别的概率。
#P(D)为某一文档的概率。朴素假定各个特征之间相互独立。
#P(D|C)为文档D属于C类的概率。

#6.4.1 抽取特征
from sklearn.base import TransformerMixin
from nltk import word_tokenize #对句子进行分词
import nltk
nltk.download('punkt')

class NLTKBOW(TransformerMixin):
    def fit(self, X, y=None):
        return self
    def transform(self, X):
        return[{word: True for word in word_tokenize(document)} 
                for document in X]
#返回结果为一个元素为字典的列表,第一个字典的各项为第一条消息中的所有词语。字典的每一
#项用单词作为键,值为True。

#将字典转换为矩阵
from sklearn.feature_extraction import DictVectorizer
#朴素贝叶斯分类器
from sklearn.naive_bayes import BernoulliNB

#6.4.4 组装起来
#加载消息的内容
import json
tweets = []
with open("python_tweets.json") as inf:
    for line in inf:
        if len(line.strip()) == 0:
            continue
        tweets.append(json.loads(line)['text'])
#加载消息的类别
with open("python_classes.json") as inf:
    labels = json.load(inf)
#创建流水线
from sklearn.pipeline import Pipeline
pipeline = Pipeline([('bag-of-words', NLTKBOW()),
                     ('vectorizer', DictVectorizer()),
                     ('naive-bayes', BernoulliNB())
                     ])
#用F1方法评价模型
from sklearn.cross_validation import cross_val_score 
import numpy as np
scores = cross_val_score(pipeline, tweets, labels, scoring='f1')
print("Score:{:.3f}".format(np.mean(scores)))

#6.4.6 从模型中获取更多有用的特征
model = pipeline.fit(tweets, labels)
nb = model.named_steps['naive-bayes']
#把得到的对数概率数组按照降序排列,找出最有用的特征。
top_features = np.argsort(-feature_probabilities[1])[:50]
dv = model.named_steps['vectorizer']
for i, feature_index in enumerate(top_features):
    print(i, dv.feature_names_[feature_index],
          np.exp(feature_probabilities[1][feature_index]))




  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值