This may sound very newbie, but I was wondering if there's a simple way to achieve something like Amazon's "Customers who viewed this also viewed..".
Theoretically I know you can do clustering, data mining, etc. to do something like this but I am just working on a ruby-on-rails app and want to incorporate something like this to my already existing app (which uses pgsql), and kind of lost.
I'm not looking for a super-sophisticated solution but just want something simple I can just quickly employ.
Any pointers would be appreciated. Thank you!
Amazon is able to pull this off because they have millions of users and a huge inventory which results in billions of data points. They crunch these data to make sense[user profiles, product profiles, likes, dislikes] and build a recommendation engine to help users discover products and drive sales. It makes sense to them.
Since you're not looking into data science and I have no idea of what all data you collect, you could start off by showing other products purchased by users who bought the specific product. Experiment and A/B test to see what works and what doesn't. Iterate on this, to show products bought by others users matching current users age, gender,nationality etc.
This will not be the recommendation engine that you are expecting but might drive some sales.
Related
I finally managed to come up with a really good ML model, with an accuracy over 90%. Great! But now I need to use this in real world :)
My dataset is something like this: every time a user accessed my website in the last 2 years I saved in a database if that user was using a computer or a smartphone, time of the day, week day, where the user is located.. And every time in the future, if the user did a conversion on my website, I would update the database to save that this particular user made a conversion.
I trained my ML algorithm using Naive Bayes (I used [Rubix ML][1] library for PHP which is pretty great, the devs behind it are awesome and kind people) and the results were surprisingly good, it can 90% of the time predict if a user that accessed my website will convert. That's a huge milestone to me!
So now comes the real world part: I need to extract some "logic" from the model. I can save the model weighs/configs to a txt file after training it, and then I can load that configurations and start making predictions on the fly.
BUT I CANT make predictions on the fly on my use case, here is the why: I am using Google Ads to advertise this website and I need to tell Google Ads "hey google, please show my ads only to people using computer, at night, on saturday which are female ate 18-24 age". I need to tell that to Google before running my campaign.
So here comes the real world part: how do I make any sense of those weights/configs saved in the txt file? I would like to know the relationship/interaction that the ML model found on my columns (device, gender, age, location...) and tell google only to run my campaign in the best favorable conditions, I mean, only when I am pretty confident a conversion will be made. I can run my prediction algorithm on Google Ads and tell google every time I participate in an auction "hey google, according to my predictions, this person, using this device, at this time of the day... does not worth my bidding, so please dont show my ads to this person".
THERE IS CLEARLY a relationship between the columns/features (device, gender, age...) because if I analyze the features isolated there is no evident pattern that computer is worth more showing ads than smartphone, same is true to age, gender... There is no clear winner, sure I can see some pretty small fluctuations that some features are better than others, but mostly, it's not clear at all. So I am pretty sure the features are highly dependent on each other.
Do you have any idea on how I can extract some logic from the txt file in order to know which columsn/features are worth more?
I dont know if it will be of any help, but I am providing you my txt file, just so you can see what I am dealing with.
O:31:"Rubix\ML\Classifiers\NaiveBayes":6:{s:8:" * alpha";d:1;s:12:" * logPriors";a:2:{s:3:"sim";d:-1.8178620931306924;s:4:"não";d:-0.1771818088907544;}s:12:" * fitPriors";b:1;s:10:" * weights";a:2:{s:3:"sim";i:604;s:4:"não";i:3120;}s:9:" * counts";a:2:{s:3:"sim";a:68:{i:0;a:2:{i:1;i:241;i:0;i:363;}i:1;a:2:{i:1;i:108;i:0;i:496;}i:2;a:2:{i:0;i:366;i:1;i:238;}i:3;a:2:{i:1;i:359;i:0;i:245;}i:4;a:2:{i:1;i:71;i:0;i:533;}i:5;a:2:{i:0;i:567;i:1;i:37;}i:6;a:2:{i:0;i:241;i:1;i:363;}i:7;a:2:{i:0;i:567;i:1;i:37;}i:8;a:2:{i:0;i:578;i:1;i:26;}i:9;a:2:{i:0;i:581;i:1;i:23;}i:10;a:2:{i:0;i:346;i:1;i:258;}i:11;a:2:{i:0;i:523;i:1;i:81;}i:12;a:2:{i:0;i:442;i:1;i:162;}i:13;a:2:{i:0;i:482;i:1;i:122;}i:14;a:2:{i:0;i:591;i:1;i:13;}i:15;a:2:{i:1;i:24;i:0;i:580;}i:16;a:2:{i:0;i:566;i:1;i:38;}i:17;a:2:{i:0;i:567;i:1;i:37;}i:18;a:2:{i:0;i:564;i:1;i:40;}i:19;a:2:{i:0;i:579;i:1;i:25;}i:20;a:2:{i:0;i:517;i:1;i:87;}i:21;a:2:{i:0;i:596;i:1;i:8;}i:22;a:2:{i:0;i:569;i:1;i:35;}i:23;a:2:{i:0;i:560;i:1;i:44;}i:24;a:2:{i:0;i:563;i:1;i:41;}i:25;a:2:{i:0;i:592;i:1;i:12;}i:26;a:2:{i:0;i:567;i:1;i:37;}i:27;a:2:{i:0;i:561;i:1;i:43;}i:28;a:2:{i:0;i:576;i:1;i:28;}i:29;a:2:{i:0;i:561;i:1;i:43;}i:30;a:2:{i:0;i:575;i:1;i:29;}i:31;a:2:{i:0;i:562;i:1;i:42;}i:32;a:2:{i:0;i:593;i:1;i:11;}i:33;a:2:{i:0;i:599;i:1;i:5;}i:34;a:2:{i:0;i:499;i:1;i:105;}i:35;a:2:{i:0;i:593;i:1;i:11;}i:36;a:2:{i:0;i:555;i:1;i:49;}i:37;a:2:{i:0;i:577;i:1;i:27;}i:38;a:2:{i:0;i:492;i:1;i:112;}i:39;a:2:{i:0;i:506;i:1;i:98;}i:40;a:2:{i:0;i:549;i:1;i:55;}i:41;a:2:{i:0;i:599;i:1;i:5;}i:42;a:2:{i:0;i:564;i:1;i:40;}i:43;a:2:{i:1;i:108;i:0;i:496;}i:44;a:2:{i:0;i:599;i:1;i:5;}i:45;a:2:{i:0;i:472;i:1;i:132;}i:46;a:2:{i:0;i:601;i:1;i:3;}i:47;a:2:{i:0;i:591;i:1;i:13;}i:48;a:2:{i:0;i:580;i:1;i:24;}i:49;a:2:{i:0;i:602;i:1;i:2;}i:50;a:2:{i:0;i:595;i:1;i:9;}i:51;a:2:{i:0;i:600;i:1;i:4;}i:52;a:2:{i:0;i:602;i:1;i:2;}i:53;a:2:{i:0;i:600;i:1;i:4;}i:54;a:2:{i:0;i:596;i:1;i:8;}i:55;a:2:{i:0;i:598;i:1;i:6;}i:56;a:2:{i:0;i:598;i:1;i:6;}i:57;a:2:{i:0;i:602;i:1;i:2;}i:58;a:2:{i:0;i:602;i:1;i:2;}i:59;a:2:{i:0;i:603;i:1;i:1;}i:60;a:2:{i:0;i:599;i:1;i:5;}i:61;a:2:{i:0;i:601;i:1;i:3;}i:62;a:2:{i:0;i:596;i:1;i:8;}i:63;a:2:{i:0;i:602;i:1;i:2;}i:64;a:2:{i:0;i:601;i:1;i:3;}i:65;a:2:{i:0;i:602;i:1;i:2;}i:66;a:1:{i:0;i:604;}i:67;a:1:{i:0;i:604;}}s:4:"não";a:68:{i:0;a:2:{i:0;i:2059;i:1;i:1061;}i:1;a:2:{i:0;i:2600;i:1;i:520;}i:2;a:1:{i:1;i:3120;}i:3;a:1:{i:1;i:3120;}i:4;a:1:{i:1;i:3120;}i:5;a:2:{i:1;i:212;i:0;i:2908;}i:6;a:2:{i:1;i:2059;i:0;i:1061;}i:7;a:2:{i:0;i:2921;i:1;i:199;}i:8;a:2:{i:0;i:2981;i:1;i:139;}i:9;a:2:{i:0;i:2980;i:1;i:140;}i:10;a:1:{i:0;i:3120;}i:11;a:1:{i:0;i:3120;}i:12;a:1:{i:0;i:3120;}i:13;a:2:{i:0;i:2591;i:1;i:529;}i:14;a:2:{i:0;i:3084;i:1;i:36;}i:15;a:2:{i:0;i:3010;i:1;i:110;}i:16;a:2:{i:0;i:2895;i:1;i:225;}i:17;a:2:{i:0;i:2966;i:1;i:154;}i:18;a:2:{i:0;i:2956;i:1;i:164;}i:19;a:2:{i:0;i:2923;i:1;i:197;}i:20;a:2:{i:0;i:2675;i:1;i:445;}i:21;a:2:{i:0;i:3087;i:1;i:33;}i:22;a:2:{i:0;i:2930;i:1;i:190;}i:23;a:2:{i:0;i:2912;i:1;i:208;}i:24;a:2:{i:0;i:2889;i:1;i:231;}i:25;a:1:{i:0;i:3120;}i:26;a:1:{i:0;i:3120;}i:27;a:2:{i:0;i:2944;i:1;i:176;}i:28;a:2:{i:0;i:2876;i:1;i:244;}i:29;a:2:{i:0;i:2972;i:1;i:148;}i:30;a:2:{i:0;i:2958;i:1;i:162;}i:31;a:2:{i:0;i:2823;i:1;i:297;}i:32;a:2:{i:0;i:3039;i:1;i:81;}i:33;a:2:{i:0;i:3068;i:1;i:52;}i:34;a:2:{i:0;i:2586;i:1;i:534;}i:35;a:2:{i:0;i:3078;i:1;i:42;}i:36;a:1:{i:0;i:3120;}i:37;a:2:{i:0;i:2952;i:1;i:168;}i:38;a:2:{i:1;i:551;i:0;i:2569;}i:39;a:1:{i:0;i:3120;}i:40;a:1:{i:0;i:3120;}i:41;a:1:{i:0;i:3120;}i:42;a:1:{i:0;i:3120;}i:43;a:1:{i:0;i:3120;}i:44;a:1:{i:0;i:3120;}i:45;a:1:{i:0;i:3120;}i:46;a:2:{i:0;i:3104;i:1;i:16;}i:47;a:1:{i:0;i:3120;}i:48;a:1:{i:0;i:3120;}i:49;a:2:{i:0;i:3099;i:1;i:21;}i:50;a:1:{i:0;i:3120;}i:51;a:1:{i:0;i:3120;}i:52;a:2:{i:0;i:3104;i:1;i:16;}i:53;a:1:{i:0;i:3120;}i:54;a:1:{i:0;i:3120;}i:55;a:1:{i:0;i:3120;}i:56;a:1:{i:0;i:3120;}i:57;a:1:{i:0;i:3120;}i:58;a:1:{i:0;i:3120;}i:59;a:1:{i:0;i:3120;}i:60;a:1:{i:0;i:3120;}i:61;a:1:{i:0;i:3120;}i:62;a:1:{i:0;i:3120;}i:63;a:1:{i:0;i:3120;}i:64;a:1:{i:0;i:3120;}i:65;a:1:{i:0;i:3120;}i:66;a:1:{i:0;i:3120;}i:67;a:1:{i:0;i:3120;}}}s:8:" * probs";a:2:{s:3:"sim";a:68:{i:0;a:2:{i:1;d:-0.917942259912628;i:0;d:-0.5097261184325736;}i:1;a:2:{i:1;d:-1.7155321038401707;i:0;d:-0.19828995997268575;}i:2;a:2:{i:0;d:-0.5015181380147443;i:1;d:-0.9304164341378038;}i:3;a:2:{i:1;d:-0.5207759546191588;i:0;d:-0.9015484501369516;}i:4;a:2:{i:1;d:-2.1302138670532593;i:0;d:-0.1264841471091196;}i:5;a:2:{i:0;d:-0.06475856734816308;i:1;d:-2.7692938263429285;}i:6;a:2:{i:0;d:-0.917942259912628;i:1;d:-0.5097261184325736;}i:7;a:2:{i:0;d:-0.06475856734816308;i:1;d:-2.7692938263429285;}i:8;a:2:{i:0;d:-0.04557750849631925;i:1;d:-3.1110431200649855;}i:9;a:2:{i:0;d:-0.040409538337876666;i:1;d:-3.228826155721369;}i:10;a:2:{i:0;d:-0.5575552061224552;i:1;d:-0.8500519243697767;}i:11;a:2:{i:0;d:-0.14538830174827225;i:1;d:-2.0001607388050613;}i:12;a:2:{i:0;d:-0.3133102160241788;i:1;d:-1.313129785262552;}i:13;a:2:{i:0;d:-0.22686333241674173;i:1;d:-1.594695630696897;}i:14;a:2:{i:0;d:-0.023373351185308713;i:1;d:-3.767822656454056;}i:15;a:2:{i:1;d:-3.1880041612011136;i:0;d:-0.042129229217403225;}i:16;a:2:{i:0;d:-0.06652068234156232;i:1;d:-2.743318339939668;}i:17;a:2:{i:0;d:-0.06475856734816308;i:1;d:-2.7692938263429285;}i:18;a:2:{i:0;d:-0.0700542549228735;i:1;d:-2.6933079193650067;}i:19;a:2:{i:0;d:-0.0438518825288494;i:1;d:-3.1487834480478325;}i:20;a:2:{i:0;d:-0.15690474380983138;i:1;d:-1.929543171591108;}i:21;a:2:{i:0;d:-0.014962872676712377;i:1;d:-4.209655408733095;}i:22;a:2:{i:0;d:-0.06124362524071867;i:1;d:-2.8233610476132043;}i:23;a:2:{i:0;d:-0.07715908054661809;i:1;d:-2.6002174962989946;}i:24;a:2:{i:0;d:-0.0718257345712555;i:1;d:-2.6692103677859462;}i:25;a:2:{i:0;d:-0.02168558707158898;i:1;d:-3.841930628607778;}i:26;a:2:{i:0;d:-0.06475856734816308;i:1;d:-2.7692938263429285;}i:27;a:2:{i:0;d:-0.07537813617562336;i:1;d:-2.622690352151053;}i:28;a:2:{i:0;d:-0.04903771956121486;i:1;d:-3.0395841560828405;}i:29;a:2:{i:0;d:-0.07537813617562336;i:1;d:-2.622690352151053;}i:30;a:2:{i:0;d:-0.05077232537342326;i:1;d:-3.005682604407159;}i:31;a:2:{i:0;d:-0.07360035792962409;i:1;d:-2.6456798703757523;}i:32;a:2:{i:0;d:-0.020000666706669543;i:1;d:-3.9219733362813143;}i:33;a:2:{i:0;d:-0.009950330853168092;i:1;d:-4.61512051684126;}i:34;a:2:{i:0;d:-0.19227188764712272;i:1;d:-1.7434408919572473;}i:35;a:2:{i:0;d:-0.020000666706669543;i:1;d:-3.9219733362813143;}i:36;a:2:{i:0;d:-0.08611169181873207;i:1;d:-2.4948569806411682;}i:37;a:2:{i:0;d:-0.047306117396936985;i:1;d:-3.0746754758941104;}i:38;a:2:{i:0;d:-0.20637081202662433;i:1;d:-1.6794921673569738;}i:39;a:2:{i:0;d:-0.17836898247813132;i:1;d:-1.8117601359347244;}i:40;a:2:{i:0;d:-0.09696170784279785;i:1;d:-2.3815282953341654;}i:41;a:2:{i:0;d:-0.009950330853168092;i:1;d:-4.61512051684126;}i:42;a:2:{i:0;d:-0.0700542549228735;i:1;d:-2.6933079193650067;}i:43;a:2:{i:1;d:-1.7155321038401707;i:0;d:-0.19828995997268575;}i:44;a:2:{i:0;d:-0.009950330853168092;i:1;d:-4.61512051684126;}i:45;a:2:{i:0;d:-0.24778459757738155;i:1;d:-1.5165308578475607;}i:46;a:2:{i:0;d:-0.006622540760493382;i:1;d:-5.020585624949423;}i:47;a:2:{i:0;d:-0.023373351185308713;i:1;d:-3.767822656454056;}i:48;a:2:{i:0;d:-0.042129229217403225;i:1;d:-3.1880041612011136;}i:49;a:2:{i:0;d:-0.004962789342129014;i:1;d:-5.308267697401205;}i:50;a:2:{i:0;d:-0.01663931900396467;i:1;d:-4.104294893075269;}i:51;a:2:{i:0;d:-0.008285051534106917;i:1;d:-4.797442073635215;}i:52;a:2:{i:0;d:-0.004962789342129014;i:1;d:-5.308267697401205;}i:53;a:2:{i:0;d:-0.008285051534106917;i:1;d:-4.797442073635215;}i:54;a:2:{i:0;d:-0.014962872676712377;i:1;d:-4.209655408733095;}i:55;a:2:{i:0;d:-0.011618387953865076;i:1;d:-4.460969837014002;}i:56;a:2:{i:0;d:-0.011618387953865076;i:1;d:-4.460969837014002;}i:57;a:2:{i:0;d:-0.004962789342129014;i:1;d:-5.308267697401205;}i:58;a:2:{i:0;d:-0.004962789342129014;i:1;d:-5.308267697401205;}i:59;a:2:{i:0;d:-0.003305788134499544;i:1;d:-5.713732805509369;}i:60;a:2:{i:0;d:-0.009950330853168092;i:1;d:-4.61512051684126;}i:61;a:2:{i:0;d:-0.006622540760493382;i:1;d:-5.020585624949423;}i:62;a:2:{i:0;d:-0.014962872676712377;i:1;d:-4.209655408733095;}i:63;a:2:{i:0;d:-0.004962789342129014;i:1;d:-5.308267697401205;}i:64;a:2:{i:0;d:-0.006622540760493382;i:1;d:-5.020585624949423;}i:65;a:2:{i:0;d:-0.004962789342129014;i:1;d:-5.308267697401205;}i:66;a:1:{i:0;d:0;}i:67;a:1:{i:0;d:0;}}s:4:"não";a:68:{i:0;a:2:{i:0;d:-0.41576783929175054;i:1;d:-1.0783198992734933;}i:1;a:2:{i:0;d:-0.1825778356267258;i:1;d:-1.7904790593220103;}i:2;a:1:{i:1;d:0;}i:3;a:1:{i:1;d:0;}i:4;a:1:{i:1;d:0;}i:5;a:2:{i:1;d:-2.6849369353659522;i:0;d:-0.07066444258017576;}i:6;a:2:{i:1;d:-0.41576783929175054;i:0;d:-1.0783198992734933;}i:7;a:2:{i:0;d:-0.0662055087647326;i:1;d:-2.7479117345273405;}i:8;a:2:{i:0;d:-0.045879605750693664;i:1;d:-3.104586678466073;}i:9;a:2:{i:0;d:-0.04621500739730597;i:1;d:-3.0974692106972093;}i:10;a:1:{i:0;d:0;}i:11;a:1:{i:0;d:0;}i:12;a:1:{i:0;d:0;}i:13;a:2:{i:0;d:-0.18604404360321208;i:1;d:-1.7733520945292098;}i:14;a:2:{i:0;d:-0.011922164735889139;i:1;d:-4.435311188431153;}i:15;a:2:{i:0;d:-0.03620157259364352;i:1;d:-3.3366988997630433;}i:16;a:2:{i:0;d:-0.07514334756977041;i:1;d:-2.6256941018030915;}i:17;a:2:{i:0;d:-0.05092248078455562;i:1;d:-3.002803984156131;}i:18;a:2:{i:0;d:-0.05429858122290015;i:1;d:-2.940283627174797;}i:19;a:2:{i:0;d:-0.06552128020570824;i:1;d:-2.757962070380842;}i:20;a:2:{i:0;d:-0.15415067982725836;i:1;d:-1.9459101490553135;}i:21;a:2:{i:0;d:-0.0109501899307106;i:1;d:-4.519868576459216;}i:22;a:2:{i:0;d:-0.06313016036448493;i:1;d:-2.7939556730287474;}i:23;a:2:{i:0;d:-0.06929034411594272;i:1;d:-2.7038948491105663;}i:24;a:2:{i:0;d:-0.07721731996889954;i:1;d:-2.5994917294090674;}i:25;a:1:{i:0;d:0;}i:26;a:1:{i:0;d:0;}i:27;a:2:{i:0;d:-0.058365004989690265;i:1;d:-2.8700793685015484;}i:28;a:2:{i:0;d:-0.08172573752382947;i:1;d:-2.5449708905306503;}i:29;a:2:{i:0;d:-0.048902278077279634;i:1;d:-3.042282795129918;}i:30;a:2:{i:0;d:-0.05362244867516768;i:1;d:-2.952478900268615;}i:31;a:2:{i:0;d:-0.10031950246224468;i:1;d:-2.3491356145699727;}i:32;a:2:{i:0;d:-0.026616306675110037;i:1;d:-3.6395098538111244;}i:33;a:2:{i:0;d:-0.0171220464556412;i:1;d:-4.075937187523255;}i:34;a:2:{i:0;d:-0.18797491888934822;i:1;d:-1.763962354179371;}i:35;a:2:{i:0;d:-0.013868953150876944;i:1;d:-4.285028985381815;}i:36;a:1:{i:0;d:0;}i:37;a:2:{i:0;d:-0.05565221933145465;i:1;d:-2.9163303861523038;}i:38;a:2:{i:1;d:-1.732681054798282;i:0;d:-0.19456792318611196;}i:39;a:1:{i:0;d:0;}i:40;a:1:{i:0;d:0;}i:41;a:1:{i:0;d:0;}i:42;a:1:{i:0;d:0;}i:43;a:1:{i:0;d:0;}i:44;a:1:{i:0;d:0;}i:45;a:1:{i:0;d:0;}i:46;a:2:{i:0;d:-0.005460106707798186;i:1;d:-5.2130157570191615;}i:47;a:1:{i:0;d:0;}i:48;a:1:{i:0;d:0;}i:49;a:2:{i:0;d:-0.007071710602139796;i:1;d:-4.955186647717062;}i:50;a:1:{i:0;d:0;}i:51;a:1:{i:0;d:0;}i:52;a:2:{i:0;d:-0.005460106707798186;i:1;d:-5.2130157570191615;}i:53;a:1:{i:0;d:0;}i:54;a:1:{i:0;d:0;}i:55;a:1:{i:0;d:0;}i:56;a:1:{i:0;d:0;}i:57;a:1:{i:0;d:0;}i:58;a:1:{i:0;d:0;}i:59;a:1:{i:0;d:0;}i:60;a:1:{i:0;d:0;}i:61;a:1:{i:0;d:0;}i:62;a:1:{i:0;d:0;}i:63;a:1:{i:0;d:0;}i:64;a:1:{i:0;d:0;}i:65;a:1:{i:0;d:0;}i:66;a:1:{i:0;d:0;}i:67;a:1:{i:0;d:0;}}}}
As I understand, when a user logs into your site, with his/her details, and you want to show your specific ads (eventually not showing any). According to your server technology, you develop a web component that displays your contents according to your predictions. These contents (pictures/text) would be linked to the actual marketing page, including your site as referer. Then you would be rewarded if clicked.
Maybe you want to show specific Google Ads, ones that you favor. That is Google Ads' job to select ads, I doubt if Google allows your choice. Google has its own prediction algorithms based on the (same) user's actions while browsing on Chrome.
I have a Rails inventory app that is available to global users, allowing them to enter their own inventory information and query those of others.
a British person in London adds 10 units of "bicycle" to the inventory table
a Japanese person adds 2 units of 自転車 (bicycle in Japanese)
a Vietnamese adds 5 units of xe dap (bicycle in Vietnamese)
The British person can query 'bicycle' and it will output all bicycles in the system (17 units) and can show the details of each in their original language, without the users classifying them beforehand. Likewise, the Japanese person can query '自転車', which will show all bicycles.
How can this be done?
The globalize gem requires users to manually translate each record so it's not the correct way. I've heard about machine learning and deep learning but I don't know if it's the right solution for this.
So if stackoverflow is not the right place to ask this? Where should I ask? Quora does not allow long questions.
Machine learning does not seem like a proper solution in this context since you don't have enough experience with it and it's a complex matter to just start with it and learn enough to apply to a real life problem.
Here are a few solutions you could implement today, as long as you understand the requirements and the up/downs for each, you will have to figure those out by yourself.
Since I don't have enough information about your system I'll try and generalize it to something that's likely.
Solutions:
1.Define a limited number of items for your system, like Bike and add
them to a config file or in a items database, each item having it's
unique id and when a user will have to add something they will have
to select from your list. Have a Other item as a catch-all, and
maybe provide a note so the users can add anything to recognize the
item.
2.Similar to the above solution but you give the users a way to add new items into the system, so you have 10 standard items and every user can add items to the site (those being moderated) and other users will have access to them.
3.Have a solid search system in place like Elasticsearch (or anything else), and when the user create items you index that item in the language that is entered, and then use Google translation API (or another translation service) to translate them in all the languages you need and index those for search as well.
I think solution 1 is the best if you are able to implement it followed by solution 2.
I'am creating a new feature for my iOS app. After I publish the app I wants to show the new feature only for 50% of the users, so I can do some testing which version makes more orders. I have no idea how to do it without using some third parties like Optimizely.
Also is it possible to do this using Google Tag Manager(GTM).
So can someone please help me to figure this out.
Thank you very much for your time.:)
It’s hard to do it on your own, though not impossible of course: Optimizelys of the world are just programs. You’ll need to solve these problems:
Targeting: Some algorithm that will assign user session to either control or (one of) treatment(s). This has to be random, of course, or you may as well stop there.
Routing: Send sessios to the targeted experience.
Logging: You’ll need to intelligently log events from sessions as they traverse their targeted experience. These may be many, so be careful not to add latency to your app path. Your statistical analysis will be based on these.
Experience stability: how do you ensure (if you do) that a returning user sees the same experience he’s already seen.
Note as well, that Optimizely will only help you if all your changes are on the device and not on the server. If you need to instrument server changes as well, you’ll have to look into Sitespect or Variant.
I finally figured out how to do the A/B testing with 'Google Tag Manager'(GTM).
In GTM you can create a variable called 'Google Analytics Content Experiment'. With this variable you can select how many percentage of users going to see each Variation(your experiments). You can create up to 10 variations for single experiment.
GTM is so cool and powerful. GTM contains so many features that could save lot of time and I totally recommend it for anyone who is going to do A/B testing.
I have a Rails 3 app that I'm looking to create in-house analytics for. The items I need to track are impressions (and unique impressions), clicks that come from those impressions, and conversions that come from those clicks. And these are all user-specific so each user can see how many impressions, clicks, and conversions they've received.
What is the best way to go about this? Should I create a separate rails app and call it with pixels? Or should I include all the analytics code in the same app?
Also, are there any analytics platforms already out there that I can customize to meet my needs?
Thanks!
Tim
Before you start re-inventing the wheel, Google Analytics provide a developer API (via OAuth, among other choices) that may provide you with the ability to do what you need (provide each user with a view of their own data).
http://code.google.com/apis/analytics/docs/gdata/home.html
Building your own, while it may seem like an initially basic thing to do, could have serious performance implications further down the line, and Google provide a very detailed view of the the data.
If you really want to write your own, I would strongly urge you not to hit the database for each request you want to track. Keep the data in Redis, or one of the alternatives and periodically persist it to the database via a background task.
If, however, you don't want to put your data into the clutches of our Google Overlord :) then you might indeed consider rolling your own. I have twice before - and I'm doing it again right now: better this time, of course!
If your traffic is not very high and you're running on any decent server platform then adding a tracking system is not going to tax your Rails app noticeably (I know that depends on what 'decent server platform' means but this stuff is pretty cheap these days). Writing to a database is typically very fast - you'd have to have shedloads of clicks to not want to do this straightaway. You can probably bypass most if not all of your before_filters and so on to get a lightning response. One app that runs 2.3.9 uses Metal to do this, for example.
In my new tracking system I have an STI table that goes with models derived from an Activity model; in here you can record both impressions and clicks. Impressions are recorded as the page is built and clicks are recorded using AJAX.
I'm not going to bother with fancy graphs and so on - I'm happy with raw numbers - but these could be added, of course.
At the moment my system is just in the usual app/ folder but I'll probably move it to an engine so I can re-use it more easily.
Hope that helps!
BTW I use Google Analytics as well for a range of sites and it's OK - I just like to do this bit myself.
Depending on how you are going to associate Google Analytics data with a specific user then you might need to double-check the privacy implications. Google doesn't allow their data to be associated with any identifying information about the users being tracked.
If there is a problem then you could try out Piwik as it's open source and you can do what you like with it. It's written in PHP, not Ruby so that might be an issue. As #d11wtq mentions, tracking systems can have performance issues if not built in the right way so you'd be better off starting from something that's already proven to work if possible.
I work for a publishing house and we're discussing different ways to sell our content over digital channels.
Besides the web, we're closely watching the development of content publishing on tablets (e.g. iPad) and smartphones (e.g. iPhone). Right now, it looks like there are four different approaches:
Conventional publishing houses release Apps like The Daily, Wired or Time Magazine. Personally I name them Print-Content-Meets-Offline-Website Magazines. Very nice to look at, but slow, very heavy regarding datasize and often inconsistent on the usability side. Besides that: These magazines don't co-exist well in a world where Facebook and Twitter is where users spend most of their time and share content.
Plain and stupid PDF. More or less lightweight, but as interactive and shareable as a granite block. A model mostly used by conventional publishers and apps like Zinio.
Websites with customized views for different devices (like Die Zeit's tablet-enhanced website). Lightweight, but (at least until now) not able to really exploit a hardware platform as a native app can.
Apps like Flipboard, Reeder or Zite go a different way: Relaying on Twitter-, Facebook- and/or syndication-feeds like RSS and Atom, they give the user a very personalized way to consume news and media. Besides that, the data behind it is as lightweight as possible, the architecture to distribute the data is fast and has proven for years to be reliable.
Personally, I think #4 is the way to go. Unluckily the mentioned Apps only distribute free content and as a publishing house we're also interested in distributing paid content.
I did some research googled around and came to the conclusion, that there is no standardized way to protect and sell individual articles in a syndication feed.
My question:
Do you have any hints or ideas how this could be implemented in a plattform-agnostic way? Or is there an existing solution I just haven't found yet?
Update:
This article explains exactly what we're looking for:
"What publishers and developers need is
a standard API that enables
distribution of content for authorized
purposes, monitors its use, offers
standard advertising units and
subscription requirements, and
provides a way to share revenues."
Just brainstorming, so take it for what it's worth:
Feedreaders can't do buying but most of them have at least let you authenticate to feeds, right? If your free feed was authenticated, you would be able to tie the retrieval of atom entries to a given user account. The retrieval could check the user account against purchased articles and make sure they were populated with fully paid content.
For unpurchased content, the feed gets populated with a link that takes you to a Buy The Article page. You adjust that user account and the next time the feed is updated, the feed gets shows the full content. You could even offer "article tracks" or something like that where someone can by everything written by a given author or everything matching some search criteria. You could adjust rates accordingly.
You also want to be able to allow people to refer articles to others via social media sites and blogs and so forth. To facilitate this, the article URLs (and the atom entry ids) would need to be the same whether they are purchased or not. Only the content of the feed changes depending on the status of the account accessing the feed.
The trick, it seems to me, is providing enough enticement to get people to create an account. Presumably, you'd need interesting things to read and probably some percentage of it free so that it leaves people wanting more.
Another problem is preventing redistribution of paid content to free channels. I don't know that there is a way to completely prevent this. You'd need to monitor the usage of your feeds by account to look for access anomalies, but it's a hard problem.
Solution we're currently following:
We'll use the same Atom feed for paid and free content. A paid content entry in the feed will have no content (besides title, summary, etc.). If a user chooses to buy that content, the missing content is fetched from a webservice and inserted into the feed.
Downside: The buying-process is not implemented in any existing feedreader.
Anyone got a better idea?
I was looking for something else, but I've came across with Flattr RSS plugin for WordPress.
I didn't have time to look it through, but maybe you can find some useful ideas in it.