任何机器学习算法都可以找到这种模式:x1 < x2 而无需先生成新特征(例如 x1-x2)吗?
Can any machine learning algorithm find this pattern: x1 < x2 without generating a new feature (e.g. x1-x2) first?
如果我有 2 个特征 x1 和 x2,我知道模式是:
if x1 < x2 then
class1
else
class2
任何机器学习算法都能找到这样的模式吗?那是什么算法?
我知道我可以创建第三个特征 x3 = x1-x2。那么 feature x3 可以很容易地被一些机器学习算法使用。例如,决策树可以使用 x3 和仅 3 个节点(1 个决策和 2 个叶节点)100% 地解决问题。
但是,是否可以在不创建新功能的情况下解决这个问题?如果机器学习算法只能找到这样的模式,这似乎是一个应该可以轻松 100% 解决的问题。
我用不同的内核尝试了 MLP 和 SVM,包括 svg 内核,结果不是很好。作为我尝试过的示例,这是 SVM 只能获得 0.992 分数的 scikit-learn 代码:
import numpy as np
from sklearn.svm import SVC
# Generate 1000 samples with 2 features with random values
X_train = np.random.rand(1000,2)
# Label each sample. If feature "x1" is less than feature "x2" then label as 1, otherwise label is 0.
y_train = X_train[:,0] < X_train[:,1]
y_train = y_train.astype(int) # convert boolean to 0 and 1
svc = SVC(kernel = "rbf", C = 0.9) # tried all kernels and C values from 0.1 to 1.0
svc.fit(X_train, y_train)
print("SVC score: %f" % svc.score(X_train, y_train))
输出运行代码:
SVC score: 0.992000
这是对我的问题的过度简化。真正的问题可能有数百个特征和不同的模式,而不仅仅是 x1 < x2。但是,首先了解如何解决这个简单的模式会很有帮助。
要理解这一点,您必须进入 sklearn
提供的所有参数的设置,尤其是 C
。它还有助于理解 C
的值如何影响分类器的训练过程。
如果您查看 User Guide for SVC 中的等式,该等式有两个主要部分 - 第一部分试图找到解决问题的一小组权重,第二部分试图最小化分类错误。
C
是与错误分类相关的惩罚乘数。如果你减少 C
,那么你会减少惩罚(较低的训练准确性但更好的泛化测试),反之亦然。
尝试将 C
设置为 1e+6
。您会发现您几乎总是 获得 100% 的准确率。分类器学习了模式 x1 < x2。但是当你查看另一个名为 tol
的参数时,它认为 99.2% 的准确度就足够了。这控制了多少错误对您来说可以忽略不计,默认情况下它设置为 1e-3
。如果降低公差,您也可以期望得到类似的结果。
一般来说,我建议您使用 GridSearchCV
(link) 之类的东西来找到超参数的最佳值,例如 C
,因为这会在内部将数据集拆分为训练和验证。这有助于确保您不仅调整超参数以获得良好的训练准确性,而且还确保分类器在实践中表现良好。
如果我有 2 个特征 x1 和 x2,我知道模式是:
if x1 < x2 then
class1
else
class2
任何机器学习算法都能找到这样的模式吗?那是什么算法?
我知道我可以创建第三个特征 x3 = x1-x2。那么 feature x3 可以很容易地被一些机器学习算法使用。例如,决策树可以使用 x3 和仅 3 个节点(1 个决策和 2 个叶节点)100% 地解决问题。
但是,是否可以在不创建新功能的情况下解决这个问题?如果机器学习算法只能找到这样的模式,这似乎是一个应该可以轻松 100% 解决的问题。
我用不同的内核尝试了 MLP 和 SVM,包括 svg 内核,结果不是很好。作为我尝试过的示例,这是 SVM 只能获得 0.992 分数的 scikit-learn 代码:
import numpy as np
from sklearn.svm import SVC
# Generate 1000 samples with 2 features with random values
X_train = np.random.rand(1000,2)
# Label each sample. If feature "x1" is less than feature "x2" then label as 1, otherwise label is 0.
y_train = X_train[:,0] < X_train[:,1]
y_train = y_train.astype(int) # convert boolean to 0 and 1
svc = SVC(kernel = "rbf", C = 0.9) # tried all kernels and C values from 0.1 to 1.0
svc.fit(X_train, y_train)
print("SVC score: %f" % svc.score(X_train, y_train))
输出运行代码:
SVC score: 0.992000
这是对我的问题的过度简化。真正的问题可能有数百个特征和不同的模式,而不仅仅是 x1 < x2。但是,首先了解如何解决这个简单的模式会很有帮助。
要理解这一点,您必须进入 sklearn
提供的所有参数的设置,尤其是 C
。它还有助于理解 C
的值如何影响分类器的训练过程。
如果您查看 User Guide for SVC 中的等式,该等式有两个主要部分 - 第一部分试图找到解决问题的一小组权重,第二部分试图最小化分类错误。
C
是与错误分类相关的惩罚乘数。如果你减少 C
,那么你会减少惩罚(较低的训练准确性但更好的泛化测试),反之亦然。
尝试将 C
设置为 1e+6
。您会发现您几乎总是 获得 100% 的准确率。分类器学习了模式 x1 < x2。但是当你查看另一个名为 tol
的参数时,它认为 99.2% 的准确度就足够了。这控制了多少错误对您来说可以忽略不计,默认情况下它设置为 1e-3
。如果降低公差,您也可以期望得到类似的结果。
一般来说,我建议您使用 GridSearchCV
(link) 之类的东西来找到超参数的最佳值,例如 C
,因为这会在内部将数据集拆分为训练和验证。这有助于确保您不仅调整超参数以获得良好的训练准确性,而且还确保分类器在实践中表现良好。