做微商推廣有哪些好的分類信息網(wǎng)站seo關(guān)鍵詞優(yōu)化推廣外包
需求背景:
XX一直使用約會(huì)網(wǎng)站尋找適合自己的約會(huì)對象,ta會(huì)把人分為3種類型:
不喜歡、魅力一般、非常有魅力
對人分類軸,發(fā)現(xiàn)了對象樣本的以下3種特征:
1、每年獲得的飛行里程數(shù)
2、玩視頻游戲所耗時(shí)間百分比
3、每周消費(fèi)的冰淇淋數(shù)量
數(shù)據(jù)初始化:
將上述特征輸入到分類器之前,必須將待處理數(shù)據(jù)的格式處理成分類器可以接受的格式。因?yàn)樵磾?shù)據(jù)存在txt文件中,所以要?jiǎng)?chuàng)建一個(gè)函數(shù)處理數(shù)據(jù):
def file2matrix(filename):fr=open(filename)arrayOlines=fr.readlines()numberOfLines=len(arrayOlines)returnMat=zeros((numberOfLines,3))classLabelVector=[]index=0for line in arrayOlines:line=line.strip()listFromLine=line.split('\t')returnMat[index,:]=listFromLine[0:3]classLabelVector.append(int(listFromLine[-1]))index += 1return returnMat,classLabelVector
從上面的代碼可以看到,Python處理文本文件非常容易。
處理順序:
1、獲得文件的行數(shù)
2、創(chuàng)建以0填充的矩陣NumPy
3、循環(huán)處理文件中的每行數(shù)據(jù),使用函數(shù)line.strip()截取掉所有的回車字符
分析數(shù)據(jù):
使用Matplotlib制作原始數(shù)據(jù)的散點(diǎn)圖:
datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
plt.show()
可以看到,由于沒有使用樣本分類的特征值,很難從圖中看出任何有用的數(shù)據(jù)模式信息,所以調(diào)試代碼,利用scatter函數(shù)進(jìn)行個(gè)性化標(biāo)記散點(diǎn)圖上的點(diǎn):
ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
現(xiàn)在就可以看出每種分類人群的特征
準(zhǔn)備數(shù)據(jù):歸一化數(shù)值
從數(shù)據(jù)上可以看出,每年飛行里程數(shù)對于計(jì)算結(jié)果的影響遠(yuǎn)遠(yuǎn)大于另外兩個(gè)特征的影響。而產(chǎn)生這種線性的原因,僅僅是因?yàn)轱w行里程數(shù)遠(yuǎn)大于其他特征,但因?yàn)橛脩粽J(rèn)為這三種特征是同等重要的,所以作為特征之一,里程數(shù)不應(yīng)該如此嚴(yán)重的影響到計(jì)算結(jié)果。
處理這種不同取值范圍的特征值時(shí),我們通常采用的方法是將數(shù)值歸一化,比如將取值范圍處理為0到1或者-1到1之間。下面的公式可以將任意取值范圍轉(zhuǎn)化為0到1區(qū)間內(nèi)的值:
newValue=(oldValue-min)/(max-min)
其中min和max分別是數(shù)據(jù)集中的最小特征值和最大特征值。
歸一化函數(shù):
def autoNorm(dataSet):minVals=dataSet.min(0)maxVals=dataSet.max(0)ranges=maxVals-minValsnormDataSet=zeros(shape(dataSet))m=dataSet.shape[0]normDataSet=dataSet-tile(minVals,(m,1))normDataSet=normDataSet/tile(ranges,(m,1))return normDataSet,ranges,minVals
在這個(gè)函數(shù)中,我們將每列的最小值放在變量minVals中,將最大值放在變量maxVals中,其中dataSet.min(0)中的參數(shù)0使得函數(shù)可以從列中選取最小值,而不是選取當(dāng)前行的最小值。然后,函數(shù)計(jì)算可能的取值范圍,并創(chuàng)建新的返回矩陣。為了歸一化特征值,我們必須使用當(dāng)前值減去最小值,然后除以取值范圍。需要注意的是,特征矩陣由1000*3個(gè)值,而minVals和range的值都是1*3.為了解決這個(gè)問題,使用NumPy庫中的tile()函數(shù)將變量內(nèi)容復(fù)制乘輸入矩陣同樣大小的矩陣。這是具體特征值相處。
測試算法:作為完整程序驗(yàn)證分類器
機(jī)器學(xué)習(xí)算法一個(gè)很重要的工作就是評估算法的正確率,通常我們只提供90%的數(shù)據(jù)作為訓(xùn)練樣本,而使用剩余的10%作為測試數(shù)據(jù)。其中10%的測試數(shù)據(jù)應(yīng)該是隨機(jī)選擇的。
完美分類器的錯(cuò)誤量為0,而錯(cuò)誤率為1.0的分類器不會(huì)給出任何正確的分類
為了測試分類器效果,我們創(chuàng)建以下函數(shù):
def datingClassTest():hoRatio=0.10datingDataMat=datingLabels=file2matrix('datingTestSet2.txt')normMat,ranges,minVals=autoNorm(datingDataMat)m=normMat.shape[0]errorCount=0.0numTestVecs=int(m*hoRatio)for i in range(numTestVecs):classifierResult=classify0(normMat[i,:],normMat[numTestVecs:m,],datingLabels[numTestVecs:m],3)print(classifierResult,datingLabels[i])if (classifierResult!=datingLabels[i]):errorCount+=1.0print(errorCount/float(numTestVecs))
函數(shù)datingClassTest首先使用了file2matrix和autoNorm函數(shù)從文件中讀取數(shù)據(jù)并將其轉(zhuǎn)化為歸一化特征值。接著計(jì)算測試向量的數(shù)量,這一步?jīng)Q定了normMat向量中哪些數(shù)據(jù)用于測試,那些數(shù)據(jù)用于訓(xùn)練;然后將這兩部分?jǐn)?shù)據(jù)輸入到原始kNN分類器函數(shù)classify0.最后,函數(shù)計(jì)算錯(cuò)誤率并輸出結(jié)果。
需要注意,此處我們使用原始分類器。
分類器處理數(shù)據(jù)集的錯(cuò)誤率為5%,這是一個(gè)還不錯(cuò)的結(jié)果。我們可以改變函數(shù)中hoRatio和變量k的值,檢測錯(cuò)誤率是否會(huì)隨著變量值的變換而增加,
使用算法:構(gòu)建完整可用系統(tǒng)
上面已經(jīng)在數(shù)據(jù)上對分類器進(jìn)行了測試,現(xiàn)在可以用這個(gè)分類器對人員進(jìn)行分類:
def classifyPerson():resultList=['完全不喜歡','一般魅力','很有魅力']percentTats=float(input('每年玩視頻游戲的時(shí)間比例?'))ffMiles=float(input('每年的飛行里程數(shù)?'))iceCream=float(input('每年吃冰激凌的數(shù)量?'))datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')normMat,ranges,minVals=autoNorm(datingDataMat)inArr=array([ffMiles,percentTats,iceCream])classifierResult=classify0((inArr-minVals)/ranges,normMat,datingLabels,3)print('你對于這個(gè)人的感受:',resultList[classifierResult-1])