| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Name | Name | Last commit date | ||
|---|---|---|---|---|
I have used Weka for quite some time now. There were quite some things that bothered me. The dataset management was clumsy at best, but I could deal with that. What I couldn't get around was the general slowness of the library. This is not only my complaint, just make a basic google search. The reason for that? Weka doesn't use BLAS (and neither does any other Java machine learning library). Not only that, many times unnecessary data copies are made.
So, here is the manifesto of the QuantumLearn library:
Beware, this library is in really early alpha stage. Do not use in production.
Until the algorithm is implemented in effective Scala code, the algorithm from Weka is wrapped. For now, this causes a dataset copy (but it is done only once).
Let's first create an unlabeled (unsupervised) dataset. We create a matrix and name the features.
val unlabeled = Unlabeled(DenseMatrix(
(16.0,2.0,3.0),
(3.0,11.0,5.5),
(4.0,8.0,10.0),
(5.0,100.0,7.0)
), Vector('x, 'y, 'z))This dataset might be used for clustering or to make predictions on. However, if we want to learn from it, we have to label (supervize) it. Along with the dataset, you can specify a custom cost function, as is shown below with specifying hinge loss for the binary dataset.
val isMale = Binary('isMale, unlabeled, Vector(true, false, true, true), loss = HingeLoss)
val age = Numerical('age, unlabeled, Vector(20.3, 56.8, 10.3, 11.8))
val major = Nominal('major, unlabeled, Vector("ML", "literature", "ML", "art"))You can then group many of those single-labeled datasets into a multi-labeled one.
val labeled = MultiLabeled(isMale, age, major)Finally, to check everything is fine so far, we call labeled.report and get this on the standard output:
x y z isMale age major=ML major=literature major=art 16.00000 2.000000 3.000000 -> 1.000000 20.30000 1.000000 0.00000000000000 0.0000000 3.000000 11.00000 5.500000 -> 0.000000 56.80000 0.000000 1.00000000000000 0.0000000 4.000000 8.000000 10.00000 -> 1.000000 10.30000 1.000000 0.00000000000000 0.0000000 5.000000 100.0000 7.000000 -> 1.000000 11.80000 0.000000 0.00000000000000 1.0000000
This is currently just a proposal. In the future, it should be possible to instantiate an unabeled dataset containing image data. This dataset behaves no differently as the one described above.
Let's create the collection of images, each of which is resized to 40x30 pixels. Moreover, each image is stored five times - the original, translated 1 and 5 pixels to the right and 1 and 3 pixels to the left. Additionally, each images has a 30% chance of appearing rotated by 1, 3 of 5 degrees.
val unlabeledImages = ImageDataset(
Seq("images/bird1.jpg", "images/bird2.jpg", "images/bird3.png"),
height = 40, width = 30,
translations = Seq(1, -1, -3, 5),
rotations = Seq(1.0, 3.0, 5.0), rotationProbability = 0.3
)Say we want to add two new features to the dataset. We can use arbitrary data or reuse existing. Here's how it's done:
val augmented = FeatureAdder(
'isFemale -> (row => !row('isMale)),
'ageInMonths -> (row => row('age) * 12)
).transform(labeled)Everything Weka-connected resides in a qlearn.algorithms.weka package. Some of the Weka algorithms are already nicely wrapped. The ones that are not, you can wrap yourself:
// simple example
WekaWrapper(new J48)
// complex example
WekaWrapper({
val tmp = new J48
tmp.setMinNumObj(10)
tmp.setUseLaplace(true)
tmp
})Once this is done, you can use Weka learners in the same manner as the native ones. It's that simple.
This section presents future ideas for optimization / improvement. We are not in a hurry, first just make sure everything works correctly.
For efficiency (simplicity, memory and coputation) reasons, the X dataset is represented as as simple matrix. This suffices most of the time by simply binarizing the nominal attribures. Some algorithms, such as Naive bayes, requires the higher level of knowledge. This could be solved this way:
val unlabeled = Unlabeled(DenseMatrix(
(1.0,2.0,3.0),
(2.0,11.0,5.5),
(1.0,8.0,10.0),
(3.0,100.0,7.0)
), Vector('hairColor, 'y, 'z), nominal = Seq('hairColor))| Back | FazBrowse Home | New Git URL |