朴素贝叶斯(Naive Bayesian)是最为广泛使用的分类方法,它以概率论为基础,是基于贝叶斯定理和特征条件独立假设的分类方法。
一、 概述
1.1 简介
朴素贝叶斯(Naive Bayesian)是基于贝叶斯定理和特征条件独立假设的分类方法,它通过特征计算分类的概率,选取概率大的情况进行分类,因此它是基于概率论的一种机器学习分类方法。因为分类的目标是确定的,所以也是属于监督学习。
Q1:什么是基于概率论的方法?
通过概率来衡量事件发生的可能性。概率论和统计学恰好是两个相反的概念,统计学是抽取部分样本进行统计来估算总体的情况,而概率论是通过总体情况来估计单个事件或者部分事情的发生情况。因此,概率论需要已知的数据去预测未知的事件。
例如,我们看到天气乌云密布,电闪雷鸣并阵阵狂风,在这样的天气特征(F)下,我们推断下雨的概率比不下雨的概率大,也就是p(下雨)>p(不下雨),所以认为待会儿会下雨。这个从经验上看对概率进行判断。
而气象局通过多年长期积累的数据,经过计算,今天下雨的概率p(下雨)=85%,p(不下雨)=15%,同样的,p(下雨)>p(不下雨),因此今天的天气预报肯定预报下雨。这是通过一定的方法计算概率从而对下雨事件进行判断。
Q2:朴素贝叶斯,朴素在什么地方?
之所以叫朴素贝叶斯,因为它简单、易于操作,基于特征独立性假设,假设各个特征不会相互影响,这样就大大减小了计算概率的难度。
1.2 条件概率与贝叶斯定理
(1)概率论中几个基本概念
事件交和并:
A和B两个事件的交,指的是事件A和B同时出现,记为A∩B;
A和B两个事件的并,指的是事件A和事件B至少出现一次的情况,记为A∪B。
互补事件:事件A的补集,也就是事件A不发生的时候的事件,记为Ac。这个时候,要么A发生,要么Ac发生,P(A)+P(Ac)=1。
条件概率(conditional probability):
某个事件发生时另外一个事件发生的概率,如事件B发生条件下事件A发生的概率:
概率的乘法法则(multiplication rule of probability):
独立事件交的概率:
两个相互独立的事件,其交的概率为:
更多概率论基本概念,参见:概率论基本概念
(2)贝叶斯定理(Bayes’s Rule):
如果有k个互斥且有穷个事件
p(A):事件A发生的概率;
p(A∩B):事件A 和事件B同时发生的概率
p(A|B):表示事件A在事件B发生的条件下发生的概率,
1.3 朴素贝叶斯分类的原理
朴素贝叶斯基于条件概率、贝叶斯定理和独立性假设原则
(1)首先,我们来看条件概率原理:
基于概率论的方法告诉我们,当只有两种分类时:
(2)其次,贝叶斯定理
同样的道理,引入贝叶斯定理,有:
其中,x,y表示特征变量,ci表示分类,p(ci|x,y)即表示在特征为x,y的情况下分入类别ci的概率,因此,结合条件概率和贝叶斯定理,有:
如果p(c1|x,y)>p(c2|x,y),那么分类应当属于c1;
如果p(c1|x,y)<p(c2|x,y),那么分类应当属于c2;
贝叶斯定理最大的好处是可以用已知的三个概率去计算未知的概率,而如果仅仅是为了比较p(ci|x,y)和p(cj|x,y)的大小,只需要已知两个概率即可,分母相同,比较p(x,y|ci)p(ci)和p(x,y|cj)p(cj)即可。
(3)特征条件独立假设原则
朴素贝叶斯最常见的分类应用是对文档进行分类,因此,最常见的特征条件是文档中,出现词汇的情况,通常将词汇出现的特征条件用词向量ω表示,由多个数值组成,数值的个数和训练样本集中的词汇表个数相同。
因此,上述的贝叶斯条件概率公式可表示为:
前面提到朴素贝叶斯还有一个假设,就是基于特征条件独立的假设,也就是我们姑且认为词汇表中各个单词独立出现,不会相互影响,因此,p(ω|ci)可以将ω展开成独立事件概率相乘的形式,因此:
这样,计算概率就简单太多了。
1.4 朴素贝叶斯分类的流程和优缺点
(1)分类流程
1.数据准备:收集数据,并将数据预处理为数值型或者布尔型,如对文本分类,需要将文本解析为词向量
2.训练数据:根据训练样本集计算词项出现的概率,训练数据后得到各类下词汇出现概率的向量
3. 测试数据:用测试样本集去测试分类的准确性
(2) 优缺点
1. 监督学习,需要确定分类的目标
2. 对缺失数据不敏感,在数据较少的情况下依然可以使用该方法
3. 可以处理多个类别 的分类问题
4. 适用于标称型数据
5. 对输入数据的形势比较敏感
6. 由于用先验数据去预测分类,因此存在误差
二、Python算法实现
以在线社区的留言板评论为例,运用朴素贝叶斯分类方法,对文本进行自动分类。
构造一些实验样本,包括已经切分词条的文档集合,并且已经分类(带有侮辱性言论,和正常言论)。为了获取方便,在bayes.py中构造一个loadDataSet函数来生成实验样本。
def loadDataSet():
postingList=[['my', 'dog', 'has', 'flea', 'problems', 'help', 'please'],
['maybe', 'not', 'take', 'him', 'to', 'dog', 'park', 'stupid'],
['my', 'dalmation', 'is', 'so', 'cute', 'I', 'love', 'him'],
['stop', 'posting', 'stupid', 'worthless', 'garbage'],
['mr', 'licks', 'ate', 'my', 'steak', 'how', 'to', 'stop', 'him'],
['quit', 'buying', 'worthless', 'dog', 'food', 'stupid']]
classVec=[0,1,0,1,0,1] #1表示侮辱性言论,0表示正常言论
return postingList,classVec
2.1 根据文档词汇表构建词向量
(1)构建词汇表生成函数creatVocabList:
def createVocabList(dataSet):
vocabSet=set([])
for document in dataSet:
vocabSet=vocabSet|set(document) #取两个集合的并集
return list(vocabSet)
(2)对输入的词汇表构建词向量
#词集模型
def setOfWords2Vec(vocabList,inputSet):
returnVec=zeros(len(vocabList)) #生成零向量的array
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)]=1 #有单词,则该位置填充0
else: print('the word:%s is not in my Vocabulary!'% word)
return returnVec #返回全为0和1的向量
这种构建词向量的方法,只记录了每个词是否出现,而没有记录词出现的次数,这样的模型叫做词集模型,如果在词向量中记录词出现的次数,没出现一次,则多记录一次,这样的词向量构建方法,被称为词袋模型,下面构建以一个词袋模型的词向量生成函数bagOfWord2VecMN:
#词袋模型
def bagOfWords2VecMN(vocabList,inputSet):
returnVec=[0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)]+=1
return returnVec #返回非负整数的词向量
测试,对词向量生成函数进行测试,在控制台输入如下命令:
In [105]: import bayes
...:
In [106]: listPosts,listClasses=bayes.loadDataSet()
...:
In [107]: myVocabList=bayes.createVocabList(listPosts)
...:
In [108]: myVocabList
...:
Out[108]:
['I','quit', 'him', 'licks', 'food', 'problems', 'how', 'help', 'mr', 'my', 'take', 'posting', 'stupid', 'has', 'steak', 'buying', 'dalmation', 'flea', 'cute', 'park', 'please', 'dog', 'worthless', 'to', 'garbage','love', 'is', 'so', 'maybe', 'ate', 'stop', 'not']
In [109]: bayes.setOfWords2Vec(myVocabList,listPosts[0])
...:
Out[109]: array([ 0., 0., 0., ..., 0., 0., 0.])
In [110]: bayes.setOfWords2Vec(myVocabList,listPosts[1])
...:
2.2 运用词向量计算概率
再看前文提到的朴素贝叶斯的原理,要计算词向量ω=(ω0,ω1,ω2,...ωN,),落入ci类别下的概率:
因此计算出现概率大致有这么一些流程:
是用Python代码实现,创建函数TrainNB:
def trainNB0(trainMatrix,trainCategory):
numTrainDocs=len(trainMatrix) #文档数目
numWord=len(trainMatrix[0]) #词汇表词数目
pAbusive=sum(trainCategory)/len(trainCategory) #p1,出现侮辱性评论的概率
p0Num=zeros(numWord);p1Num=zeros(numWord)
p0Demon=0;p1Demon=0
for i in range(numTrainDocs):
if trainCategory[i]==0:
p0Num+=trainMatrix[i] #向量相加
p0Demon+=sum(trainMatrix[i]) #向量中1累加求和
else:
p1Num+=trainMatrix[i]
p1Demon+=sum(trainMatrix[i])
p0Vec=p0Num/p0Demon
p1Vec=p1Num/p1Demon
return p0Vec,p1Vec,pAbusive
解释:
1.pAbusive=sum(trainCategory)/len(trainCategory),表示文档集中分类为1的文档数目,累加求和将词向量中所有1相加,len求长度函数则对所有0和1进行计数,最后得到分类为1的概率
2.p0Num+=trainMatrix[i];p0Demon+=sum(trainMatrix[i]),前者是向量相加,其结果还是向量,trainMatrix[i]中是1的位置全部加到p0Num中,后者是先求和(该词向量中词项的数目),其结果是数值,表示词项总数。
3.p0Vec=p0Num/p0Demon,向量除以数值,结果是向量,向量中每个元素都除以该数值。
测试:对构建的朴素贝叶斯分类器训练函数进行测试,在python(个人使用的是ipython)提示符中输入:
In [111]: reload(bayes)
...:
Out[111]: <module 'bayes' from 'G:\\Workspaces\\MachineLearning\\bayes.py'>
In [112]: listPosts,listClasses=bayes.loadDataSet()
...:
In [113]: myVocabList=bayes.createVocabList(listPosts)
...:
In [114]: trainMat=[]
...:
In [115]: for postinDoc in listPosts:
...: trainMat.append(bayes.setOfWords2Vec(myVocabList,postinDoc))
...:
...:
In [116]: p0v,p1v,pAb=bayes.trainNB0(trainMat,listClasses)
...:
In [117]: pAb
...:
Out[117]: 0.5
In [118]: p0v
...:
Out[118]:
array([ 0.04166667, 0. , 0.08333333, ..., 0.04166667,
0.04166667, 0. ])
In [119]: p1v
...:
Out[119]:
array([ 0. , 0.05263158, 0.05263158, ..., 0. ,
0.05263158, 0.05263158])
#myVocabList中第26个词汇是'love',即myVocabList[25]='love'
In [121]: p0v[25]
Out[121]: 0.041666666666666664
In [122]: p1v[25]
Out[122]: 0.0
##myVocabList中第13个词汇是'stupid',即myVocabList[13]='stupid'
In [124]: p0v[12]
Out[124]: 0.0
In [125]: p1v[12]
Out[125]: 0.15789473684210525
从结果我们看到,侮辱性文档出现的概率是0.5,词项’love’在侮辱性文档中出现的概率是0,在正常言论中出现的概率是0.042;词项‘stupid’在正常言论中出现的概率是0,在侮辱性言论中出现的规律是0.158.
算法漏洞:
乘积为0
我们看到,当某分类下某词项出现频次为0时,其概率也是0,因此在计算p(w0|ci)p(w1|ci)p(w2|ci)......p(wN|ci)会因为其中某个的概率为0而全部是0。
为了避免这样的情况发生,我们将所有词项出现的频次都初始化为1,某类所有词项数量初始化为2。
因子太小导致结果溢出问题
由于p(w0|ci)p(w1|ci)p(w2|ci)......p(wN|ci)中每个因子都很小,所有因子相乘,特别是因子数量多的时候,会导致结果溢出,从而得到错误的数据
避免溢出问题的发生,可以使用求自然对数的方法,自然对数和原本的数值同增同减,不会有任何损失,因此不会影响求得的概率结果。
因此,将朴素贝叶斯分类器函数修改为:
def trainNB1(trainMatrix,trainCategory):
numTrainDocs=len(trainMatrix)
numWord=len(trainMatrix[0])
pAbusive=sum(trainCategory)/len(trainCategory)
p0Num=ones(numWord);p1Num=ones(numWord)# 初始化为1
p0Demon=2;p1Demon=2 #初始化为2
for i in range(numTrainDocs):
if trainCategory[i]==0:
p0Num+=trainMatrix[i]
p0Demon+=sum(trainMatrix[i])
else:
p1Num+=trainMatrix[i]
p1Demon+=sum(trainMatrix[i])
p0Vec=log(p0Num/p0Demon) #对结果求对数
p1Vec=log(p1Num/p1Demon) #对结果求自然对数
return p0Vec,p1Vec,pAbusive
2.3 运用分类器函数对文档进行分类
前文概率论讲到,计算文档在各类中的概率,取较大者作为该文档的分类,所以构建分类函数classifyNB:
def testingNB():
listPosts,listClasses=loadDataSet()
myVocabList=createVocabList(listPosts)
trainMat=[]
for postinDoc in listPosts:
trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
p0V,p1V,pAb=trainNB1(trainMat,listClasses)
testEntry=['love','my','dalmation']
thisDoc=setOfWords2Vec(myVocabList,testEntry)
print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))
testEntry=['stupid','garbage']
thisDoc=array(setOfWords2Vec(myVocabList,testEntry))
print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))
说明:
p1=sum(vec2Classify*p1Vec)+log(pClass1) 的数学原理是ln(a*b)=ln(a) +ln(b)
接下来构造几个样本,来测试分类函数:
def testingNB():
listPosts,listClasses=loadDataSet()
myVocabList=createVocabList(listPosts)
trainMat=[]
for postinDoc in listPosts:
trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
p0V,p1V,pAb=trainNB1(trainMat,listClasses)
testEntry=['love','my','dalmation']
thisDoc=setOfWords2Vec(myVocabList,testEntry)
print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))
testEntry=['stupid','garbage']
thisDoc=array(setOfWords2Vec(myVocabList,testEntry))
print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))
测试,在Python命令符中输入:In [126]: reload(bayes)
...:
Out[126]: <module 'bayes' from 'G:\\Workspaces\\MachineLearning\\bayes.py'>
In [127]: bayes.testingNB()
...:
['love', 'my', 'dalmation'] classified as: 0 #分类到正常言论
['stupid', 'garbage'] classified as: 1 #分类到侮辱性言论
三、 实例:使用朴素贝叶斯过滤垃圾邮件
文件夹spam和ham中各有25封txt文档形式的邮件正文,两个文件夹分别分类为1和0,如打开ham中2.txt文件,其内容为:
Yay to you both doing fine!
I'm working on an MBA in Design Strategy at CCA (top art school.) It's a new program focusing on more of a right-brained creative and strategic approach to management. I'm an 1/8 of the way done today!
现在,利用这些文档,进行朴素贝叶斯分类算法训练和测试:
#切分文本函数 def textParser(bigString): import re #正则表达式 listOfTokens=re.split(r'\W*',bigString) #\W表示非单词符进行划分 return [tok.lower() for tok in listOfTokens if len(tok)>2] #返回小写且长度大于2的词项 #对文件夹中文件进行自动处理 def spanTest(): docList=[];classList=[];fullText=[] for i in range(1,26): wordList=textParser(open('machinelearninginaction/Ch04/email/spam/%d.txt'%i).read()) docList.append(wordList) fullText.extend(wordList) classList.append(1) wordList=textParser(open('machinelearninginaction/Ch04/email/ham/%d.txt'%i).read()) docList.append(wordList) fullText.extend(wordList) classList.append(0) vocabList=createVocabList(docList) #留存交叉验证 trainingSet=list(range(50));testSet=[] for i in range(10): randIndex=int(random.uniform(0,len(trainingSet))) testSet.append(trainingSet[randIndex]) del(trainingSet[randIndex]) trainMat=[];trainClasses=[] for docIndex in trainingSet: trainMat.append(setOfWords2Vec(vocabList,docList[docIndex])) trainClasses.append(classList[docIndex]) p0V,p1V,pAb=trainNB1(trainMat,trainClasses) errorCount=0 for docIndex in testSet: wordVector=setOfWords2Vec(vocabList,docList[docIndex]) if classifyNB(wordVector,p0V,p1V,pAb) != classList[docIndex]: errorCount+=1 print('classification error',docList[docIndex]) print('the error rate is:',float(errorCount)/len(testSet))
利用该样本集合中的数据样本,随机选取一部分作为训练样本集,剩余部分作为测试样本集,这样的方法称为留存交叉验证
在Python console中对函数进行测试:
In [131]: bayes.spanTest()
...:
classification error ['home', 'based', 'business', 'opportunity', 'knocking', 'your', 'door', 'don抰', 'rude', 'and', 'let', 'this', 'chance', 'you', 'can', 'earn', 'great', 'income', 'and', 'find', 'your', 'financial', 'life', 'transformed', 'learn', 'more', 'here', 'your', 'success', 'work', 'from', 'home', 'finder', 'experts']
the error rate is: 0.1
D:\Tools\ANACONDA\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
return _compile(pattern, flags).split(string, maxsplit)
可以看到测试的错误率为0.1,并且输出了分类错误的文档中的词项。多次执行上述函数进行测试,发现错误率会变化。
四、实例:使用朴素贝叶斯分类器从个人广告中获取区域倾向
我们利用python库中中的Universal Feed Parser来获取数据,首先需要引入包feedparser:import feedparser,如果没有需要安装,比较简单的方法是使用pip进行安装。
#获取频率最高的词项
def calcMostFreq(vocabList,fullText):
import operator
freqDict={}
for word in vocabList:
freqDict[word]=fullText.count(word)
sortedFreq=sorted(freqDict.items(),key=operator.itemgetter(1),reverse=True)
return sortedFreq[:20]
#
def localWords(feed1,feed0):
import feedparser
docList=[];classList=[];fullText=[]
minLen=min(len(feed1['entries']),len(feed0['entries']))
for i in range(minLen):
wordList=textParser(feed1['entries'][i]['summary'])
docList.append(wordList)
fullText.extend(wordList)
classList.append(1)
wordList=textParser(feed0['entries'][i]['summary'])
docList.append(wordList)
fullText.extend(wordList)
classList.append(0)
vocabList=createVocabList(docList)
top30words=calcMostFreq(vocabList,fullText) #选取频率最高的30个词
#去掉出现频率最高的30个词
for pairW in top30words:
if pairW[0] in vocabList:
vocabList.remove(pairW[0])
trainSet=list(range(2*minLen))
testSet=[]
for i in range(20):
randIndex=int(random.uniform(0,len(trainSet)))
testSet.append(trainSet[randIndex])
del(trainSet[randIndex])
trainMat=[];trainClasses=[]
for docIndex in trainSet:
trainMat.append(bagOfWords2VecMN(vocabList,docList[docIndex]))
trainClasses.append(classList[docIndex])
p0V,p1V,pSpam=trainNB1(trainMat,trainClasses)
errorCount=0
for docIndex in testSet:
wordVector=bagOfWords2VecMN(vocabList,docList[docIndex])
if classifyNB(wordVector,p0V,p1V,pSpam) !=classList[docIndex]:
errorCount+=1
print('the error rate is:',float(errorCount)/len(testSet))
return vocabList,p0V,p1V
说明:
1.为什么要去除频次最高的词项:因为出现频次高的词项很多是没有意义的冗余和辅助性内容,不移除这些词汇,使用朴素贝叶斯分类算法,其错误率会显著高一些
- 另外一个方法,是从词表中删除辅助词,这个需要删除的词表被称为停用词表,这个网站列出了多门语言,如英文、中文等语言中的停用词表。
在Python命令符中对上述函数进行测试:
In [132]: import feedparser
...:
In [133]: ny=feedparser.parse('https://newyork.craigslist.org/stp/index.rss')
...:
In [134]: sf=feedparser.parse('https://sfbay.craigslist.org/stp/index.rss')
...:
In [135]: vocabList,pSF,pNY=bayes.localWords(ny,sf)
...:
the error rate is: 0.45
D:\Tools\ANACONDA\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
return _compile(pattern, flags).split(string, maxsplit)
In [136]: vocabList,pSF,pNY=bayes.localWords(ny,sf)
...:
the error rate is: 0.3
D:\Tools\ANACONDA\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
return _compile(pattern, flags).split(string, maxsplit)
(2)显示最具表征性的词汇
In [143]: bayes.getTopWords(ny,sf,-4.5)
the error rate is: 0.4
SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF
guy
know
talk
friendship
married
maybe
going
single
out
male
NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY
day
out
meet
chat
seeking
year
time
stocks
well
now
woman
kik
company
work
D:\Tools\ANACONDA\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
return _compile(pattern, flags).split(string, maxsplit)#最具表征性的词汇表显示函数
def getTopWords(ny,sf,t=-6.0):
import operator
vocabList,p0V,p1V=localWords(ny,sf)
topNY=[];topSF=[]
for i in range(len(p0V)):
#选取一个阈值t
if p0V[i]>t:topSF.append((vocabList[i],p0V[i]))
if p1V[i]>t:topNY.append((vocabList[i],p1V[i]))
sortedSF=sorted(topSF,key=lambda x: x[1],reverse=True)
print('SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF')
for item in sortedSF:
print(item[0])
sortedNY=sorted(topNY,key=lambda pair: pair[1],reverse=True)
print('NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY')
for item in sortedNY:
print(item[0])
测试:在Python命令符中输入命令来测试函数:
In [143]: bayes.getTopWords(ny,sf,-4.5)
the error rate is: 0.4
SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF**SF
guy
know
talk
friendship
married
maybe
going
single
out
male
NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY**NY
day
out
meet
chat
seeking
year
time
stocks
well
now
woman
kik
company
work
D:\Tools\ANACONDA\lib\re.py:212: FutureWarning: split() requires a non-empty pattern match.
return _compile(pattern, flags).split(string, maxsplit)
数据分析咨询请扫描二维码
在准备数据分析师面试时,掌握高频考题及其解答是应对面试的关键。为了帮助大家轻松上岸,以下是10个高频考题及其详细解析,外加 ...
2024-12-20互联网数据分析师是一个热门且综合性的职业,他们通过数据挖掘和分析,为企业的业务决策和运营优化提供强有力的支持。尤其在如今 ...
2024-12-20在现代商业环境中,数据分析师是不可或缺的角色。他们的工作不仅仅是对数据进行深入分析,更是协助企业从复杂的数据信息中提炼出 ...
2024-12-20随着大数据时代的到来,数据驱动的决策方式开始受到越来越多企业的青睐。近年来,数据分析在人力资源管理中正在扮演着至关重要的 ...
2024-12-20在数据分析的世界里,表面上的技术操作只是“入门票”,而真正的高手则需要打破一些“看不见的墙”。这些“隐形天花板”限制了数 ...
2024-12-19在数据分析领域,尽管行业前景广阔、岗位需求旺盛,但实际的工作难度却远超很多人的想象。很多新手初入数据分析岗位时,常常被各 ...
2024-12-19入门数据分析,许多人都会感到“难”,但这“难”究竟难在哪儿?对于新手而言,往往不是技术不行,而是思维方式、业务理解和实践 ...
2024-12-19在如今的行业动荡背景下,数据分析师的职业前景虽然面临一些挑战,但也充满了许多新的机会。随着技术的不断发展和多领域需求的提 ...
2024-12-19在信息爆炸的时代,数据分析师如同探险家,在浩瀚的数据海洋中寻觅有价值的宝藏。这不仅需要技术上的过硬实力,还需要一种艺术家 ...
2024-12-19在当今信息化社会,大数据已成为各行各业不可或缺的宝贵资源。大数据专业应运而生,旨在培养具备扎实理论基础和实践能力,能够应 ...
2024-12-19阿里P8、P9失业都找不到工作?是我们孤陋寡闻还是世界真的已经“癫”成这样了? 案例一:本硕都是 985,所学的专业也是当红专业 ...
2024-12-19CDA持证人Louis CDA持证人基本情况 我大学是在一个二线城市的一所普通二本院校读的,专业是旅游管理,非计算机非统计学。毕业之 ...
2024-12-18最近,知乎上有个很火的话题:“一个人为何会陷入社会底层”? 有人说,这个世界上只有一个分水岭,就是“羊水”;还有人说,一 ...
2024-12-18在这个数据驱动的时代,数据分析师的技能需求快速增长。掌握适当的编程语言不仅能增强分析能力,还能帮助分析师从海量数据中提取 ...
2024-12-17在当今信息爆炸的时代,数据分析已经成为许多行业中不可或缺的一部分。想要在这个领域脱颖而出,除了热情和毅力外,你还需要掌握 ...
2024-12-17数据分析,是一项通过科学方法处理数据以获取洞察并支持决策的艺术。无论是在商业环境中提升业绩,还是在科研领域推动创新,数据 ...
2024-12-17在数据分析领域,图表是我们表达数据故事的重要工具。它们不仅让数据变得更加直观,也帮助我们更好地理解数据中的趋势和模式。相 ...
2024-12-16在当今社会,我们身处着一个飞速发展、变化迅猛的时代。不同行业在科技进步、市场需求和政策支持的推动下蓬勃发展,呈现出令人瞩 ...
2024-12-16在现代商业世界中,数据分析师扮演着至关重要的角色。他们通过解析海量数据,为企业战略决策提供有力支持。要有效完成这项任务, ...
2024-12-16在当今数据爆炸的时代,数据分析师是组织中不可或缺的导航者。他们通过从大量数据中提取可操作的洞察力,帮助企业在竞争激烈的市 ...
2024-12-16