具有真正价值特征的斯坦福分类器

时间:2017-02-09 15:55:24

标签: java machine-learning classification stanford-nlp text-classification

我想使用Stanford Classifier进行文字分类。我的功能主要是文本功能,但也有一些数字功能(例如句子的长度)。

我开始使用ClassifierExample,如果停止灯为F且{{1},则使用值为100的简单实值功能BROKEN替换当前要素否则,这导致以下代码(除了第10-16行中的0.1函数,这只是原始ClassifierExample类的代码):

makeStopLights()

在我对线性分类器的理解中,特征public class ClassifierExample { protected static final String GREEN = "green"; protected static final String RED = "red"; protected static final String WORKING = "working"; protected static final String BROKEN = "broken"; private ClassifierExample() {} // not instantiable // the definition of this function was changed!! protected static Datum<String,String> makeStopLights(String ns, String ew) { String label = (ns.equals(ew) ? BROKEN : WORKING); Counter<String> counter = new ClassicCounter<>(); counter.setCount("F", (label.equals(BROKEN)) ? 100 : 0.1); return new RVFDatum<>(counter, label); } public static void main(String[] args) { // Create a training set List<Datum<String,String>> trainingData = new ArrayList<>(); trainingData.add(makeStopLights(GREEN, RED)); trainingData.add(makeStopLights(GREEN, RED)); trainingData.add(makeStopLights(GREEN, RED)); trainingData.add(makeStopLights(RED, GREEN)); trainingData.add(makeStopLights(RED, GREEN)); trainingData.add(makeStopLights(RED, GREEN)); trainingData.add(makeStopLights(RED, RED)); // Create a test set Datum<String,String> workingLights = makeStopLights(GREEN, RED); Datum<String,String> brokenLights = makeStopLights(RED, RED); // Build a classifier factory LinearClassifierFactory<String,String> factory = new LinearClassifierFactory<>(); factory.useConjugateGradientAscent(); // Turn on per-iteration convergence updates factory.setVerbose(true); //Small amount of smoothing factory.setSigma(10.0); // Build a classifier LinearClassifier<String,String> classifier = factory.trainClassifier(trainingData); // Check out the learned weights classifier.dump(); // Test the classifier System.out.println("Working instance got: " + classifier.classOf(workingLights)); classifier.justificationOf(workingLights); System.out.println("Broken instance got: " + classifier.classOf(brokenLights)); classifier.justificationOf(brokenLights); } } 应该使分类任务变得非常简单 - 毕竟,我们只需要检查F的值是否大于某个阈值。但是,分类器会在测试集中的每个实例上返回F

现在我的问题是:我做错了什么,我是否需要更改代码的其他部分以及实值功能,或者我对线性分类器的理解是否有问题?

1 个答案:

答案 0 :(得分:1)

您的代码看起来很好。请注意,通常使用最大熵分类器,您可以提供二进制值特征(1或0)。

以下是关于最大熵分类器的更多阅读:http://web.stanford.edu/class/cs124/lec/Maximum_Entropy_Classifiers

查看标题为“基于特征的线性分类器”的幻灯片,以查看最大熵分类器的特定概率计算。

以下是具有1个功能和2个类(“工作”,“已损坏”)的示例案例的公式:

probability(c1) = exp(w1 * f1) / total probability(c2) = exp(w2 * f1) / total total = exp(w1 * f1) + exp(w2 * f1)

w1是“作品”的学习重量,w2是“破碎”的学习重量

分类器选择更高的概率。请注意,f1 =(100或0.1)您的特征值。

如果您考虑具体的示例数据,由于您有(2个类,1个特征,特征总是正数),因此无法构建将该数据分开的最大熵分类器,它将始终以单向猜测或者另一个。

为了争论,请说w1 > w2

v > 0是你的特征值(100或0.1)。

然后是w1 * v > w2 * v,因此exp(w1 * v) > exp(w2 * v),因此无论v具有什么价值,您都会为class1分配更多概率。