这是我自己亲身遇到的问题,写在这里只是为了自己查看方便,不管问题大小。遇到的问题我是随机选入的,所以有时候上下文可能没有逻辑关系。
输入:某结构的结构参数,总共有7个features。所有数据共5000组
输出:此结构对应的一条曲线,选取曲线上的100个点,故输出共有100个(labels)。
由于这里提到的是SVM算法,所以就算这种问题可以使用DNN之类的模型,也直接略去。
由于sklearn中有相应的包能直接调用,所以选用sklearn。这里要调用MultiOutputRegressor,它又可以调用所有回归器,如这里的SVR。相关语句如下:
from sklearn.multioutput import MultiOutputRegressor
model = MultiOutputRegressor(SVR(kernel='poly', C=1, degree=2, verbose=1,shrinking=0))
SVR中的语意可以自己查,中文文档如下链接:
链接: sklearn中文文档.
#coding=utf-8
from sklearn import metrics
from sklearn.model_selection import train_test_split
from sklearn.svm import SVR
from sklearn.multioutput import MultiOutputRegressor
from sklearn.preprocessing import StandardScaler
import numpy as np
from numpy import random
import pandas as pd
##数据预处理
img_rows, img_cols = 7, 1
all_result = pd.read_csv("result-5000h.csv", header=None).as_matrix()
X_0, Y_0 = np.array(all_result[:, :img_rows]), np.array(all_result[:, img_rows:])
shuffle_idx = np.random.permutation(np.arange(Y_0.shape[0]))
X_0 = X_0[shuffle_idx]
Y_0 = Y_0[shuffle_idx]
def multilabelSVM():
X_train, X_test, Y_train, Y_test = train_test_split(X_0, Y_0, test_size=0.2, random_state=0)
##数据归一化
scaler = StandardScaler()
scaler.fit_transform(X_train)
scaler.transform(X_test)
model = MultiOutputRegressor(SVR(kernel='poly', C=1, degree=2, verbose=1,shrinking=0))
model.fit(X_train, Y_train)
model.score(X_test, Y_test)
predicted = model.predict(X_test)
mse = metrics.mean_squared_error(Y_test, predicted)
print("\nmse:",mse)
print("predicted:",predicted)
if __name__ == '__main__':
multilabelSVM()
似乎没有很好的算法,详见PRML书。来源:链接: 知乎 “萧萧白马”的答案.
解释:我要解决的问题是一维label,不是多维的,形式如下:
[10.2, 20.2, 22.4, 24.5, …, 100]. 这个数组总共100个元素,可以画出一条曲线(横坐标是我自己定义了的,即10.2对应于x1,20.2对应于x2,…)
所以不会出现多维标签问题。
可能可以,但解决我这种一维多标签问题应该是完全可以的。
多维标签可以参考这个链接,但不完整所以我没有细看。来源:链接: 知乎 “NoneSoVile”的答案.
一维多标签问题是完全可以解决的,方式如下:
from sklearn.neighbors import KNeighborsRegressor
from sklearn.multioutput import MultiOutputRegressor
model = MultiOutputRegressor(KNeighborsRegressor())
KNN中的语意可以自己查,中文文档同上。
此外,KNN分类器是可以直接解决多标签分类问题的:
sklearn.neighbors.KNeighborsClassifier
具体语意的中文文档同上。
Multiclass classification 多类分类 意味着一个分类任务需要对多于两个类的数据进行分类。比如,对一系列的橘子,苹果或者梨的图片进行分类。多类分类假设每一个样本有且仅有一个标签:一个水果可以被归类为苹果,也可以 是梨,但不能同时被归类为两类。
Multilabel classification 多标签分类 给每一个样本分配一系列标签。这可以被认为是预测不相互排斥的数据点的属性,例如与文档类型相关的主题。一个文本可以归类为任意类别,例如可以同时为政治、金融、 教育相关或者不属于以上任何类别。
Multioutput regression 多输出分类 为每个样本分配一组目标值。这可以认为是预测每一个样本的多个属性,比如说一个具体地点的风的方向和大小。
Multioutput-multiclass classification and multi-task classification 多输出-多类分类和多任务分类 意味着单个的评估器要解决多个联合的分类任务。这是只考虑二分类的 multi-label classification 和 multi-class classification 任务的推广。 此类问题输出的格式是一个二维数组或者一个稀疏矩阵。
来源:链接: 多类多标签.
警告类型:
WARNING: using -h 0 may be faster
*
optimization finished, #iter = 4078
obj = -10295.123752, rho = 65.395952
nSV = 3917, nBSV = 3915
解释:h参数的描述如下:
-h shrinking : whether to use the shrinking heuristics, 0 or 1 (default 1)
这是一个limsvm缩小启发式的警告,缩小的启发式是为了加速优化。
部分存疑解释如下:这是一个运行时的问题,不是收敛的问题。(来源链接.)
迭代次数达到了上限,却没有达到收敛条件,所以训练结果可能会很差。(来源链接.)
解决方法:将shrinking设置为0或false关闭优化即可。
如果要使用多标签SVM分类器,一定要将输出Y的格式设置成二进制。
Y_enc = MultiLabelBinarizer().fit_transform(Y) ##这一步是设置成二进制
X_train, X_test, Y_train, Y_test = train_test_split(X, Y_enc, test_size=0.2, random_state=0)
model = OneVsRestClassifier(SVC()) ##一对多SVC分类器
model.fit(X_train, Y_train)
如果使用多类别SVM分类器,就不需要将输出Y的格式设置成二进制:
##开头不需要设置成二进制
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,random_state=0)
model = OneVsRestClassifier(SVC())
model.fit(X_train, y_train)
例子链接点击此处
这个例子很适合理解回归。
点击此处