NLP—比较各分类器在影评分类任务上的性能

题目:比较分类器在影评分类任务上的性能。

训练集:1500,测试集:500。
1、Naive Bayes(朴素贝叶斯)有三个常用模型:高斯、多项式、伯努利;
2、KNN选择K(最好是交叉验证);
3、SVM选择核函数。
4、决策树分类器
5、最大熵分类器
要求:在原理部分,对每种模型要简述原理,调整的每个参数要说明意义。最后部分简单概括,各分类器在影评分类任务上的性能。

【方法原理】

1、朴素贝叶斯模型:选择具有最高后验概率作为确定类别的指标。
2、KNN模型:如果待测样本在特征空间中的k个最邻近样本中的大多数属于某一个类别,则该样本也属于这个类别,并拥有这个类别上样本的特征。实现确定近邻数,一般为奇数;根据事先确定的距离度量公式(欧式距离),计算待分类数据点和所有已分类样本点之间的距离,并计算出最近的k个样本点;统计哥哥样本点中,各个类别的数量,数量最多的样本类型,即为待分类数据的类型。当样本数量不平衡时,一个类的样本数量很大,而其他样本数量很少时,很有可能导致,当输入一个未知样本时,该样本的K个邻居中大数量类样本占多数;可以通过为距离设置权值来改进,与该样本距离大的权值小,与该样本距离小的权值大。
3、SVM:支持向量机是一种回归和支持向量机算法,通过调节核函数参数的设置,可将数据集映射到多维平面上,对其细粒度化,从而使它的特征从二维变成多维,将在二维上线性不可分的问题转化为在多维上线性可分的问题,最后再寻找一个最优切割平面(相当于在决策树基础上再寻找一个最优解),因此svm的分类效果是优于大多数的机器学习分类方法的。
1)线性核函数:主要用于线性可分的情况,我们可以看到特征空间到输入空间的维度是一样的,其参数少速度快,对于线性可分数据,其分类效果很理想,因此我们通常首先尝试用线性核函数来做分类,看看效果如何,如果不行再换别的。
2)多项式核函数可以实现将低维的输入空间映射到高纬的特征空间,但是多项式核函数的参数多,当多项式的阶数比较高的时候,核矩阵的元素值将趋于无穷大或者无穷小,计算复杂度会大到无法计算。
3)高斯径向基函数是一种局部性强的核函数,其可以将一个样本映射到一个更高维的空间内,该核函数是应用最广的一个,无论大样本还是小样本都有比较好的性能,而且其相对于多项式核函数参数要少,因此大多数情况下在不知道用什么核函数的时候,优先使用高斯核函数。
  采用sigmoid核函数,支持向量机实现的就是一种多层神经网络。
在选择核函数时,吴恩达在课上提到过几种方法:
如果特征的数量大到和样本数量差不多,则选用LR或者线性核的SVM;
如果特征的数量小,样本的数量正常,则选用SVM+高斯核函数;
如果特征的数量小,而样本的数量很大,则需要手工添加一些特征从而变成第一种情况。
附带sklearn.svm.SVC参数说明
C:C-SVC的惩罚参数C,默认值是1.0
C越大,相当于惩罚松弛变量,希望松弛变量接近0,即对误分类的惩罚增大,趋向于对训练集全分对的情况,这样对训练集测试时准确率很高,但泛化能力弱。C值小,对误分类的惩罚减小,允许容错,将他们当成噪声点,泛化能力较强。
kernel :核函数,默认是rbf,可以是‘linear’, ‘poly’, ‘rbf’, ‘sigmoid’, ‘precomputed’
  0 – 线性:u’v
   1 – 多项式:(gamma*u’v + coef0)^degree
  2 – RBF函数:exp(-gamma|u-v|^2)
  3 –sigmoid:tanh(gamma
u’v + coef0)
degree :多项式poly函数的维度,默认是3,选择其他核函数时会被忽略。
gamma : ‘rbf’,‘poly’ 和‘sigmoid’的核函数参数。默认是’auto’,则会选择1/n_features
coef0 :核函数的常数项。对于‘poly’和 ‘sigmoid’有用。
probability :是否采用概率估计?.默认为False
shrinking :是否采用shrinking heuristic方法,默认为true
tol :停止训练的误差值大小,默认为1e-3
cache_size :核函数cache缓存大小,默认为200
class_weight :类别的权重,字典形式传递。设置第几类的参数C为weight
C(C-SVC中的C)
verbose :允许冗余输出?
max_iter :最大迭代次数。-1为无限制。
decision_function_shape :‘ovo’, ‘ovr’ or None, default=None3
random_state :数据洗牌时的种子值,int值
主要调节的参数有:C、kernel、degree、gamma、coef0

4、决策树是一种树形结构,为人们提供决策依据,决策树可以用来回答yes和no问题,它通过树形结构将各种情况组合都表示出来,每个分支表示一次选择(选择yes还是no),直到所有选择都进行完毕,最终给出正确答案。构造树的基本想法是随着树深度的增加,节点的熵迅速地降低。熵降低的速度越快越好(即信息增益越大越好)。
建树方法简单表述为:求出每一个属性的信息增益,最大的为根结点,以此类推,继续构造决策树。系统的信息熵降为0时,就没有必要再往下构造决策树了,此时叶子节点都是纯的–这是理想情况。最坏的情况下,决策树的高度为属性(决策变量)的个数,叶子节点不纯(这意味着我们要以一定的概率来作出决策,一般采用多数表决的方式确定此叶子节点)。

5、最大熵原理认为,学习概率模型时,在所有可能的概率模型(分布)中,熵最大的模型是最好的模型。如果有约束条件,最大熵原理也可以表述为在满足约束条件的模型集合中选取熵最大的模型。最大熵模型做的事就是假设分类模型是一个条件概率分布P(Y|X),然后利用最大熵原理选择最好的分类模型。
最大熵模型在分类方法中算是比较优的模型,但是由于它的约束函数数目一般来说会随着样本量的增大而增大,导致样本量很大的时候,对偶函数的优化求解过程非常慢。优点是可以灵活设置约束条件,通过约束条件的多少可以调节模型对未知数据的适应度和对已知数据的拟合度。缺点是约束函数数量和样本数目有关,导致迭代过程计算量巨大,实际应用比较难。

【结果】

1、Naive Bayes
在这里插入图片描述
2、KNN
求出不同K值时的准确率,最后选择最好的k值,输出其准确率。
在这里插入图片描述
在这里插入图片描述
3、SVM
首先判断四个核函数最好的是linear,然后使用linear求出向量机模型的准确率。
在这里插入图片描述

4、决策树
在这里插入图片描述
5、最大熵
在这里插入图片描述

【代码】

Nave Bayes

import nltk
from nltk.corpus import movie_reviews
from nltk.corpus import stopwords
import random
import numpy as np
from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import MultinomialNB
from sklearn.naive_bayes import BernoulliNB

documents=[(list(movie_reviews.words(fileid)),category)for category in movie_reviews.categories()for fileid in movie_reviews.fileids(category)]
random.shuffle(documents)
all_words = nltk.FreqDist(w.lower()for w in movie_reviews.words())      #建立全部影评的词频表
all_words = all_words.most_common(2000)     #词频表按频率排序
stop_words=stopwords.words('english')	#去停止词

word_features  =[w for (w,f) in all_words if w not in stop_words]

features = np.zeros([len(documents),len(word_features)],dtype=float)
for n in range(len(documents)):
        document_words = set(documents[n][0])
        for  m in range(len(word_features)):
                if word_features[m] in document_words:
                        features[n,m] = 1 # 文件-词集矩阵

target=[c for (d,c) in documents]
train_set=features[:1500,:]
target_train=target[:1500]
test_set=features[1500:,:]
target_test=target[1500:]

#高斯
gauNB = GaussianNB()
gauNB.fit(train_set,target_train)
pred = gauNB.predict(test_set)
print("高斯模型准确率:%s"%str(sum([1 for n in range(len(target_test)) if pred[n]==target_test[n] ])/len(target_test)))
#多项式
mulNB = MultinomialNB()
mulNB.fit(train_set,target_train)
pred = mulNB.predict(test_set)
print("多项式模型准确率:%s"%str(sum([1 for n in range(len(target_test)) if pred[n]==target_test[n] ])/len(target_test)))   
#伯努利
berNB = BernoulliNB()
berNB.fit(train_set,target_train)
pred = berNB.predict(test_set)
print("伯努利模型准确率:%s"%str(sum([1 for n in range(len(target_test)) if pred[n]==target_test[n] ])/len(target_test)))

KNN

documents = [(list(movie_reviews.words(fileid)), category) for category in movie_reviews.categories() for fileid in movie_reviews.fileids(category)]  #转化为词列表的影评,与标签,组成二元组
import random
random.shuffle(documents)	

all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words())
all_words=all_words.most_common(2000)	#词频表按频率排序
from nltk.corpus import stopwords
stop_words=stopwords.words('english')	#去停止词

word_features  =[w for (w,f) in all_words if w not in stop_words]

import numpy as np
features = np.zeros([len(documents),len(word_features)],dtype=float)
for n in range(len(documents)):
        document_words = set(documents[n][0])
        for  m in range(len(word_features)):
                if word_features[m] in document_words:
                        features[n,m] = 1 # 文件-词集矩阵

target=[c for (d,c) in documents]
train_set=features[:1500,:]
target_train=target[:1500]
test_set=features[1500:,:]
target_test=target[1500:]

#交叉验证
from sklearn.model_selection import cross_val_score
from sklearn.neighbors import KNeighborsClassifier
import matplotlib.pyplot as plt
X =[3,5,7,9,11,13,15,17,19,21,23,25,27,29,31]
k_scores = []

for k in X:
        knnclf = KNeighborsClassifier(n_neighbors=k)
        scores = cross_val_score(knnclf,train_set,target_train,cv=10)
        k_scores.append(scores.mean())
print(k_scores)
plt.plot(X, k_scores)
plt.xlabel('K Value in KNN')
plt.ylabel('Cross-Validation Mean Accuracy')
plt.show()
#使用效果最好的k值进行预测
knnclf = KNeighborsClassifier(n_neighbors=31)#default with k=5  
knnclf.fit(train_set,target_train)  
pred = knnclf.predict(test_set)
print(sum([1 for n in range(len(target_test)) if pred[n]==target_test[n] ])/len(target_test))

SVM

import nltk
from nltk.corpus import movie_reviews
documents = [(list(movie_reviews.words(fileid)), category) for category in movie_reviews.categories() for fileid in movie_reviews.fileids(category)]  #转化为词列表的影评,与标签,组成二元组
import random
random.shuffle(documents)	
print(documents[:200])

all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words())
all_words=all_words.most_common(2000)	#词频表按频率排序,高频2000词

from nltk.corpus import stopwords
stop_words=stopwords.words('english')	#停止词 stopwords
import string
punct = set(string.punctuation)                 # punctuation marks
word_features  =[w for (w,f) in all_words if w not in stop_words and w not in punct]

import numpy as np
features = np.zeros([len(documents),len(word_features)],dtype=float)
for n in range(len(documents)):
        document_words = set(documents[n][0])
        for  m in range(len(word_features)):
                if word_features[m] in document_words:
                        features[n,m] = 1 # 文件-词集矩阵

target=[c for (d,c) in documents]
train_set=features[:1500,:]
target_train=target[:1500]
test_set=features[1500:,:]
target_test=target[1500:]
print(test_set)
print(target_test)

##
###选择分类效果最好的核函数
##from sklearn.model_selection import GridSearchCV
##from sklearn.svm import SVC
##tuned_parameters = [{'kernel': ['rbf','poly','linear','sigmoid']}]
##svm_clf = GridSearchCV(SVC(gamma='auto'), tuned_parameters, cv=10)
##svm_clf.fit(train_set,target_train)
##print("The best parameters are %s : %0.2f" % (svm_clf.best_params_,svm_clf.best_score_))
##
###基于上一步选出的最好的核函数为线形
##svc= SVC(kernel = 'linear')
##svc.fit(train_set,target_train)
##pred = svc.predict(test_set)
##print("支持向量机准确率:"+str(sum([1 for n in range(len(target_test)) if pred[n]==target_test[n] ])/len(target_test)))

决策树

import nltk
from nltk.corpus import movie_reviews
documents = [(list(movie_reviews.words(fileid)), category) for category in movie_reviews.categories() for fileid in movie_reviews.fileids(category)]  #转化为词列表的影评,与标签,组成二元组
import random
random.shuffle(documents)	

all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words())
all_words=all_words.most_common(2000)	#词频表按频率排序
from nltk.corpus import stopwords
stop_words=stopwords.words('english')	#去停止词

word_features  =[w for (w,f) in all_words if w not in stop_words]

#建立特征提取器,标定该影评中是否有特征词
def document_features(document):
    document_words = set(document)
    features = {}
    for word in word_features:
        features['contains(%s)'%word]=(word in document_words)
    return features
#建立特征集
featuresets = [(document_features(d),c) for (d,c) in documents]
train_set,test_set = featuresets[:1500],featuresets[1500:]

from nltk.classify import DecisionTreeClassifier
dt_classifier = DecisionTreeClassifier.train(train_set, binary=True, entropy_cutoff=0.8, depth_cutoff=50, support_cutoff=30)
##Entropy_cutoff:当子集的熵大于该值时,会被进一步分解。因此,如果该值过大,子集中的标签分布很不均匀就已经停止了决策。
##Depth_cutoff:该值控制树的深度,它与训练时间成正比,与精度成反比。
##Support_cutoff:控制用于分解子集的标签集的数量,当少于该值时,被认为训练一个特征的样本数量不足。


print("决策树精确度:%s"%nltk.classify.accuracy(dt_classifier, test_set))

最大熵

import nltk
from nltk.corpus import movie_reviews
documents = [(list(movie_reviews.words(fileid)), category) for category in movie_reviews.categories() for fileid in movie_reviews.fileids(category)]  #转化为词列表的影评,与标签,组成二元组
import random
random.shuffle(documents)	

all_words = nltk.FreqDist(w.lower() for w in movie_reviews.words())
all_words=all_words.most_common(2000)	#词频表按频率排序
from nltk.corpus import stopwords
stop_words=stopwords.words('english')	#去停止词

word_features  =[w for (w,f) in all_words if w not in stop_words]

#建立特征提取器,标定该影评中是否有特征词
def document_features(document):
    document_words = set(document)
    features = {}
    for word in word_features:
        features['contains(%s)'%word]=(word in document_words)
    return features
#建立特征集
featuresets = [(document_features(d),c) for (d,c) in documents]
train_set,test_set = featuresets[:1500],featuresets[1500:]

from nltk.classify import MaxentClassifier
me_classifier = MaxentClassifier.train(train_set, algorithm='iis', trace=0, max_iter=1, min_lldelta=0.5)
print('最大熵分类器精度:%s'%nltk.classify.accuracy(me_classifier, test_set))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值