Weka XRFFSaver including missing sparse values - weka

I'm using the XRFFSaver class in the current weka dev version. I'm using xrff rather than arff as I have extremely sparse data and the specs here indicate that sparse instances are handled nicely and efficiently (i.e. not included in output).
However using XRFFSaver they are included in the output like this:
<value index="1" missing="yes"/>
<value index="2" missing="yes"/>
...
Which defeats the purpose of the whole exercise. Anyone know if this is operator error or will I need to write my own saver?
I had a quick look at the source and I could not find any way of toggling this behaviour in either XRFFSaver or XMLInstances, however it was a quick look.
tnx

I quickly hacked up a solution to this:
Note: This is in C# (I use weka through ikvm). However, this should be very simple for anyone to convert to Java.
Note2: The only important line is this one: if (sparse) continue which I also highlighted below with comments. Everything else is a straight copy of the weka source which I found through grepcode and google. Not even sure if its the latest version I copied so please use with discretion.
I also tested to ensure that the standard XRFFLoader handles this correctly and it appears it does.
Tnx
// Usage
var saver = new EfficientXRFFSaver();
saver.setCompressOutput(file.EndsWith(".gz"));
saver.setInstances(Instances);
saver.setFile(new java.io.File(file));
saver.writeBatch();
// Implementation
public class EfficientXRFFSaver : XRFFSaver
{
public override void resetOptions() {
base.resetOptions();
setFileExtension(getCompressOutput() ? XRFFLoader.FILE_EXTENSION_COMPRESSED : XRFFLoader.FILE_EXTENSION);
try { m_XMLInstances = new EfficientXMLInstances(); }
catch { m_XMLInstances = null; }
}
}
public class EfficientXMLInstances : XMLInstances
{
protected override void addInstance(Element parent, Instance inst) {
var node = m_Document.createElement(TAG_INSTANCE);
parent.appendChild(node);
var sparse = inst is SparseInstance;
if (sparse) { node.setAttribute(ATT_TYPE, VAL_SPARSE); }
if (inst.weight() != 1.0) { node.setAttribute(ATT_WEIGHT, Utils.doubleToString(inst.weight(), m_Precision)); }
for (var i = 0; i < inst.numValues(); i++) {
var index = inst.index(i);
var value = m_Document.createElement(TAG_VALUE);
if (inst.isMissing(index)) {
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!!!!!!!!! IMPORTANT !!!!!!!!!!!!!
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// This line will not add this element if its missing and sparse.
if (sparse) continue;
value.setAttribute(ATT_MISSING, VAL_YES);
} else {
if (inst.attribute(index).isRelationValued()) {
var child = m_Document.createElement(TAG_INSTANCES);
value.appendChild(child);
for (var n = 0; n < inst.relationalValue(i).numInstances(); n++) {
addInstance(child, inst.relationalValue(i).instance(n));
}
} else {
value.appendChild(inst.attribute(index).type() == weka.core.Attribute.NUMERIC ?
m_Document.createTextNode(Utils.doubleToString(inst.value(index), m_Precision)) :
m_Document.createTextNode(validContent(inst.stringValue(index))));
}
}
node.appendChild(value);
if (sparse) { value.setAttribute(ATT_INDEX, "" + (index + 1)); }
}
}
}

Related

how to check if personID is in my_customers (see my example)

In C++, the interface for this file says
*If no soup left returns OUT_OF_SOUP
* If personID not found in my_customers AND numbBowlsSoupLeft>0 then give this person a bowl of soup (return BOWL_OF_SOUP)
* and record it by creating new customer struct using personID, numbBowlsSoup=1 and adding this struct to my_customers, be sure to decrement numbBowlsSoupLeft.
for my implementation, I'm trying to put
int Soupline::getSoup(int personID) {
if (numBowlsSoupLeft == 0) {
return OUT_OF_SOUP;
}
if (!(personID : my_customers) && numbBowlsSoupLeft > 0) {
}
But that second if statement is giving me syntax errros, I just want to know how to check to see if the personID is IN my_customers?
my_customers was created in the soupline interface using:
std::vector<customer> my_customers; // keeps track of customers
First you want to use find() to search a vector.
Second, please handle the case if numbBowlsSoupLeft < 0, because that can be a huge source of problem.
Third, your syntax error is the (personID : my_customers), the : is for iteration.
int Soupline::getSoup(int personID) {
if (numBowlsSoupLeft <= 0) { // handles negative numBowlsSoupLeft
return OUT_OF_SOUP;
}
bool found_customer = false;
for (auto c : my_customers) {
if (personID == c.person_id()) { // This is my guess on how the id is stored in customer class
// Logic to process soup for customer
found_customer = true;
break;
}
}
if (!found_customer) {
// Logic to process non-customer asking for soup?
}
}
Sorry i dunno what is the return integer is supposed to be, so it is not defined in my code example.

CouchDB view reduce one doc per key

I'm trying to solve what seems like a fairly simple problem with a couchDb view, but I'm not even getting close to the target with my result set.
Rather than updating documents, I'm creating a new document every time as my versioning strategy, and tying those documents together with a versioning field called ver. The very first document in a version chain will see the ver field and the _id field having the same value. All subsequent documents in the chain will have the same ver field as previous docs in the chain, but will have a unique _id field. These documents also have a createdTime field which is my way of knowing which document is the latest.
Here's my documents:
{
"_id": "abcd-1234-efgh-9876",
"ver": "abcd-1234-efgh-9876",
"createdTime": "2020-01-12 01:15:00 PM -0600",
...
},
{
"_id": "uopa-3849-pmdi-1935",
"ver": "abcd-1234-efgh-9876",
"createdTime": "2020-02-16 02:39:00 PM -0600",
...
}
Here's my map function:
function (doc) {
emit(doc.ver, doc);
}
Here's my reduce function:
function(keys, values, rereduce) {
var latestVersions = {};
for (var i = 0; i < keys.length; i++) {
var found = latestVersions[keys[i][0]];
if (!found || found.createdTime < values[i].createdTime) {
latestVersions[keys[i][0]] = values[i];
}
}
return latestVersions;
}
And finally, here's my desired output from the view (just the doc that I want):
{
"_id": "uopa-3849-pmdi-1935",
"ver": "abcd-1234-efgh-9876",
"createdTime": "2020-02-16 02:39:00 PM -0600",
...
}
What am I missing here? The reduce function is returning both records, which is not what I want. Is what I'm trying to achieve possible or is there a better way to go about this?
Update
I was able to get this to work when a single key is used to access the view, which is one of my use cases.
function (keys, values, rereduce) {
var toReturn = values[0];
for (var i = 1; i < values.length; i++) {
if (values[i].createdTime > toReturn.createdTime) {
toReturn = values[i];
}
}
return toReturn;
}
I have another use case that will be returning all of the data in the view, however. The desired result there is the same as above, but the function I'm using for single keys will only ever return one result. How do I filter multiple values with a shared key such that 1 "shared" key:n values -> 1 key:1 value.
I was finally able to resolve this when I stumbled upon this couchbase article. It was much more articulate than some of the other dry computer-science documentation.
I still do not understand why certain items are grouped in a reduce method and other ones are not. For example, reduce was called 5 times for 6 items that shared an identical key; only one of the keys had actually grouped anything -- an array of two documents. It probably has something to do with those dry computer-science B-tree documents I glossed over.
Anyway, I was able to determine that all I needed to do was group the values by the ver field in both scenarios (the only difference being that rereduce had a 2 dimensional array). Here's what my reduce function ended up looking like:
function (keys, values, rereduce) {
var toValues = function(myMap) {
return Object.keys(myMap).map(function(key) {
return myMap[key];
});
}
if (rereduce) {
// values should look like [[{...}, {...}], [{...}]]
var outputMap = {};
for (var i = 0; i < values.length; i++) {
for (var j = 0; j < values[i].length; j++) {
var currentEl = values[i][j];
var found = outputMap[currentEl.ver];
if ((found && found.createdDate < currentEl.createdDate) || !found) {
outputMap[currentEl.ver] = currentEl;
}
}
}
return toValues(outputMap);
} else {
var outputMap = {};
for (var i = 0; i < values.length; i++) {
var found = outputMap[values[i].ver];
if ((found && found.createdDate < values[i].createdDate) || !found) {
outputMap[values[i].ver] = values[i];
}
}
return toValues(outputMap);
}
}

How to dequeueCell in a CCTableView with multiple custom CCTableViewCell’s?

I have a CCTableView that i would like to use multiple custom CCTableViewCells, but it seems that dequeueCell treats all cells as if they were the same. The other option is to have a different cell for each row but this is not performant.
Oh and this is cocos2dx v2.2
I actually came up with a decent solution but it requires adding this member to CCTableView
CCTableViewCell *CCTableView::dequeueCellWithTag(int nTag)
{
CCTableViewCell *cell = NULL;
for (int i = 0, len = m_pCellsFreed->count(); i < len; i++) {
CCTableViewCell *tempCell = (CCTableViewCell*)m_pCellsFreed->objectAtIndex(i);
if (tempCell->getTag() == nTag) {
cell = tempCell;
cell->retain();
m_pCellsFreed->removeObjectAtIndex(i);
cell->autorelease();
break;
}
}
return cell;
}
Basically you do cell->setTag(tagId) on your cell after you create it and then you tableView->dequeueCellWithTag(tagId). Hopefully this could be built in because its pretty standard.
If anyone knows a better way i'm open to suggestions!

Keep old values of a List<SelectItem> for a back to the previous

i don't know if i can clearly explain my problem but i will try :)
I have lot of folder , and each folder depends of an other.
Example :
Document, Pictures , Other depends of root.
Text depends of Documents.
PNG,GIF,JPG depends of Pictures.
The first time i display the list i have :
DOCUMENT
OTHER
PICTURES
When i select for example PICTURES, the list will display PNG,GIF,JPG.
It is always the same list.
And i don't see how come back to the previous list.
I tryed to create a other list for keep the old value but it doesn't work, or i dont know where put the assignement of that value.
public List<SelectItem> getListSelectItemFolder() {
if(mListSelectItemFolder == null)
{
mListSelectItemFolder = new ArrayList<SelectItem>();
List<Folder> lListFolder = getFolderManager().searchFolder(getFolderManager().getRootFolderId(mSessionBean.getUser(), mSessionBean.isNotUserAdminGe()), mSessionBean.getUser().getFirm(), mSessionBean.isNotUserAdminGe());
mListSelectItemFolder.add(new SelectItem(getFolderManager().getById(getFolderManager().getRootFolderId(mSessionBean.getUser(), mSessionBean.isNotUserAdminGe())), "root"));
for (Folder lFolder : lListFolder) {
if(lFolder.getId()>=0)
{
mListSelectItemFolder.add(new SelectItem(lFolder, lFolder.getName()));
}
}
return mListSelectItemFolder;
}
if(getDocument().getFolder()!=null)
{
List<Folder> lListFolder = getFolderManager().searchFolder(mDocument.getFolder().getId(), mSessionBean.getUser().getFirm(), mSessionBean.isNotUserAdminGe());
if(lListFolder.size()>0)
{
mListSelectItemFolder = new ArrayList<SelectItem>();
for (Folder lFolder : lListFolder) {
if(lFolder.getId()>=0)
{
mListSelectItemFolder.add(new SelectItem(lFolder, lFolder.getName()));
}
}
}
}
return mListSelectItemFolder;
}
up please =)
I have created a button, here is the code :
public void backButton()
{
if(mListSelectItemFolder==null || ((Folder) mListSelectItemFolder.get(0).getValue()).getIdDep()==0 )
{
//if the list is null or the parent folder is the first one name rootone (id=0)
mListSelectItemFolder=null;
}
else
{
if(mFolderManager.getById(mFolderManager.getById(((Folder) mListSelectItemFolder.get(0).getValue()).getIdDep()).getIdDep()).getIdDep()==0)
{
//case where we gonna go back in the first level, the start folder
mListSelectItemFolder=null;
}
else
{
getDocument().setFolder(((Folder) mFolderManager.getById(((Folder)mListSelectItemFolder.get(0).getValue()).getIdDep())));
}
}
}

How to update Target object from markup extension in SL5?

I'm trying this code in a markup extension in Silverlight 5.
public override object ProvideValue(IServiceProvider serviceProvider)
{
_target = (IProvideValueTarget)serviceProvider.GetService(typeof(IProvideValueTarget));
_depObj = _target.TargetObject as DependencyObject;
_depProp = _target.TargetProperty as DependencyProperty;
return GetText(TextId, DefaultText);
}
depObj seems to be provided correctly, however depProp seems not to be of type
DependencyProperty (The type is Sytem.String (of System.Reflection.PropertyInfo)). The cast results in null.
depProp is representing to the right Text or Content property, but without it being a
DependencyProperty I cannot set its value.
Any input greatly appreciated.
SiKo
Not sure why its coming up as a PropertyInfo but you can of course set the value with code something like:
if (TargetProperty is DependencyProperty)
{
var dependencyObject = target as DependencyObject;
if (dependencyObject != null)
{
var newValue = GetValue();
dependencyObject.SetValue(TargetProperty as DependencyProperty, newValue);
}
}
else if (TargetProperty is PropertyInfo)
{
var pi = target as PropertyInfo;
pi.SetValue(target, GetValue(), null);
}
The approach #Berryl gave above could work. But if you also need to get to the DependencyProperty, you can use something like this. This code also demonstrates the subtle differences between silverlight and WPF, but both can work great.
For silverlight or WPF only, you can remove the parts before or after the #else to simplify the code a little bit.
But the part that resolves the dependency property is in the middle (assigning _property).
public override object ProvideValue(IServiceProvider serviceProvider)
{
IProvideValueTarget Target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
if (Target == null) {
throw new InvalidOperationException(
"Cannot resolve the IProvideValueTarget. Are you binding to a property?");
}
/* we need the dependency property (for bindings) */
#if SILVERLIGHT
PropertyInfo Property = (PropertyInfo)Target.TargetProperty;
/* resolve the dependency property */
FieldInfo DepPropertyInfo = Target.TargetObject.GetType()
.GetField(Property.Name + "Property", BindingFlags.Static | BindingFlags.Public);
_property = (DependencyProperty)DepPropertyInfo.GetValue(/* obj = */ null);
#else
_property = Target.TargetProperty as DependencyProperty;
#endif
if (_property != null) {
#if SILVERLIGHT
if (Property.Name.StartsWith("Text")) {
UpdateSourceTrigger = UpdateSourceTrigger.Default;
#else
if (_property.Name.StartsWith("Text")) {
UpdateSourceTrigger = UpdateSourceTrigger.LostFocus;
#endif
}
else {
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
}
}