快乐学习
前程无忧、中华英才非你莫属!

Python数据分析实战5

第五课、 比较多项式和高斯朴素贝叶斯

# read the data
import pandas as pd
url = 'https://archive.ics.uci.edu/ml/machine-learning-databases/pima-indians-diabetes/pima-indians-diabetes.data';;
col_names = ['pregnant', 'glucose', 'bp', 'skin', 'insulin', 'bmi', 'pedigree', 'age', 'label']
pima = pd.read_csv(url, header=None, names=col_names)

#注意所有功能都是连续的
pima.head()

# 创建X和Y.
X = pima.drop('label', axis=1)
y = pima.label

# 分成训练和测试集
from sklearn.cross_validation import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)

# 导入多项式和高斯朴素贝叶斯
from sklearn.naive_bayes import MultinomialNB, GaussianNB
from sklearn import metrics

# 多项式朴素贝叶斯检验的准确性
mnb = MultinomialNB()
mnb.fit(X_train, y_train)
y_pred_class = mnb.predict(X_test)
print metrics.accuracy_score(y_test, y_pred_class)

# 高斯朴素贝叶斯检验的准确性
gnb = GaussianNB()
gnb.fit(X_train, y_train)
y_pred_class = gnb.predict(X_test)
print metrics.accuracy_score(y_test, y_pred_class)

#**结论:**将朴素贝叶斯分类应用于具有**连续特征**的数据集时,最好使用高斯朴素贝叶斯比多项朴素贝叶斯。
# 后者适用于包含**离散特征**(例如,字数)的数据集。

第六课、自然语言处理(NLP)

#NLP需要理解**语言**和**世界**。
###第一部分:阅读Yelp评论
# - “语料库”=文件的集合
# - “corpora”= corpu的复数形式s

import pandas as pd
import numpy as np
import scipy as sp
from sklearn.cross_validation import train_test_split
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.linear_model import LogisticRegression
from sklearn import metrics
from textblob import TextBlob, Word
from nltk.stem.snowball import SnowballStemmer

# 将yelp.csv读入DataFrame
url = 'https://raw.githubusercontent.com/justmarkham/DAT8/master/data/yelp.csv';;
yelp = pd.read_csv(url)

# 创建一个只包含五星评论和一星评论的新数据框
yelp_best_worst = yelp[(yelp.stars == 5) | (yelp.stars == 1)]

# 定义X和y
X = yelp_best_worst.text
y = yelp_best_worst.stars

# 将新的DataFrame分成训练和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)

###第2部分:令牌化

# - **什么:**将文本分成单词,如句子或单词
# - **为什么:**给以前非结构化文本的结构
# - **备注:**英文文本比较容易,一些语言不容易

#使用CountVectorizer从X_train和X_test创建文档项矩阵
vect = CountVectorizer()
X_train_dtm = vect.fit_transform(X_train)
X_test_dtm = vect.transform(X_test)

# 行是文档,列是术语(又名“令牌”或“功能”)
X_train_dtm.shape

# 最后50个功能
print vect.get_feature_names()[-50:]

#显示矢量选项
vect

# - **小写:**布尔值,默认为true
# - 在标记之前将所有字符转换为小写。

# 不要转换为小写
vect = CountVectorizer(lowercase=False)
X_train_dtm = vect.fit_transform(X_train)
X_train_dtm.shape

# - ** ngram_range:**元组(min_n,max_n)
# - 要提取的不同n-gram的n值范围的下限和上限。 将使用n的所有值,使得min_n <= n <= max_n。
#包括1克和2克

vect = CountVectorizer(ngram_range=(1, 2))
X_train_dtm = vect.fit_transform(X_train)
X_train_dtm.shape

# 最后50个功能
print vect.get_feature_names()[-50:]

#**预测星级评分:**

#使用CountVectorizer的默认选项
vect = CountVectorizer()

# 创建文档术语矩阵
X_train_dtm = vect.fit_transform(X_train)
X_test_dtm = vect.transform(X_test)

# 使用朴素贝叶斯来预测星级
nb = MultinomialNB()
nb.fit(X_train_dtm, y_train)
y_pred_class = nb.predict(X_test_dtm)

# 计算准确度
print metrics.accuracy_score(y_test, y_pred_class)

# 计算零准确度
y_test_binary = np.where(y_test == 5, 1, 0)
max(y_test_binary.mean(), 1 - y_test_binary.mean())

# 定义一个接受向量的函数并计算精度
def tokenize_test(vect):
    X_train_dtm = vect.fit_transform(X_train)
    print 'Features: ', X_train_dtm.shape[1]
    X_test_dtm = vect.transform(X_test)
    nb = MultinomialNB()
    nb.fit(X_train_dtm, y_train)
    y_pred_class = nb.predict(X_test_dtm)
    print 'Accuracy: ', metrics.accuracy_score(y_test, y_pred_class)

# 包括1克和2克
vect = CountVectorizer(ngram_range=(1, 2))
tokenize_test(vect)

##第3部分:停用词删除
# - **什么:**删除可能出现在任何文本中的常见词汇
# - **为什么:**他们没有告诉你很多关于你的文字
#show vectorizer选项

vect

# - ** stop_words:** string {'english'},列表或None(默认)
# - 如果是英文,则使用英文的内置停用词表。
# - 如果一个列表,假设该列表包含停用词,所有这些都将从结果标记中删除。
# - 如果没有,则不会使用停用词。 可以将max_df设置为[0.7,1.0]范围内的一个值,以便根据术语内部语料文档的频率自动检测并过滤停用词。
# 删除英文停用词
vect = CountVectorizer(stop_words='english')
tokenize_test(vect)

# 停止词的集合
print vect.get_stop_words()

###第4部分:其他CountVectorizer选项

# - ** max_features:** int或None,default = None
# - 如果不是None,建立一个词汇表,只考虑整个语料库中词频排序的顶级max_features。
#删除英文停用词,只保留100个功能
vect = CountVectorizer(stop_words='english', max_features=100)
tokenize_test(vect)

#全部100个功能
print vect.get_feature_names()

# 包括1克和2克,并限制功能的数量
vect = CountVectorizer(ngram_range=(1, 2), max_features=100000)
tokenize_test(vect)

#  - ** min_df:**浮动范围[0.0,1.0]或int,默认= 1
#  - 建立词汇表时忽略文档频率严格低于给定阈值的词汇。 这个值在文献中也被称为切断。 如果是浮点数,则该参数表示文档的一个比例,即整数绝对计数。
#
# 包括1克和2克,只包括出现至少2次的术语
vect = CountVectorizer(ngram_range=(1, 2), min_df=2)
tokenize_test(vect)

##第5部分:TextBlob简介

#TextBlob:“简体文字处理”
#打印第一个评论
print yelp_best_worst.text[0]

# 将其另存为TextBlob对象
# curl https://raw.github.com/sloria/TextBlob/master/download_corpora.py | python
#python -m textblob.download_corpora 安装语料库
review = TextBlob(yelp_best_worst.text[0])

#列出单词
review.words

# 列出句子
review.sentences

# 一些字符串方法可用
review.lower()

###第6部分:词干和词形化
# #**词干:**
#  - **什么:**减少一个词的基础/干/根的形式
#  - **为什么:**以相同的方式处理相关的词常常是有意义的
#  - **备注:**
#  - 使用“简单”和快速的基于规则的方法
#  - 词干通常不会显示给用户(用于分析/索引)
#  - 一些搜索引擎将同词干的单词视为同义词
#
# #初始化stemmer
stemmer = SnowballStemmer('english')

# 干每个字
print [stemmer.stem(word) for word in review.words]

# **词形化**
# - **什么:**推导一个单词的规范形式(“引理”)
# - **为什么:**可以比干扰更好
# - **注释:**使用基于字典的方法(比词干慢)
# #假设每个单词都是一个名词
print [word.lemmatize() for word in review.words]

# 假定每个单词都是动词
print [word.lemmatize(pos='v') for word in review.words]

# 定义一个接受文本并返回引理列表的函数
def split_into_lemmas(text):
    text = unicode(text, 'utf-8').lower()
    words = TextBlob(text).words
    return [word.lemmatize() for word in words]

#使用split_into_lemmas作为特征提取功能(WARNING:SLOW!)
vect = CountVectorizer(analyzer=split_into_lemmas)
tokenize_test(vect)

# 最后50个功能
print vect.get_feature_names()[-50:]

###第7部分:术语频率逆文档频率(TF-IDF)

# - **什么:**计算一个单词出现在文档中的“相对频率”,而不是所有文档的频率
# - **为什么:**比“词频”更有用于识别每个文档中的“重要”单词(该文档中频率高,其他文档中频率低)
# - **备注:**用于搜索引擎评分,文字摘要,文档聚类

# 示例文档
simple_train = ['call you tonight', 'Call me a cab', 'please call me... PLEASE!']

# 术语频率
vect = CountVectorizer()
tf = pd.DataFrame(vect.fit_transform(simple_train).toarray(), columns=vect.get_feature_names())
tf

#文档频率
vect = CountVectorizer(binary=True)
df = vect.fit_transform(simple_train).toarray().sum(axis=0)
pd.DataFrame(df.reshape(1, 6), columns=vect.get_feature_names())

# 术语频率反向文档频率(简单版本)
tf / df

# TfidfVectorizer
vect = TfidfVectorizer()
pd.DataFrame(vect.fit_transform(simple_train).toarray(), columns=vect.get_feature_names())

#**更多细节:** [TF-IDF是关于什么的](http://planspace.org/20150524-tfidf_is_about_what_matters/)

###第8部分:使用TF-IDF总结Yelp评论
#Reddit的autotldr使用基于TF-IDF的[SMMRY](http://smmry.com/about)算法!

# 使用TF-IDF创建一个文档项矩阵
vect = TfidfVectorizer(stop_words='english')
dtm = vect.fit_transform(yelp.text)
features = vect.get_feature_names()
dtm.shape

def summarize():
    #选择一个至少300个字符的随机评论
    review_length = 0
    while review_length < 300:
        review_id = np.random.randint(0, len(yelp))
        review_text = unicode(yelp.text[review_id], 'utf-8')
        review_length = len(review_text)

    # 创建一个单词字典和他们的TF-IDF分数
    word_scores = {}
    for word in TextBlob(review_text).words:
        word = word.lower()
        if word in features:
            word_scores[word] = dtm[review_id, features.index(word)]

    # 打印前5名TF-IDF分数的单词
    print 'TOP SCORING WORDS:'
    top_scores = sorted(word_scores.items(), key=lambda x: x[1], reverse=True)[:5]
    for word, score in top_scores:
        print word

    # 随机打印5个单词
    print '\n' + 'RANDOM WORDS:'
    random_words = np.random.choice(word_scores.keys(), size=5, replace=False)
    for word in random_words:
        print word

    # 打印评论
    print '\n' + review_text

summarize()

# ## 第九部分:情感分析

print review

# 极性范围从-1(最负)到1(最正)
review.sentiment.polarity

# 了解应用方法
yelp['length'] = yelp.text.apply(len)
yelp.head(1)

# 定义一个接受文本并返回极性的函数
def detect_sentiment(text):
    return TextBlob(text.decode('utf-8')).sentiment.polarity

# 为情绪创建一个新的DataFrame列(WARNING:SLOW!)
yelp['sentiment'] = yelp.text.apply(detect_sentiment)

# 按星星分组的情节盒情节
yelp.boxplot(column='sentiment', by='stars')

# 评论与最积极的情绪
yelp[yelp.sentiment == 1].text.head()

# 评论与最消极的情绪
yelp[yelp.sentiment == -1].text.head()

# 扩大列显示
pd.set_option('max_colwidth', 500)

# 5星评论中的负面情绪
yelp[(yelp.stars == 5) & (yelp.sentiment < -0.3)].head(1)

# 积极的情绪在一星评论
yelp[(yelp.stars == 1) & (yelp.sentiment > 0.5)].head(1)

# 重置列显示宽度
pd.reset_option('max_colwidth')

###奖金:将特征添加到文档术语矩阵

#创建一个仅包含5星评论和1星评论的DataFrame
yelp_best_worst = yelp[(yelp.stars == 5) | (yelp.stars == 1)]

# 定义X和y
feature_cols = ['text', 'sentiment', 'cool', 'useful', 'funny']
X = yelp_best_worst[feature_cols]
y = yelp_best_worst.stars

# 分成训练和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=1)

# 仅使用带有文本列的CountVectorizer
vect = CountVectorizer()
X_train_dtm = vect.fit_transform(X_train.text)
X_test_dtm = vect.transform(X_test.text)
print X_train_dtm.shape
print X_test_dtm.shape

# 其他四个特征栏的形状
X_train.drop('text', axis=1).shape

# 将其他特征列转换为浮点并转换为稀疏矩阵
extra = sp.sparse.csr_matrix(X_train.drop('text', axis=1).astype(float))
extra.shape

# 组合稀疏矩阵
X_train_dtm_extra = sp.sparse.hstack((X_train_dtm, extra))
X_train_dtm_extra.shape

# 重复测试设置
extra = sp.sparse.csr_matrix(X_test.drop('text', axis=1).astype(float))
X_test_dtm_extra = sp.sparse.hstack((X_test_dtm, extra))
X_test_dtm_extra.shape

# 仅使用文本列进行逻辑回归
logreg = LogisticRegression(C=1e9)
logreg.fit(X_train_dtm, y_train)
y_pred_class = logreg.predict(X_test_dtm)
print metrics.accuracy_score(y_test, y_pred_class)

# 使用具有所有特征的逻辑回归
logreg = LogisticRegression(C=1e9)
logreg.fit(X_train_dtm_extra, y_train)
y_pred_class = logreg.predict(X_test_dtm_extra)
print metrics.accuracy_score(y_test, y_pred_class)

# ##奖金:有趣的TextBlob功能

# 拼写更正
TextBlob('15 minuets late').correct()

# 拼写检查
Word('parot').spellcheck()

# 定义
Word('bank').define('v')

# 语言识别
a = TextBlob('Hola amigos').detect_language()
a

###结论
#NLP是一个巨大的领域
# - 了解基础知识将扩大您可以使用的数据类型
# - 简单的技术有很长的路要走
# - 尽可能使用scikit-learn来进行NLP

第七课、用自行车数据进行练习

import pandas as pd
import numpy as np
from sklearn.cross_validation import cross_val_score
from sklearn.linear_model import LinearRegression
from sklearn.tree import DecisionTreeRegressor, export_graphviz

# 读取数据并设置“datetime”作为索引
url = 'https://raw.githubusercontent.com/justmarkham/DAT8/master/data/bikeshare.csv';;
bikes = pd.read_csv(url, index_col='datetime', parse_dates=True)

# “count”是一种方法,所以最好重命名该列
bikes.rename(columns={'count':'total'}, inplace=True)

# 创建“小时”作为自己的功能
bikes['hour'] = bikes.index.hour

bikes.head()

bikes.tail()

# ## 任务1
#运行这两个`groupby`语句,并找出他们告诉你的数据。
#“每日工作日”的平均租金
bikes.groupby('workingday').total.mean()

# 每个“小时”值的平均租金
bikes.groupby('hour').total.mean()

###任务2
#运行这个绘图代码,并确保你了解输出。 然后,把这个情节分成两个独立的情节,以“工作日”为条件。 (换句话说,一个小区应显示“workingday = 0”的小时趋势,另一个应显示“workingday = 1”的小时趋势。)

#平均租金为“小时”的每个值
bikes.groupby('hour').total.mean().plot()

# “工作日= 0”的小时租金趋势
bikes[bikes.workingday==0].groupby('hour').total.mean().plot()

# “工作日= 1”每小时租金趋势
bikes[bikes.workingday==1].groupby('hour').total.mean().plot()

# 结合这两块地块
bikes.groupby(['hour', 'workingday']).total.mean().unstack().plot()

###任务3
#使用“total”作为响应,“hour”和“workingday”作为唯一的特征,将线性回归模型拟合到整个数据集中。 然后,打印系数并解释它们。 在这种情况下线性回归的局限性是什么?
#创建X和Y
feature_cols = ['hour', 'workingday']
X = bikes[feature_cols]
y = bikes.total

# 拟合线性回归模型并打印系数
linreg = LinearRegression()
linreg.fit(X, y)
linreg.coef_

###任务4

#使用10倍交叉验证来计算线性回归模型的RMSE。

#保存10个由cross_val_score输出的MSE分数
scores = cross_val_score(linreg, X, y, cv=10, scoring='neg_mean_squared_error')

# 将MSE转换为RMSE,然后计算10个RMSE分数的均值
np.mean(np.sqrt(-scores))

###任务5
#使用10倍交叉验证来评估具有相同功能的决策树模型(适合您选择的任何“max_depth”)。
#用“max_depth = 7”评估决策树模型

treereg = DecisionTreeRegressor(max_depth=7, random_state=1)
scores = cross_val_score(treereg, X, y, cv=10, scoring='neg_mean_squared_error')
np.mean(np.sqrt(-scores))

###任务6
#使用“max_depth = 3”将决策树模型拟合到整个数据集中,并使用Graphviz创建树图。 然后,找出每个叶代表什么。 决策树学到一个线性回归模型不能学习的是什么?
#用“max_depth = 3”来拟合决策树模型
treereg = DecisionTreeRegressor(max_depth=3, random_state=1)
treereg.fit(X, y)

# 创建一个Graphviz文件
export_graphviz(treereg, out_file='tree_bikeshare.dot', feature_names=feature_cols)

#在命令行运行这个转换为PNG:
#dot -Tpng tree_bikeshare.dot -o tree_bikeshare.pn
#![自行车数据树](images / tree_bikeshare.png)
打赏
赞(0) 打赏
未经允许不得转载:同乐学堂 » Python数据分析实战5

特别的技术,给特别的你!

联系QQ:1071235258QQ群:710045715

觉得文章有用就打赏一下文章作者

非常感谢你的打赏,我们将继续给力更多优质内容,让我们一起创建更加美好的网络世界!

支付宝扫一扫打赏

微信扫一扫打赏

error: Sorry,暂时内容不可复制!