# 第五课、 比较多项式和高斯朴素贝叶斯
# 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 #
未经允许不得转载:同乐学堂 » Python数据分析实战5