首先要區(qū)別多分類 和多標簽的區(qū)別。
多分類問題:一個樣本的類別是多個泳猬,比如判別一個未知水果,它可能是蘋果蛾娶,也可能是香蕉,也可能是西瓜均澳。水果的種類的是多樣的,但是一個樣本只可能是其中一類符衔。
多標簽問題:一個樣本包含多個類別找前。例如評價某個人和善,聰明判族,懶惰躺盛,即這個樣本包含多個類別標簽,既可以是A也可以是B,類別之間不互斥形帮。
算法原理
改進版knn :ml-knn (multi-label knn)
- 1.通過knn 算法尋找和樣本最近的K個樣本
- 2.統(tǒng)計k個樣本中每個類別的個數(shù)
- 3.根據(jù)第二步的統(tǒng)計槽惫,采用 native bayes算法計算每個標簽的概率
- 4.輸出類別概率
算法偽代碼:
(1)-(13)步驟是native bayes 模型訓練
步驟一:由(1)-(2) 統(tǒng)計類別L在樣本中的概率。
s :參數(shù)辩撑,用于數(shù)據(jù)平滑界斜,
m:是標準樣本個數(shù)。
:表示標簽L的概率
: 表示樣本中標簽L的個數(shù)合冀。
步驟二:(3)-(13)計算每個樣本的K個最近鄰中各薇,在樣本標簽為L的條件下,(K個樣本中有j個L標簽的樣本數(shù)量)的概率水慨。以及在樣本不是標簽L的條件下得糜,的概率
步驟三:新樣本估計
(這里native bayes中的分母省略計算敬扛,比較分子大小就夠了)
其中:指的是樣本類別向量
偽代碼中就是樣本每個類的概率。
算法簡單實踐:
MLkNN 來自于scikit-multilearn庫
庫安裝:
pip install scikit-multilearn
數(shù)據(jù)讀取
import scipy
import pandas as pd
from scipy.io import arff
data, meta = scipy.io.arff.loadarff('/app/jupyter_dir/data/yeast-train.arff')
df = pd.DataFrame(data)
df.head()
Att1 Att2 Att3 Att4 Att5 Att6 Att7 Att8 Att9 Att10 ... Class5 Class6 Class7 Class8 Class9 Class10 Class11 Class12 Class13 Class14
0 0.093700 0.139771 0.062774 0.007698 0.083873 -0.119156 0.073305 0.005510 0.027523 0.043477 ... b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0'
1 -0.022711 -0.050504 -0.035691 -0.065434 -0.084316 -0.378560 0.038212 0.085770 0.182613 -0.055544 ... b'0' b'0' b'1' b'1' b'0' b'0' b'0' b'1' b'1' b'0'
2 -0.090407 0.021198 0.208712 0.102752 0.119315 0.041729 -0.021728 0.019603 -0.063853 -0.053756 ... b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'1' b'1' b'0'
3 -0.085235 0.009540 -0.013228 0.094063 -0.013592 -0.030719 -0.116062 -0.131674 -0.165448 -0.123053 ... b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'1' b'1' b'1'
4 -0.088765 -0.026743 0.002075 -0.043819 -0.005465 0.004306 -0.055865 -0.071484 -0.159025 -0.111348 ... b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0' b'0'
這里用yeast的數(shù)據(jù)做測試朝抖,可以看出樣本數(shù)據(jù)中有14個類別啥箭。
數(shù)據(jù)切分
from sklearn.model_selection import train_test_split
X = df.iloc[:,0:103].values
y = df.iloc[:,103:117].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
數(shù)據(jù)類型轉(zhuǎn)換
import numpy as np
y_train = y_train.astype(np.float64)
y_test = y_test.astype(np.float64)
模型訓練及預測
from skmultilearn.adapt import MLkNN
from sklearn.metrics import accuracy_score
classifier = MLkNN(k=20)
# train
classifier.fit(X_train, y_train)
# predict
predictions = classifier.predict(X_test)
準確率統(tǒng)計
z = predictions.toarray()
[rows, cols] = y_test.shape
zzz = 0
for i in range(rows - 1):
for j in range(cols - 1):
if y_test[i, j] == z[i, j]:
zzz += 1
zzz / (rows*cols)
實驗基于jupyter,下載:
鏈接:鏈接:https://pan.baidu.com/s/1SLo5nZjvrVrJwqgoEvOpoQ 密碼:qge8
點個贊唄~老哥們治宣。