#数据准备,数据已下载
import nltk
#nltk.download('movie_reviews')
#nltk.download('stopwords')
#数据查看
#movie_reviews.categories()#数据集中对数据分类情况查看,提取数据集中的类别名
#每个分类的实际存储内容:
#movie_reviews.fileids(cat)#查看每个类别的内容
from nltk.corpus import movie_reviews
from sklearn.model_selection import StratifiedShuffleSplit
from nltk.corpus import stopwords
from nltk.collocations import BigramCollocationFinder
#Bigram是由相邻的且有意义的两个单词组成的序列,用于捕获单词之间的关系。
#BigramCollocationFinder是一个可以帮助我们找到在文本中出现频率较高的Bigram的工具。
#StratifiedShuffleSplit是一种基于分层抽样的交叉验证方法。
from nltk.metrics import BigramAssocMeasures
#BigramAssocMeasures是NLTK中的一个类,用于计算和评估不同的基于bigram的关联性度量
#载入数据集及所需模块
def GetData():
#存储数据
DataSet=[]
#存储类别
YLabels=[]
for cat in movie_reviews.categories():
for fileid in movie_reviews.fileids(cat):
words=list(movie_reviews.words(fileid))
DataSet.append((words,cat))
#二元组,它由两个或多个元素组成,每个元素可以是任意数据类型
#二元组,在设立是([标签],'特征')
YLabels.append(cat)
return DataSet,YLabels
#cat 当前文件的分类 fileid:当前文件ID
#定义了一个函数,载入数据集并划分数据集
def GetTrainTest(InData,YLabels):
TrainSize=0.7
TestSize=0.3
RanData=StratifiedShuffleSplit(train_size=TrainSize,test_size=TestSize,random_state=77)
#StratifiedShuffleSplit:一个交叉验证的方法,用于训练集和测试集的划分。
#random_state=77一种随机种子类型
for TrainInx,TestInx in RanData.split(InData,YLabels):
#InData:所有数据的特征集合 YLabels:对应的标签集合。RanData:随机数生成器,用于划分数据集
#装载数据集
TrainData=[InData[i] for i in TrainInx]
#TrainInx是StratifiedShuffleSplit方法生成的索引值
TrainY=[YLabels[i] for i in TrainInx]
#装载测试集
TestData=[InData[i] for i in TestInx]
TestY=[YLabels[i] for i in TestInx]
return TrainData,TestData,TrainY,TestY
#三种构造特征集的方式
def BuildWordFeatures(InData):
#用字典保存特征
FeatureSet={}
#词列表的实例元组里的第一个子项
words=InData[0]
#把特征保存到字典中,即每个词
for word in words:
FeatureSet[word]=1
#实例元组中第二个子项是类别标签
return (FeatureSet,InData[1])
#ps:第一种,直接用每个分词
def BuildNegFeatures(InData):#???
words=InData[0]
final=[]
#标识,为true则上个词是负面词,当前词要修饰
NegTag=False
#负面词列表
NegWords=['no','not']
#在负面词的本体前加"Not_"前缀,负面词本身不进入特征字典,修饰后的加入
for word in words:
if NegTag:
word='Not_'+word
NegTag=False
if word not in NegWords:
final.append(word)
else:
NegTag=True
#用字典保存特征
FeatureSet={}
for word in final:
FeatureSet[word]=1
#实例元组中第二个子项是类别标签
return (FeatureSet,InData[1])
#ps:第二种,单词进阶式,将负面词修饰一下
#一个处理停用词的函数
def StopWords(InData):
StopWord=stopwords.words('english')
NegWords=['no','not']
#创建新的停用词列表来排除负面词
NewStopWord=[word for word in StopWord if word not in NegWords]
label=InData[1]#权重???
#删除停用词
words=[word for word in InData[0] if word not in NewStopWord]
return (words,label)
def BuildKeyPhraseFeatrues(InData):
#用字典保存特征
FeatureSet={}
InData=StopWords(InData)
words=InData[0]
#将词进行二元组合
BigramFinder=BigramCollocationFinder.from_words(words)
#按照频率降序排序后,取前400个
bigrams=BigramFinder.nbest(BigramAssocMeasures.raw_freq,400)
for bigram in bigrams:
FeatureSet[bigram]=1
return (FeatureSet,InData[1])
#ps:第三种,组合词式,将词两两组合
def BayesModel(InData):
model=nltk.NaiveBayesClassifier.train(InData)
return model
#进行贝叶斯建模
def CheckModel(model,features,DataSetType='Train'):
acc=nltk.classify.accuracy(model,features)
print("\n"+DataSetType+"Accuracy=%0.2f"%(acc*100)+"%.")
#检查模型精度并打印
def ShowFeatures(model,FeaturesNO=5):
print("\nFeatrue Importance:")
print("==========================\n")
print(model.show_most_informative_features(FeaturesNO))
#打印模型中各特征的影响状况
##对照三种特征集构造方式,设立测试模型并观察指标的函数
def BuildModelNormal(TrainData,DevData,TestData):
#训练集特征
TrainFea=list(map(BuildWordFeatures,TrainData))
#调优测试集特征
DevFea=list(map(BuildWordFeatures,DevData))
#最终测试集特征
TestFea=list(map(BuildWordFeatures,TestData))
#建模
model=BayesModel(TrainFea)
#模型探测
CheckModel(model,TrainFea)
CheckModel(model,DevFea,'Dev')
CheckModel(model,TestFea,'Test')
return model
#直接用每个分词
def BuildModelNeg(TrainData,DevData,TestData):
#训练集特征
TrainFea=list(map(BuildNegFeatures,TrainData))
#调优测试集特征
DevFea=list(map(BuildNegFeatures,DevData))
#最终测试集特征
TestFea=list(map(BuildNegFeatures,TestData))
#建模
model=BayesModel(TrainFea)
#模型探测
CheckModel(model,TrainFea)
CheckModel(model,DevFea,'Dev')
CheckModel(model,TestFea,'Test')
return model
#单词进阶式,将负面词修饰一下。
def BuildModelKeyPhrase(TrainData,DevData,TestData):
#训练集特征
TrainFea=list(map(BuildKeyPhraseFeatrues,TrainData))
#调优测试集特征
DevFea=list(map(BuildKeyPhraseFeatrues,DevData))
#最终测试集特征
TestFea=list(map(BuildKeyPhraseFeatrues,TestData))
#建模
model=BayesModel(TrainFea)
#模型探测
CheckModel(model,TrainFea)
CheckModel(model,DevFea,'Dev')
CheckModel(model,TestFea,'Test')
return model
#组合词式,将词两两组合
if __name__=="__main__":
DataSet,YLabels=GetData()
Train,AllTest,TrainY,AllTestY=GetTrainTest(DataSet,YLabels)
Dev,Test,DevY,TestY=GetTrainTest(AllTest,AllTestY)
#查看各数据集大小
print("\nDataSet Size: %d"%(len(DataSet)))
print("\nTrain Size: %d"%(len(Train)))
print("\nDev Size: %d"%(len(Dev)))
print("\nTest Size: %d"%(len(Test)))
#分别建模并打印信息
NormalModel=BuildModelNormal(Train,Dev,Test)
ShowFeatures(NormalModel)
NegModel=BuildModelNeg(Train,Dev,Test)
ShowFeatures(NegModel)
KPModel=BuildModelKeyPhrase(Train,Dev,Test)
ShowFeatures(KPModel)
#编写主程序,调用各函数完成贝叶斯建模并测试
#假设model为调试好的分类模型名,NewData为{“特征”:value }字典形式的待分类数据,
#接上,可用以下语句进行分类: model.classify(NewData)
不知道你这个问题是否已经解决, 如果还没有解决的话:以前一致认为lgb/xgb这样的模型时可以识别列名的,只要输入的特征相同就没有问题,但这种观点是错误的,做了一个简单的实验:
from sklearn import datasets
import lightgbm as lgb
import pandas as pd
iris = datasets.load_iris()
X = iris.data
y = iris.target
X = pd.DataFrame(X)
lgb_train = lgb.Dataset(X, y)
params = {
'task': 'train',
'boosting_type': 'gbdt', # 设置提升类型
'objective': 'regression', # 目标函数
'metric': {'l2', 'auc'}, # 评估函数
'num_leaves': 31, # 叶子节点数
'learning_rate': 0.05, # 学习速率
'feature_fraction': 0.9, # 建树的特征选择比例
'bagging_fraction': 0.8, # 建树的样本采样比例
'bagging_freq': 5, # k 意味着每 k 次迭代执行bagging
'verbose': 1 # <0 显示致命的, =0 显示错误 (警告), >0 显示信息
}
gbm = lgb.train(params,lgb_train,num_boost_round=20)
使用鸢尾花数据集做训练,然后从中间抽出一条数据做预测,结果如下
test = pd.DataFrame([[5.1],[3.5],[1.4],[0.2]]).T
print(gbm.predict(test))
[0.35976825]
变换测试集列顺序,结果如下
test = pd.DataFrame([[0.2],[3.5],[1.4],[5.1]]).T
print(gbm.predict(test))
[0.59565977]
参考这篇博客https://blog.csdn.net/hshuihui/article/details/53258111,可能是由于数据传入时调用了as_matrix()方法,直接传入的矩阵,列什么的sklearn或者lgb并不会关心。
所以,
在训练模型时一定要保证训练集、验证集、测试集列顺序一致!
我很乐意帮您解决问题!
首先,您使用的编程语言和库是什么?朴素贝叶斯算法有很多实现方式,不同的编程语言和库也有不同的用法和问题。
其次,您能否提供具体的报错信息和代码?这样才能更好地定位问题并给出解决方案。如果您的数据预处理和特征提取没有问题,通常报错信息会给出一些提示,比如哪一行代码出错,错误类型等等。
最后,您的数据集的格式和特征选取有没有问题?朴素贝叶斯算法对特征选取非常敏感,如果您的特征选取得不好,模型效果就会很差。
如果您能提供更多的信息,我会尽力帮您解决问题。