赞
踩
import random
import jieba
import pandas as pd
stopwords = pd.read_csv('~/Desktop/stopWords_3.txt',index_col=False,quoting=3,sep='\t',names=['stopword'],encoding='utf-8')
stopwords = stopwords['stopword'].values
waimai_df = pd.read_csv('~/Downloads/ChineseNlpCorpus-master/datasets/waimai_10k/waimai_10k.csv', encoding='utf-8', sep=',')
#删除语料的nan行
waimai_df.dropna(inplace=True)
#转换成列表形式
waimai = waimai_df.review.values.tolist()
label_id = waimai_df.label.values.tolist()
def preprocess_text(content_lines, sentences):
for line in content_lines:
try:
segs=jieba.lcut(line)
segs = [v for v in segs if not str(v).isdigit()]#去数字
segs = list(filter(lambda x:x.strip(), segs)) #去左右空格
segs = list(filter(lambda x:len(x)>1, segs)) #长度为1的字符
segs = list(filter(lambda x:x not in stopwords, segs)) #去掉停用词
sentences.append(" ".join(segs))
except Exception:
continue
sentences = []
preprocess_text(waimai,sentences)
sentences = list(zip(sentences,label_id))
# print(sentences)
Building prefix dict from the default dictionary ...
Loading model from cache /tmp/jieba.cache
Loading model cost 0.726 seconds.
Prefix dict has been built succesfully.
random.shuffle(sentences)
#在控制台输出前10条数据,观察一下
for sentence in sentences[:10]:
print(sentence[0], sentence[1])
一般 服务 差到 至极 饭量 要死 0
好吃 卫生 满意 1
味道 送餐 太慢 饭菜 全凉 0
送餐 米饭 三盒 两盒 两盒 0
两份 筷子 0
太坑 图片 很大 可怜 肥肉 肘子 0
好吃 准时 1
猪肉 堡里 酱流 满意 猪肉 1
送来 没人接 电话 0
太贵 八个 饺子 大小 包子 几口 1
from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(
analyzer='word', # tokenise by character ngrams
max_features=None, # keep the most common 1000 ngrams
vocabulary=None
)
from sklearn.model_selection import train_test_split
x, y = zip(*sentences)
x_train, x_test, y_train, y_test = train_test_split(x, y)
vec.fit(x_train)
CountVectorizer(analyzer='word', binary=False, decode_error='strict',
dtype=<class 'numpy.int64'>, encoding='utf-8', input='content',
lowercase=True, max_df=1.0, max_features=None, min_df=1,
ngram_range=(1, 1), preprocessor=None, stop_words=None,
strip_accents=None, token_pattern='(?u)\\b\\w\\w+\\b',
tokenizer=None, vocabulary=None)
from sklearn.svm import SVC
# svm = SVC(kernel='rbf',C=1000,gamma=0.001)
svm = SVC(kernel='linear') #0.8401735068401736
# svm = SVC(kernel='poly',gamma=1000)
svm.fit(vec.transform(x_train), y_train)
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
decision_function_shape='ovr', degree=3, gamma='auto_deprecated',
kernel='linear', max_iter=-1, probability=False, random_state=None,
shrinking=True, tol=0.001, verbose=False)
print(svm.score(vec.transform(x_test), y_test))
0.8468468468468469
pre = svm.predict(vec.transform(x_test))
下面可以把特征做得更强一点,尝试加入抽取 2-gram 和 3-gram 的统计特征,把词库的量放大一点。
from sklearn.feature_extraction.text import CountVectorizer
vec = CountVectorizer(
analyzer='word', # tokenise by character ngrams
ngram_range=(1,4), # use ngrams of size 1 and 2
max_features=20000, # keep the most common 1000 ngrams
)
vec.fit(x_train)
from sklearn.svm import SVC
# svm = SVC(kernel='rbf',C=1000,gamma=0.001)
svm = SVC(kernel='linear') #0.8401735068401736
# svm = SVC(kernel='poly',gamma=1000)
svm.fit(vec.transform(x_train), y_train)
print(svm.score(vec.transform(x_test), y_test))
0.8375041708375042
from sklearn.model_selection import train_test_split
x, y = zip(*sentences)
x_train, x_test, y_train, y_test = train_test_split(x, y)
vec.fit(x_train)
from sklearn.naive_bayes import MultinomialNB
classifier = MultinomialNB()
classifier.fit(vec.transform(x_train), y_train)
print(classifier.score(vec.transform(x_test), y_test))
0.8495161828495161
import xgboost as xgb from sklearn.model_selection import StratifiedKFold import numpy as np # xgb矩阵赋值 xgb_train = xgb.DMatrix(vec.transform(x_train), label=y_train) xgb_test = xgb.DMatrix(vec.transform(x_test)) params={'booster':'gbtree', 'objective': 'binary:logistic', 'eval_metric': 'auc', 'max_depth':4, 'lambda':10, 'subsample':0.75, 'colsample_bytree':0.75, 'min_child_weight':2, 'eta': 0.025, 'seed':0, 'nthread':8, 'silent':1} watchlist = [(xgb_train,'train')] bst=xgb.train(params,xgb_train,num_boost_round=5,evals=watchlist) #输出概率 ypred=bst.predict(xgb_test) # 设置阈值, 输出一些评价指标,选择概率大于0.5的为1,其他为0类 y_pred = (ypred >= 0.5)*1 from sklearn import metrics print ('AUC: %.4f' % metrics.roc_auc_score(y_test,ypred)) print ('ACC: %.4f' % metrics.accuracy_score(y_test,y_pred)) print ('Recall: %.4f' % metrics.recall_score(y_test,y_pred)) print ('F1-score: %.4f' %metrics.f1_score(y_test,y_pred)) print ('Precesion: %.4f' %metrics.precision_score(y_test,y_pred)) print(metrics.confusion_matrix(y_test,y_pred))
[0] train-auc:0.682634
[1] train-auc:0.701378
[2] train-auc:0.70118
[3] train-auc:0.701877
[4] train-auc:0.702868
AUC: 0.7019
ACC: 0.7501
Recall: 0.4863
F1-score: 0.5622
Precesion: 0.6662
[[1767 241]
[ 508 481]]
参考百度百科及以下这篇博文:
https://baijiahao.baidu.com/s?id=1597939133517926460&wfr=spider&for=pc
AUC(Area Under Curve被定义为ROC曲线下的面积。
我们往往使用AUC值作为模型的评价标准是因为很多时候ROC曲线并不能清晰的说明哪个分类器的效果更好,而作为一个数值,对应AUC更大的分类器效果更好。
其中,ROC曲线全称为受试者工作特征曲线 (receiver operating characteristic curve),它是根据一系列不同的二分类方式(分界值或决定阈),以真阳性率(敏感性)为纵坐标,假阳性率(1-特异性)为横坐标绘制的曲线。
具体到机器学习的理论中,ROC曲线该怎么理解呢?首先,需要指出的是,ROC分析的是二元分类模型,也就是输出结果只有两种类别的模型,比如:(阳性/阴性)(有病/没病)(垃圾邮件/非垃圾邮件)。在二分类问题中,数据的标签通常用(0/1)来表示,在模型训练完成后进行测试时,会对测试集的每个样本计算一个介于0~1之间的概率,表征模型认为该样本为阳性的概率,我们可以选定一个阈值,将模型计算出的概率进行二值化,比如选定阈值=0.5,那么当模型输出的值大于等于0.5时,我们就认为模型将该样本预测为阳性,也就是标签为1,反之亦然。选定的阈值不同,模型预测的结果也会相应地改变。二元分类模型的单个样本预测有四种结果:
这四种结果可以画成2 × 2的混淆矩阵:
有了混淆矩阵,就可以定义ROC曲线了。ROC曲线将假阳性率(FPR)定义为 X 轴,真阳性率(TPR)定义为 Y 轴。其中:
TPR:在所有实际为阳性的样本中,被正确地判断为阳性的样本比率。
FPR:在所有实际为阴性的样本中,被错误地判断为阳性的样本比率。
TPR = TP / (TP + FN)
FPR = FP / (FP + TN)
给定一个二分类模型和它的阈值,就可以根据所有测试集样本点的真实值和预测值计算出一个 (X=FPR, Y=TPR) 坐标点,这也就是绘制单个点的方法。那整条ROC曲线又该怎么画呢?具体方法如下:
在我们训练完一个二分类模型后,可以使用该模型对测试集中的全部样本点计算一个对应的概率值,每个值都介于0~1之间。假设测试集有100个样本点,我们可以对这100个样本的预测值从高到低排序,然后依次取每个值作为阈值,一旦阈值确定我们就可以绘制ROC曲线上的一个点,按照这种方法依次将100个点绘制出来,再将各个点依次连接起来,就得到了我们想要的ROC曲线!
然后再回到最初的问题,
AUC就是衡量学习器优劣的一种性能指标,可通过对ROC曲线下各部分的面积求和而得。当我们绘制出ROC曲线之后,AUC的值自然也就计算好啦。
为什么需要用AUC值表征模型的好坏?
在进行学习器的比较时,若一个学习器的ROC曲线被另一个学习器的曲线完全“包住”,则可断言后者的性能优于前者;若两个学习器的ROC曲线发生交叉,则难以一般性的断言两者孰优孰劣。此时如果一定要进行比较,则比较合理的判断依据是比较ROC曲线下的面积,即AUC(Area Under ROC Curve)。
从AUC 判断分类器(预测模型)优劣的标准:
AUC = 1,是完美分类器。 AUC = [0.85, 0.95], 效果很好 AUC = [0.7, 0.85], 效果一般 AUC = [0.5, 0.7],效果较低,但用于预测股票已经很不错了 AUC = 0.5,跟随机猜测一样(例:丢铜板),模型没有预测价值。 AUC < 0.5,比随机猜测还差;但只要总是反预测而行,就优于随机猜测。
- 1
- 2
- 3
- 4
- 5
- 6
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。