zoukankan      html  css  js  c++  java
  • 贝叶斯--旧金山犯罪分类预测和电影评价好坏 demo

    来源引用:https://blog.csdn.net/han_xiaoyang/article/details/50629608

    1、引言

    贝叶斯是经典的机器学习算法,朴素贝叶斯经常运用于机器学习的案例。比如说

    文本分类/垃圾邮件的分类/情感分析:在文本分类中,贝斯依旧占有一席之地,因为文本数据中,分布独立这个假设基本上成立的。

    推荐系统:朴素贝叶斯和协同过滤一起使用,经常出现在推荐系统。以后有机会会好好写一篇关于推荐系统的文章。

    值得提醒的,以下部分点是要知道的:

    • 数据要服从正态分布,
    • 使用拉普斯平滑来处理测试数据中的0频次项
    • sklearn中的可调参数很少,只有拉普斯平滑因子alpha,类别先验概率class_prior和预算数据类别先验fit_prior。所以建议加强特征工程的操作来完善模型。
    • 集成方法对贝叶斯没有用,因为集成方法是用来减少过拟合的,减少variance的,而贝叶斯没有variance可以减少。

    在sklearn中分为三类先验:高斯分布,多项式分布,伯努利分布

    这三个类适用的分类场景各不相同,一般来说,

    • 如果样本特征的分布大部分是连续值,使用GaussianNB会比较好。
    • 如果如果样本特征的分大部分是多元离散值,使用MultinomialNB比较合适。
    • 如果样本特征是二元离散值或者很稀疏的多元离散值,应该使用BernoulliNB。

    接下来分析下kaggle比赛里面的旧金山犯罪分类预测问题。

    给出时间,地点,街区等特征来推测旧金山下一个犯罪类型是什么。

    来做一个小小的demo

    import pandas as pd
    import numpy as np
    
    #用pandas载入csv训练数据,并解析第一列为日期格式
    train=pd.read_csv('../input/train.csv', parse_dates = ['Dates'])
    test=pd.read_csv('../input/test.csv', parse_dates = ['Dates'])
    train
    
    import pandas as pd
    import numpy as np
    from sklearn.cross_validation import train_test_split
    from sklearn import preprocessing
    
    #用LabelEncoder对不同的犯罪类型编号
    leCrime = preprocessing.LabelEncoder()
    crime = leCrime.fit_transform(train.Category)
    
    #因子化星期几,街区,小时等特征,就是one hot编码
    days = pd.get_dummies(train.DayOfWeek)
    district = pd.get_dummies(train.PdDistrict)
    hour = train.Dates.dt.hour
    hour = pd.get_dummies(hour) 
    
    #组合特征
    trainData = pd.concat([hour, days, district], axis=1)
    trainData['crime']=crime
    
    #对于测试数据做同样的处理
    days = pd.get_dummies(test.DayOfWeek)
    district = pd.get_dummies(test.PdDistrict)
    
    hour = test.Dates.dt.hour
    hour = pd.get_dummies(hour) 
    
    testData = pd.concat([hour, days, district], axis=1)
    trainData
    
    from sklearn.cross_validation import train_test_split
    from sklearn import preprocessing
    from sklearn.metrics import log_loss
    from sklearn.naive_bayes import BernoulliNB
    from sklearn.linear_model import LogisticRegression
    import time
    
    # 只取星期几和街区作为分类器输入特征
    features = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'BAYVIEW', 'CENTRAL', 'INGLESIDE', 'MISSION',
     'NORTHERN', 'PARK', 'RICHMOND', 'SOUTHERN', 'TARAVAL', 'TENDERLOIN']
    
    # 分割训练集(3/5)和测试集(2/5)
    training, validation = train_test_split(trainData, train_size=.60)
    
    #朴素贝叶斯建模,计算log_loss
    model = BernoulliNB()
    nbStart = time.time()
    model.fit(training[features], training['crime'])
    nbCostTime = time.time() - nbStart
    predicted = np.array(model.predict_proba(validation[features]))
    #predict, predict_proba, predict_log_probas三种方法的区别
    print("朴素贝叶斯建模耗时 %f 秒" %(nbCostTime)) print("朴素贝叶斯log损失为 %f" %(log_loss(validation['crime'], predicted))) #逻辑回归建模,计算log_loss model = LogisticRegression(C=.01) lrStart= time.time() model.fit(training[features], training['crime']) lrCostTime = time.time() - lrStart predicted = np.array(model.predict_proba(validation[features]))
    print("逻辑回归建模耗时 %f 秒" %(lrCostTime)) print("逻辑回归log损失为 %f" %(log_loss(validation['crime'], predicted)))

    然后另一个经典应用是情感分析,kaggle类似的比赛就是 Bag of Words Meets Bags of Popcorn

    给出各个用户对电影的评价语句来判断对该电影的评价是好还是坏。

    我们知道DL的效果是好,但是耗时耗资源,贝叶斯建模快而且效果还可以。

    首先我们explore下数据,train集数据包含三部分,分别是id,sentiment(好坏),review(内容),根据kaggle的官方指导,要对评论进行处理:去掉Html的标签,‘/r’ 的处理,词语转化处理

    import re #正则表达式
    from
    bs4 import BeautifulSoup #html标签处理 import pandas as pd def review_to_wordlist(review): ''' 把IMDB的评论转成词序列 ''' # 去掉HTML标签,拿到内容 review_text = BeautifulSoup(review).get_text() # 用正则表达式取出符合规范的部分 review_text = re.sub("[^a-zA-Z]"," ", review_text) # 小写化所有的词,并转成词list words = review_text.lower().split() # 返回words return words # 使用pandas读入训练和测试csv文件
    # “header = 0”表示文件的第一行包含列名,“delimiter = ”表示字段由制表符分隔,quoting = 3表示Python忽略双引号,否则可能会遇到错误。
    train = pd.read_csv('../input/labeledTrainData.tsv', header=0, delimiter=" ", quoting=3) test = pd.read_csv('../input/testData.tsv', header=0, delimiter=" ", quoting=3 ) # 取出情感标签,positive/褒 或者 negative/贬 y_train = train['sentiment'] # 将训练和测试数据都转成词list train_data = []
    # xrange 用法与 range 完全相同,所不同的是生成的不是一个list对象,而是一个生成器。不用事先占用大内存。
    for i in xrange(0,len(train['review'])): train_data.append(" ".join(review_to_wordlist(train['review'][i]))) test_data = [] for i in xrange(0,len(test['review'])): test_data.append(" ".join(review_to_wordlist(test['review'][i])))

    接下来进行特征处理

    评论经过上面的处理后还是一串字符串,要把它变成数字才好进行模型拟合。kaggle中的引导是使用word2vec的特征抽取方式,当然还有其它的特征抽取方法,比如说利用互信息的提取,有点类似决策树的特征判断。这里的话,使用sklearn的一种文本检索有效的方法:TF-IDF向量法。该方法会把电影评论转化成一个TF-IDF向量。简要的解释是,TF-IDF是一种统计方法,用以评估一字词(或者n-gram)对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加,但同时会随着它在语料库中出现的频率成反比下降。

    以下是在sklearn的具体解释,以后会整理出具体的用法:

    http://sklearn.apachecn.org/cn/0.19.0/modules/feature_extraction.html#text-feature-extraction

    具体以下代码是去掉停用词,在单词级别上拓展到2元语言模型

    from sklearn.feature_extraction.text import TfidfVectorizer as TFIV
    # 初始化TFIV对象,去停用词,加2元语言模型
    tfv = TFIV(min_df=3,  max_features=None, strip_accents='unicode', analyzer='word',token_pattern=r'w{1,}', ngram_range=(1, 2), use_idf=1,smooth_idf=1,sublinear_tf=1, stop_words = 'english')
    # 合并训练和测试集以便进行TFIDF向量化操作
    X_all = train_data + test_data
    len_train = len(train_data)
    
    # 这一步有点慢
    tfv.fit(X_all)
    X_all = tfv.transform(X_all)
    # 恢复成训练集和测试集部分
    X = X_all[:len_train] 
    X_test = X_all[len_train:]

    逻辑回归和贝叶斯模型拟合:

    # 多项式朴素贝叶斯
    from sklearn.naive_bayes import MultinomialNB as MNB
    
    model_NB = MNB()
    model_NB.fit(X, y_train) 
    MNB(alpha=1.0, class_prior=None, fit_prior=True)
    
    from sklearn.cross_validation import cross_val_score
    import numpy as np
    
    print "多项式贝叶斯分类器20折交叉验证得分: ", np.mean(cross_val_score(model_NB, X, y_train, cv=20, scoring='roc_auc'))
    # 多项式贝叶斯分类器20折交叉验证得分: 0.950837239
    
    # 逻辑回归
    from sklearn.linear_model import LogisticRegression as LR
    from sklearn.grid_search import GridSearchCV
    
    # 设定grid search的参数
    grid_values = {'C':[30]}  
    # 设定打分为roc_auc
    model_LR = GridSearchCV(LR(penalty = 'L2', dual = True, random_state = 0), grid_values, scoring = 'roc_auc', cv = 20) 
    model_LR.fit(X,y_train)
    # 20折交叉验证,开始漫长的等待...
    GridSearchCV(cv=20, estimator=LogisticRegression(C=1.0, class_weight=None, dual=True, 
                 fit_intercept=True, intercept_scaling=1, penalty='L2', random_state=0, tol=0.0001),
            fit_params={}, iid=True, loss_func=None, n_jobs=1,
            param_grid={'C': [30]}, pre_dispatch='2*n_jobs', refit=True,
            score_func=None, scoring='roc_auc', verbose=0)
    #输出结果
    print model_LR.grid_scores_
    #[mean: 0.96459, std: 0.00489, params: {'C': 30}]
  • 相关阅读:
    jmeter(46) redis
    jmeter(45) tcp/ip协议
    Codeforces Round #538 (Div. 2)D(区间DP,思维)
    Codeforces Global Round 1D(DP,思维)
    Educational Codeforces Round 57D(DP,思维)
    UPC11073(DP,思维)
    Yahoo Progamming Contest 2019D(DP,思维)
    Atcoder Beginner Contest 118D(DP,完全背包,贪心)
    Xuzhou Winter Camp 1C(模拟)
    Educational Codeforces Round 57 (Rated for Div. 2)D(动态规划)
  • 原文地址:https://www.cnblogs.com/hotsnow/p/9507834.html
Copyright © 2011-2022 走看看