<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Andrei&#039;s Web Mining Blog</title>
	<atom:link href="http://webmining.olariu.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://webmining.olariu.org</link>
	<description>Useless results of curiosity</description>
	<lastBuildDate>Thu, 13 May 2021 15:34:38 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>ML Workshop at Codiax: BERT, Gradient Boosting and Journalism</title>
		<link>http://webmining.olariu.org/ml-workshop-at-codiax-bert-gradient-boosting-and-journalism/</link>
					<comments>http://webmining.olariu.org/ml-workshop-at-codiax-bert-gradient-boosting-and-journalism/#respond</comments>
		
		<dc:creator><![CDATA[Andrei Olariu]]></dc:creator>
		<pubDate>Thu, 13 May 2021 15:32:11 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<guid isPermaLink="false">http://webmining.olariu.org/?p=247</guid>

					<description><![CDATA[Held a workshop today at Codiax 2011 with the title: Matching Journalists with Domain Experts: Text Classification with BERT and Gradient Boosting Trees from Idea to Production. Abstract: We’ll start with a real world challenge: matching journalists interested in writing a story with relevant domain experts. We’ll examine the business use case, convert it into [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Held a workshop today at <a rel="noreferrer noopener" href="https://codiax.co/" target="_blank">Codiax 2011</a> with the title: <strong>Matching Journalists with Domain Experts: Text Classification with BERT and Gradient Boosting Trees from Idea to Production</strong>.</p>



<p>Abstract: We’ll start with a real world challenge: matching journalists interested in writing a story with relevant domain experts. We’ll examine the business use case, convert it into a technical one and discuss a baseline approach. We’ll then work on implementing a better and smarter solution, using a combination of Machine Learning algorithms. We’ll discuss performance, pros and cons, as well as future steps.</p>



<p>I&#8217;ve added the slides (written in jupyter notebook using the RISE extension), along with the support files, on Github: <a rel="noreferrer noopener" href="https://github.com/andreiolariu/codiax_workshop" target="_blank">https://github.com/andreiolariu/codiax_workshop</a></p>



<figure class="wp-block-image size-large"><img fetchpriority="high" decoding="async" width="1024" height="595" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2021/05/guidedpr-1024x595.png" alt="" class="wp-image-249" srcset="http://webmining.olariu.org/wp-content/uploads/sites/2/2021/05/guidedpr-1024x595.png 1024w, http://webmining.olariu.org/wp-content/uploads/sites/2/2021/05/guidedpr-600x348.png 600w, http://webmining.olariu.org/wp-content/uploads/sites/2/2021/05/guidedpr-768x446.png 768w, http://webmining.olariu.org/wp-content/uploads/sites/2/2021/05/guidedpr.png 1338w" sizes="(max-width: 1024px) 100vw, 1024px" /></figure>
]]></content:encoded>
					
					<wfw:commentRss>http://webmining.olariu.org/ml-workshop-at-codiax-bert-gradient-boosting-and-journalism/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Top Ten Finish in the Deep Learning HackerEarth Challenge</title>
		<link>http://webmining.olariu.org/top-ten-finish-in-the-deep-learning-hackerearth-challenge/</link>
					<comments>http://webmining.olariu.org/top-ten-finish-in-the-deep-learning-hackerearth-challenge/#comments</comments>
		
		<dc:creator><![CDATA[Andrei Olariu]]></dc:creator>
		<pubDate>Wed, 01 Nov 2017 14:11:35 +0000</pubDate>
				<category><![CDATA[Kaggle]]></category>
		<guid isPermaLink="false">http://webmining.olariu.org/?p=225</guid>

					<description><![CDATA[If you&#8217;re reading this, you probably know I&#8217;m a big fan of Kaggle. Unfortunately, getting good results in their contests requires a significant time investment, and I&#8217;ve lacked free time lately. But when Catalin Tiseanu&#8216;s proposition to join the Deep Learning HackerEarth Challenge overlapped with an easier period at work, I said sure. The contest was [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>If you&#8217;re reading this, you probably know I&#8217;m a big fan of Kaggle. Unfortunately, getting good results in their contests requires a significant time investment, and I&#8217;ve lacked free time lately. But when <a href="https://www.topcoder.com/members/CatalinT/details/?track=DATA_SCIENCE&amp;subTrack=MARATHON_MATCH" target="_blank" rel="noopener">Catalin Tiseanu</a>&#8216;s proposition to join the <a href="https://www.hackerearth.com/challenge/competitive/deep-learning-challenge-1/" target="_blank" rel="noopener">Deep Learning HackerEarth Challenge</a> overlapped with an easier period at work, I said sure. The contest was only one month long and it was already half way in, so it was a small time commitment. I also brought my colleague Alexandru Hodorogea in as well.</p>
<p>First off, a few words about HackerEarth&#8217;s platform. OMG! You realize just how finessed Kaggle is in comparison. Just to read the challenge statement, you need to have an account and set up a team. That explains why they have over 4000 competitors, yet only ~200 that actually submitted something. If two people have both read the statement and want to form a team, well.. they can&#8217;t. Team merging is allowed, just not possible given the primitive interface. One of them will have to create another account. They have no forum, so it&#8217;s hard to have a conversation, share something, discuss ideas. The organizers are very slow (publishing the final leaderboard took about 10 days, posting the winning solutions still hasn&#8217;t happened and it&#8217;s been one month since it ended).</p>
<p>On top of that, the challenge&#8217;s dataset is <a href="http://www2.informatik.uni-freiburg.de/~eitel/freiburg_groceries_dataset.html" target="_blank" rel="noopener">freely available online</a>. Of course, the rules forbid using any external data. The organizers mentioned they&#8217;ll manually review the code for the winning models. Still, most people are not in this for the money, so having somebody get a perfect score was inevitable. While these are easy to prune, you can still use the dataset in many less obvious ways, making the leaderboard meaningless.</p>
<p>A few words about the data: the training set consists of 3200 images in 25 classes. Another 1700 are in the test set. The images are conveniently small (256&#215;256), usually of good quality, but sometimes blurry or not very clear. I think a human annotator would struggle a bit figuring out what type of product is featured in each photo.</p>
<p><a href="http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/examples.jpg"><img decoding="async" class="aligncenter size-medium wp-image-229" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/examples-600x240.jpg" alt="" width="600" height="240" srcset="http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/examples-600x240.jpg 600w, http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/examples-768x307.jpg 768w, http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/examples-1024x409.jpg 1024w, http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/examples-1000x400.jpg 1000w, http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/examples.jpg 1284w" sizes="(max-width: 600px) 100vw, 600px" /></a></p>
<p>Even though they forbid external data, the rules allow using pretrained models, and that&#8217;s how we started. We used Keras because:<br />
&#8211; it&#8217;s very easy to use<br />
&#8211; it comes packed with high quality pretrained models; I still can&#8217;t believe how easy they are to use; you can have a state-of-the-art model up and running in 10 lines of code<br />
&#8211; it&#8217;s used in Jeremy Howard&#8217;s <a href="http://course.fast.ai/" target="_blank" rel="noopener">MOOC</a> (although he mentioned he&#8217;s going to <a href="http://www.fast.ai/2017/09/08/introducing-pytorch-for-fastai/" target="_blank" rel="noopener">migrate the code to Pytorch</a>)</p>
<p>You&#8217;ve probably guessed this competition requires some serious processing power. On my GTX 760 GPU, getting one model to something usable (~90%) took about 50 hours. Fortunately, Catalin had access to a Tesla K80, which was about 5 times faster. Not only that, but it had 2 cores, so we could work in parallel. That really helped us, especially once we got to the ensembling part.</p>
<p>Before going into what we did and why we did it, <a href="https://github.com/andreiolariu/deelearning-hackerearth" target="_blank" rel="noopener">here is the code</a>. Going through it very fast, we have:<br />
&#8211; a script for preparing the data (preprocess_data.py dooh)<br />
&#8211; a collection of useful functions (util.py)<br />
&#8211; several scripts for training some networks (inc_agg_aug_full.py, inc_agg_aug_full_part_2.py and hodor_resnet.py)<br />
&#8211; the ensembling script (ensemble.py)</p>
<p>Finetuning a pretrained Keras model would get you to about 80% on the leaderboard. Let&#8217;s see how we got to 95%. First thing &#8211; do data augmentation. This is even more important here since the dataset is very small (3200 images, with some classes having less than 100 images). We used <a href="https://github.com/aleju/imgaug" target="_blank" rel="noopener">imgaug</a> and cranked up the knobs as long as our networks were able to learn the data. On the most aggressive setup, an input image (top left corner) would get distorted to what you see below. Surprisingly, the networks were able to generalize to the test data (despite some overfitting).</p>
<p><a href="http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/augment.jpg"><img decoding="async" class="wp-image-228 size-medium aligncenter" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/augment-504x500.jpg" alt="" width="504" height="500" srcset="http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/augment-504x500.jpg 504w, http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/augment-150x150.jpg 150w, http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/augment-768x762.jpg 768w, http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/augment-1024x1016.jpg 1024w, http://webmining.olariu.org/wp-content/uploads/sites/2/2017/11/augment.jpg 1157w" sizes="(max-width: 504px) 100vw, 504px" /></a></p>
<p>Aggressive augmentation got us to around 90-91% for a single network. We managed to push this by an extra ~1% by doing test-time augmentation. Instead of passing each test image once, we generated 10 augmentations and averaged the scores.</p>
<p>Finally, ensembling brought the final ~2% on the table. We didn&#8217;t have time to generate a large variety of models, so we did &#8220;poor man&#8217;s ensembling&#8221;: we added a series of checkpoints in the final stages of training a network, so we&#8217;d have not one, but several slightly different networks after training finished.</p>
<p>Something we put a lot of effort in, but didn&#8217;t work, was pseudolabeling. The idea is simple: train network A on the train data and evaluate on the test data. Then use both the train and test data (with the predicted labels) to train network B. Finally, use network B to generate the final predictions on the test data. We tried several approaches here, but neither worked and we don&#8217;t have an understanding of why it works on some problems and not on others.</p>
<p>Overall, it was a good learning opportunity for us: finetuning pretrained CNN models, working as a team across different time zones, managing GPU resources given a tight deadline and seeing how far we can push a Jupyter Notebook server until we crash it (not very far apparently).</p>
<p>PS: Be sure to check out <a href="https://my.memo.ai/external/LDQ80W6NTcGAp7TtB0s0" target="_blank" rel="noopener">Catalin&#8217;s notes here</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://webmining.olariu.org/top-ten-finish-in-the-deep-learning-hackerearth-challenge/feed/</wfw:commentRss>
			<slash:comments>5</slash:comments>
		
		
			</item>
		<item>
		<title>Mining the Best Cycling Roads around Bucharest with Strava</title>
		<link>http://webmining.olariu.org/strava-roads/</link>
					<comments>http://webmining.olariu.org/strava-roads/#comments</comments>
		
		<dc:creator><![CDATA[Andrei Olariu]]></dc:creator>
		<pubDate>Tue, 30 Aug 2016 09:46:17 +0000</pubDate>
				<category><![CDATA[Curiosity]]></category>
		<guid isPermaLink="false">http://webmining.olariu.org/?p=208</guid>

					<description><![CDATA[This year I tried to do a little more cycling during the week. I have a road bike, so I&#8217;m interested in quality roads &#8211; good tarmac, no potholes, enough shoulder to allow trucks to overtake me and live to talk about it. But I don&#8217;t know all roads around Bucharest. Best roads for biking are [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>This year I tried to do a little more cycling during the week. I have a road bike, so I&#8217;m interested in quality roads &#8211; good tarmac, no potholes, enough shoulder to allow trucks to overtake me and live to talk about it. But I don&#8217;t know all roads around Bucharest. Best roads for biking are the smaller ones, with little traffic, that lead nowhere important. How can I find them?</p>
<p><a href="http://webmining.olariu.org/data-mining-strava/" target="_blank">I&#8217;ve worked on Strava data before</a> and I saw here an opportunity to do it again. Using <a href="https://github.com/andreiolariu/strava-roads/blob/master/crawl_strava.py" target="_blank">this simple script</a>, I downloaded (over the course of several days) a total of 6 GB of GPS tracks. I started with the major Strava bike clubs in Bucharest, took all their members, then fetched all rides between April and the middle of June. Starting from 9 clubs, I looked over 1414 users. Only 674 have biked during the analyzed period. The average number of rides for those two and a half months was 25, with the [10, 25, 50, 75, 90]-percentile values of [2, 6, 17, 36, 64]. These are reasonable values, considering there are people that are commuting by bike (even over 20 km per day).</p>
<p>Ok, how can you determine the road quality from 6 GB of data? Simplest solution: take the speed every second (you already have that from Strava) and put it on a map. I did this by converting (lat, lng) pairs to (x, y) coordinates on an image. Each pixel was essentially a bucket, holding a list of speed values.</p>
<p>Let&#8217;s check out the area around Bucharest (high res version <a href="http://webmining.olariu.org/wp-content/uploads/sites/2/2016/08/chart-1.jpg" target="_blank">available here</a>):</p>
<p><a href="http://webmining.olariu.org/wp-content/uploads/sites/2/2016/07/chart_all_small.jpg"><img loading="lazy" decoding="async" class="alignnone wp-image-209 size-medium" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2016/07/chart_all_small-600x461.jpg" alt="chart_all_small" width="600" height="461" srcset="http://webmining.olariu.org/wp-content/uploads/sites/2/2016/07/chart_all_small-600x461.jpg 600w, http://webmining.olariu.org/wp-content/uploads/sites/2/2016/07/chart_all_small-768x590.jpg 768w, http://webmining.olariu.org/wp-content/uploads/sites/2/2016/07/chart_all_small-1024x787.jpg 1024w, http://webmining.olariu.org/wp-content/uploads/sites/2/2016/07/chart_all_small.jpg 1227w" sizes="auto, (max-width: 600px) 100vw, 600px" /></a></p>
<p>In this chart, bright green lines signal roads where there are many riders going over 35 kmph (technically speaking, the 80th percentile is at 35). On the opposite side, red roads are those where you&#8217;ll be lucky going with 25 kmph. The color intensity signals how popular a route is, with rarely used roads being barely visible. I already knew the good roads north of Bucharest, with Moara Vlasiei, Dascalu, Snagov and Izvorani. I saw on Strava that the SE ride to Galbinasi is popular, but I&#8217;ve never ridden it. From this analysis, I can see there are many good roads to the south and a couple of segments to the west. Unfortunately for me, for anything that&#8217;s not in the north I have to cross Bucharest, which is a buzzkill. Also notice the course from Prima Evadare (the jagged red line in the north) and the MTB trails in Cernica, Baneasa and Comana.</p>
<p>Let&#8217;s zoom in a little and see how the city looks like:</p>
<p><a href="http://webmining.olariu.org/wp-content/uploads/sites/2/2016/08/chart.jpg"><img loading="lazy" decoding="async" class="alignnone wp-image-214 size-medium" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2016/08/chart-563x500.jpg" alt="chart" width="563" height="500" srcset="http://webmining.olariu.org/wp-content/uploads/sites/2/2016/08/chart-563x500.jpg 563w, http://webmining.olariu.org/wp-content/uploads/sites/2/2016/08/chart-768x681.jpg 768w, http://webmining.olariu.org/wp-content/uploads/sites/2/2016/08/chart-1024x909.jpg 1024w, http://webmining.olariu.org/wp-content/uploads/sites/2/2016/08/chart.jpg 1207w" sizes="auto, (max-width: 563px) 100vw, 563px" /></a></p>
<p>For this chart, I relaxed the colors a little, with 35 kmph for green and only 20 kmph for red. Things to notice:</p>
<ul>
<li>the RedBull MoonTimeBike course in Tineretului (in red); notice that the whole of Tineretului or Herastrau are red; it means you can&#8217;t (and shouldn&#8217;t) bike fast in parks; please don&#8217;t bike fast in parks, it&#8217;s unpleasant (and dangerous) for bikers and pedestrians alike</li>
<li>the abandoned road circuit in Baneasa (in bright green)</li>
<li>National Arena in green</li>
<li>the two slopes around The People&#8217;s Palace in green (from how it&#8217;s built, all slopes will be green, which is not a problem, since Bucharest is pretty much flat)</li>
</ul>
<p><a href="https://github.com/andreiolariu/strava-roads" target="_blank">Full code available here.</a></p>
]]></content:encoded>
					
					<wfw:commentRss>http://webmining.olariu.org/strava-roads/feed/</wfw:commentRss>
			<slash:comments>7</slash:comments>
		
		
			</item>
		<item>
		<title>7th Place in Kaggle&#8217;s Driver Telematics Challenge</title>
		<link>http://webmining.olariu.org/kaggle-driver-telematics/</link>
					<comments>http://webmining.olariu.org/kaggle-driver-telematics/#comments</comments>
		
		<dc:creator><![CDATA[Andrei Olariu]]></dc:creator>
		<pubDate>Tue, 17 Mar 2015 08:17:23 +0000</pubDate>
				<category><![CDATA[Kaggle]]></category>
		<guid isPermaLink="false">http://webmining.olariu.org/?p=203</guid>

					<description><![CDATA[Intro The purpose of the AXA Driver Telematics Challenge was to discover outliers in a dataset of trips. We were given a total of 2730 drivers, each with 200 trips. We were told that a few of those 200 trips per driver weren&#8217;t actually his and the task was to identify which ones. Somewhat similar [&#8230;]]]></description>
										<content:encoded><![CDATA[<p><strong>Intro</strong><br />
The purpose of the <a href="https://www.kaggle.com/c/axa-driver-telematics-analysis" target="_blank">AXA Driver Telematics Challenge</a> was to discover outliers in a dataset of trips. We were given a total of 2730 drivers, each with 200 trips. We were told that a few of those 200 trips per driver weren&#8217;t actually his and the task was to identify which ones. Somewhat similar to authorship attribution on texts.</p>
<p>A drive was composed of a series of GPS measurements taken each second. Each drive started at (0, 0) and all the other points were given relative to the origin, in meters. In order to make it harder to match trips to road networks, the trips were randomly rotated and parts from the start and the end were removed.</p>
<p>If the dataset would have been composed of only one driver, then this would actually be outlier detection. But more drivers means more information available. Using a classification approach makes it possible to incorporate that extra info.</p>
<p><strong>System Overview</strong><br />
<strong> Local Testing</strong><br />
For each driver, take 180 trips and label them as 1s. Take 180 trips from other drivers and label them as 0s. Train and test on the remaining 20 trips from this driver and on another 20 trips from other drivers. That&#8217;s it.</p>
<p>Can we improve on this? Yes. Take more than just 180 trips from other drivers. Best results I&#8217;ve got were with values between 4&#215;180 and 10&#215;180. In order to avoid an unbalanced training set, I also duplicated the data from the current driver.</p>
<p>Considering there were trips from other drivers that I was labeling as 1s when testing locally, it wasn&#8217;t possible to get the same score locally as on the leaderboard. Yet the difference between the two scores was very predictable, at around 0.045, with variations of around 0.001. The only times I was unsure of my submissions were when I had a data sampling bug and when I tried a clustering approach using the results from local testing.</p>
<p><strong>Leaderboard Submissions</strong><br />
Pretty much the same logic as above. Train on 190 trips from this driver, along with 190 trips from other drivers, test on the remaining 10 trips from this driver. Repeat 20 times, in order to cover all trips (similar to crossvalidation). If the process was too slow, then repeat 10 times with 180+20 splits. Also apply the data enlargement trick used in local testing.</p>
<p><strong>Ensembling</strong><br />
In production systems, you usually try to balance the system&#8217;s performance with the computational resources it needs. In Kaggle competitions, you don&#8217;t. Ensembling is essential in getting top results. I used a linear model to combine together several predictions. The <a href="http://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Lasso.html" target="_blank">Lasso model in sklearn</a> gave the best results, mainly because it is able to compute nonnegative weights. Having a linear blend with negative weights is just wrong.</p>
<p><strong>Caching</strong><br />
When you have an ensemble (but not only then), you will need the same results again and again for different experiments. Having a system for caching results will make your life easier. I cached results for each model, both for local validation, as well as leaderboard submissions. With some models needing a couple of days to run (with 4 cores at 100%), caching proved useful.</p>
<p><strong>Feature Extraction</strong><br />
<strong> Trip Features</strong><br />
These were the best approaches overall, with a maximum local score of 0.877 using Gradient Boosting Trees (that would be an estimated LB score of about 0.922). Some of the features used were histograms and percentiles over speeds, accelerations, angles, speed * angles, accelerations over accelerations, speeds and accelerations over larger windows.</p>
<p><strong>Road segment features</strong><br />
I&#8217;ve seen a lot of talk on the forum of matching trips using Euclidean distance. I tried to go a little further and detect similar road segments. This approach should detect repeated trips, but it should also detect if different trips have certain segments in common. I applied a trajectory simplification algorithm (<a href="http://en.wikipedia.org/wiki/Ramer%E2%80%93Douglas%E2%80%93Peucker_algorithm" target="_blank">Ramer-Douglas-Peucker</a> available for Python <a href="https://pypi.python.org/pypi/rdp" target="_blank">here</a>), then I binned the resulting segments and applied SVMs or Logistic Regression, like on a text corpus. Local results went up to 0.812 (estimated LB score of around 0.857).</p>
<p>One thing I didn&#8217;t like about the RDP algorithm was how similar curves could be segmented differently due to how the threshold used by the algorithm was affected by GPS noise. So I built another model. I thought the best way to encode a trip was as a list of instructions, similar to Google Maps directions. I looked at changes in heading, encoding them as left or right turns. This model scored up to 0.803 locally, lower than the RDP model, but in the final ensemble it got a bigger weight.</p>
<p><strong>Movement features</strong><br />
I think these types of features best capture somebody&#8217;s driving style, although to some degree they also capture particular junction shapes and other road features. The main idea is to compute a few measurements each second, bin them, then treat them as text data and apply SVMs or Logistic Regression. For example, the best scoring model in this category (local score of just under 0.87) binned together the distances and the angles computed over 3-second intervals on smoothed versions of the trips (smoothing done using the <a href="http://en.wikipedia.org/wiki/Savitzky%E2%80%93Golay_filter" target="_blank">Savitzky-Golay</a> filter in <a href="http://docs.scipy.org/doc/scipy-dev/reference/generated/scipy.signal.savgol_filter.html" target="_blank">scipy</a>). After binning and converting to text data, I applied Logistic Regression on n-grams, with n between 1 and 5.</p>
<p>I tested over 100 individual models to select a final ensemble of 23 models. Local score was 0.9195 and the final LB score was 0.9645 (public LB), <a href="https://www.kaggle.com/c/axa-driver-telematics-analysis/leaderboard" target="_blank">0.9653 (private LB)</a>.</p>
<p>My code is available on <a href="https://github.com/andreiolariu/kaggle-driver-telematics" target="_blank">GitHub</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://webmining.olariu.org/kaggle-driver-telematics/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title>PhD Achievement Unlocked</title>
		<link>http://webmining.olariu.org/phd-achievement-unlocked/</link>
					<comments>http://webmining.olariu.org/phd-achievement-unlocked/#comments</comments>
		
		<dc:creator><![CDATA[Andrei Olariu]]></dc:creator>
		<pubDate>Tue, 17 Feb 2015 09:26:28 +0000</pubDate>
				<category><![CDATA[Research]]></category>
		<guid isPermaLink="false">http://webmining.olariu.org/?p=195</guid>

					<description><![CDATA[Thesis available here.]]></description>
										<content:encoded><![CDATA[<p>Thesis available <a href="http://bit.ly/aolariu_phd" target="_blank">here</a>.<br />
<div id="attachment_196" style="width: 610px" class="wp-caption aligncenter"><a href="http://webmining.olariu.org/wp-content/uploads/sites/2/2015/02/IMG_20141024_092809.jpg"><img loading="lazy" decoding="async" aria-describedby="caption-attachment-196" class="wp-image-196 size-medium" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2015/02/IMG_20141024_092809-600x414.jpg" alt="IMG_20141024_092809" width="600" height="414" srcset="http://webmining.olariu.org/wp-content/uploads/sites/2/2015/02/IMG_20141024_092809-600x414.jpg 600w, http://webmining.olariu.org/wp-content/uploads/sites/2/2015/02/IMG_20141024_092809-1024x707.jpg 1024w, http://webmining.olariu.org/wp-content/uploads/sites/2/2015/02/IMG_20141024_092809.jpg 1200w" sizes="auto, (max-width: 600px) 100vw, 600px" /></a><p id="caption-attachment-196" class="wp-caption-text">The view from on stage while my supervisor, Prof PhD Denis Enachescu, was reading his report.</p></div></p>
]]></content:encoded>
					
					<wfw:commentRss>http://webmining.olariu.org/phd-achievement-unlocked/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
			</item>
		<item>
		<title>Online Summarization of Microblogging Streams &#8211; Best Short Paper at EACL 2014</title>
		<link>http://webmining.olariu.org/online-summarization-of-microblogging-streams-my-paper-at-eacl-2014/</link>
					<comments>http://webmining.olariu.org/online-summarization-of-microblogging-streams-my-paper-at-eacl-2014/#comments</comments>
		
		<dc:creator><![CDATA[Andrei Olariu]]></dc:creator>
		<pubDate>Thu, 24 Apr 2014 10:10:25 +0000</pubDate>
				<category><![CDATA[Research]]></category>
		<guid isPermaLink="false">http://webmining.olariu.org/?p=173</guid>

					<description><![CDATA[In a couple of days I&#8217;ll be leaving for Sweden, for the 2014 edition of the EACL conference. The paper I&#8217;ll be presenting is about a fast online algorithm for summarizing Twitter streams. You can check it out on the ACL website. Here are the slides: This research has received the EACL 2014 Best Short [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>In a couple of days I&#8217;ll be leaving for Sweden, for the <a href="http://eacl2014.org/" target="_blank">2014 edition of the EACL conference</a>. The paper I&#8217;ll be presenting is about a fast online algorithm for summarizing Twitter streams. You can check it out <a href="http://www.aclweb.org/anthology/E/E14/E14-4046.pdf" target="_blank">on the ACL website</a>.</p>
<p>Here are the slides:<br />
<script class="speakerdeck-embed" type="text/javascript" src="//speakerdeck.com/assets/embed.js" async="" data-id="ea3c2990adc401311d313e814ed3dd4c" data-ratio="1.33333333333333"></script></p>
<p>This research has received the EACL 2014 Best Short Paper award. Yay!</p>
<p><a href="http://webmining.olariu.org/wp-content/uploads/sites/2/2014/04/DSC_2499.jpg"><img loading="lazy" decoding="async" class="size-medium wp-image-181 aligncenter" alt="DSC_2499" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2014/04/DSC_2499-600x400.jpg" width="600" height="400" srcset="http://webmining.olariu.org/wp-content/uploads/sites/2/2014/04/DSC_2499-600x400.jpg 600w, http://webmining.olariu.org/wp-content/uploads/sites/2/2014/04/DSC_2499-1024x682.jpg 1024w, http://webmining.olariu.org/wp-content/uploads/sites/2/2014/04/DSC_2499.jpg 1200w" sizes="auto, (max-width: 600px) 100vw, 600px" /></a></p>
]]></content:encoded>
					
					<wfw:commentRss>http://webmining.olariu.org/online-summarization-of-microblogging-streams-my-paper-at-eacl-2014/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Data Mining Strava: Running for the World Record. And Beyond</title>
		<link>http://webmining.olariu.org/data-mining-strava/</link>
					<comments>http://webmining.olariu.org/data-mining-strava/#comments</comments>
		
		<dc:creator><![CDATA[Andrei Olariu]]></dc:creator>
		<pubDate>Sun, 17 Nov 2013 21:51:46 +0000</pubDate>
				<category><![CDATA[Curiosity]]></category>
		<category><![CDATA[regression]]></category>
		<category><![CDATA[run]]></category>
		<category><![CDATA[strava]]></category>
		<category><![CDATA[svr]]></category>
		<guid isPermaLink="false">http://webmining.olariu.org/?p=150</guid>

					<description><![CDATA[I&#8217;ve been running a little more seriously this year. On Strava, I&#8217;ve registered 427km, including a few contests: EcoMarathon (14km +600m), San Francisco Marathon (41km), Golden Gate Trail Run (30km, +1200m) and Piatra Craiului Marathon (38km, +2300m). During these races I&#8217;ve noticed I&#8217;m really slow &#8211; finishing somewhere in the last 10% &#8211; 20% in [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>I&#8217;ve been running a little more seriously this year. On <a href="http://www.strava.com/athletes/434554" target="_blank">Strava</a>, I&#8217;ve registered 427km, including a few contests: <a href="http://blog.olariu.org/ecomarathon-2013-trail-running-awesomeness/" target="_blank">EcoMarathon</a> (14km +600m), <a href="http://blog.olariu.org/first-marathon/" target="_blank">San Francisco Marathon</a> (41km), <a href="http://blog.olariu.org/golden-gate-trail-run/" target="_blank">Golden Gate Trail Run</a> (30km, +1200m) and <a href="http://blog.olariu.org/piatra-craiului-marathon/" target="_blank">Piatra Craiului Marathon</a> (38km, +2300m). During these races I&#8217;ve noticed I&#8217;m really slow &#8211; finishing somewhere in the last 10% &#8211; 20% in my category. So the questions that emerged in my mind were:<br />
&#8211; taking training out of the equation, am I just slower than others?<br />
&#8211; how important is training in improving my running pace? If I trained more, how much should I expect to improve?</p>
<p><strong>Analysis Procedure</strong></p>
<p>I chose as reference the personal record over 10 kilometers. I would get this info about a bunch of users, along with how much they&#8217;ve run this year. I would remove users that are new to Strava &#8211; since I can&#8217;t determine if they just started running of if they just started using Strava, yet having already ran a lot.</p>
<p>Having this data, I would see how much the 10k time improves as an athlete trains more. I would also see how I stand compared to other having similar training and how much I can expect to improve, given more training.</p>
<p><strong>Getting the Data</strong></p>
<p>First off, let&#8217;s get some data out of Strava, so I have people to compare myself to. Since Strava doesn&#8217;t have a public API, I had to scrape their website. I got a list of users from a monthly running challenge. Scraping here was straightforward &#8211; the call didn&#8217;t require authentication and gave data in JSON. In the end, I had 17000 ids for active Strava users.</p>
<p>Then, I needed some statistics on each user. Since those statistics required authentication, I used <a href="https://github.com/loisaidasam/stravalib-scraper" target="_blank">a script that handled all that</a>, so I could access the site from within Python. Worked a little more on getting the data out of HTML format.</p>
<p>After removing users that started using Strava recently, I was left with around 7000 data points. I also had to remove users having erroneous GPS tracks &#8211; appears Garmin has a bug that sometimes sends you to the point with coordinates (0, 0):<br />

<a href='http://webmining.olariu.org/data-mining-strava/strava-error1/'><img loading="lazy" decoding="async" width="150" height="150" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2013/11/strava-error1-150x150.png" class="attachment-thumbnail size-thumbnail" alt="" /></a>
<a href='http://webmining.olariu.org/data-mining-strava/strava-error2/'><img loading="lazy" decoding="async" width="150" height="150" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2013/11/strava-error2-150x150.png" class="attachment-thumbnail size-thumbnail" alt="" /></a>
</p>
<p>I also removed people that were very slow. If you need more than 2 hours for 10km, you&#8217;re walking. And you&#8217;re also messing up my chart.</p>
<p><strong>Analysis</strong></p>
<p>I put all the points on a scatter plot. I trained an SVR on them, so I could also show a pretty line (in green). You can see my record on the chart as a red point.<br />

<a href='http://webmining.olariu.org/data-mining-strava/strava-chart1/'><img loading="lazy" decoding="async" width="150" height="150" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2013/11/strava-chart1-150x150.png" class="attachment-thumbnail size-thumbnail" alt="" /></a>
<a href='http://webmining.olariu.org/data-mining-strava/strava-chart2/'><img loading="lazy" decoding="async" width="150" height="150" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2013/11/strava-chart2-150x150.png" class="attachment-thumbnail size-thumbnail" alt="" /></a>
</p>
<p>You can see some fishy stuff on the chart. The fishiest is the group of points very similar to the 10k World Record (26:17 or 1577 seconds). I looked over a couple of the tracks that generated those points and they seem to be mislabeled bike rides. Yet, I can&#8217;t explain why there are so many points around the world record value. Most likely a Strava bug.</p>
<p>There are a lot of people faster than the World Record. Some of them are going up to over 500 kmph. Mislabeled&#8230; flight?</p>
<p>Let&#8217;s zoom on the area with the highest concentration of points. It looks like this:<br />
<a href="http://webmining.olariu.org/wp-content/uploads/sites/2/2013/11/strava-chart3.png"><img loading="lazy" decoding="async" class="size-medium wp-image-153 aligncenter" alt="strava-chart3" src="http://webmining.olariu.org/wp-content/uploads/sites/2/2013/11/strava-chart3-300x195.png" width="300" height="195" srcset="http://webmining.olariu.org/wp-content/uploads/sites/2/2013/11/strava-chart3-300x195.png 300w, http://webmining.olariu.org/wp-content/uploads/sites/2/2013/11/strava-chart3-1024x667.png 1024w, http://webmining.olariu.org/wp-content/uploads/sites/2/2013/11/strava-chart3.png 1178w" sizes="auto, (max-width: 300px) 100vw, 300px" /></a></p>
<p>What you can notice from this chart:<br />
&#8211; if you train more, you get faster. The improvement is not linear &#8211; it takes more training to improve the better you become;<br />
&#8211; I am indeed slower than other people with similar training.</p>
<p>The SVR model estimated an average runner, having the same training as me, would be 5 minutes faster. Another result from the model: I would need 867km of running in order to reach a time of 50 minutes. Hmm&#8230; seems science is telling me to move on to a new sport.</p>
<p><a href="https://github.com/andreiolariu/data-mining-strava" target="_blank">All code is available on Github.</a></p>
]]></content:encoded>
					
					<wfw:commentRss>http://webmining.olariu.org/data-mining-strava/feed/</wfw:commentRss>
			<slash:comments>9</slash:comments>
		
		
			</item>
		<item>
		<title>Trees, Ridges and Bulldozers made in 1000 AD</title>
		<link>http://webmining.olariu.org/trees-ridges-and-bulldozers-made-in-1000-ad/</link>
					<comments>http://webmining.olariu.org/trees-ridges-and-bulldozers-made-in-1000-ad/#comments</comments>
		
		<dc:creator><![CDATA[Andrei Olariu]]></dc:creator>
		<pubDate>Mon, 22 Apr 2013 11:35:55 +0000</pubDate>
				<category><![CDATA[Kaggle]]></category>
		<category><![CDATA[bulldozer]]></category>
		<category><![CDATA[kaggle]]></category>
		<category><![CDATA[randomforest]]></category>
		<category><![CDATA[regression]]></category>
		<guid isPermaLink="false">http://webmining.olariu.org/?p=138</guid>

					<description><![CDATA[New Kaggle contest! Estimating auction price for second hand construction equipment. Didn&#8217;t know bulldozer auctions were such a big thing. We had lots of historical data (400000 auctions, starting from 1989) and we had to estimate prices a few months &#8220;into the future&#8221; (2012). Getting to know the data Data cleaning is a very important [&#8230;]]]></description>
										<content:encoded><![CDATA[<p>New Kaggle contest! Estimating auction price for second hand construction equipment. Didn&#8217;t know bulldozer auctions were such a big thing. We had lots of historical data (400000 auctions, starting from 1989) and we had to estimate prices a few months &#8220;into the future&#8221; (2012).</p>
<p><strong>Getting to know the data</strong></p>
<p>Data cleaning is a very important step when analyzing most datasets, including this one. There were a lot of noisy values. For example, a lot of the equipment appeared to have been made in the year 1000. I&#8217;m no expert in bulldozers, but the guys who are (providing us the data) told us that&#8217;s noise. So, to help the competitors, they provided an index with info regarding each bulldozer in the dataset. After &#8220;correcting&#8221; the train/test data using the index, I got worse results for my model. In the end, I used the index only for filling in missing values. Other competitors used the original data along with the index data &#8211; that might have worked a little better.</p>
<p><strong>Building the model</strong></p>
<p>My first model was composed out of two Random Forest Regressors and two Gradient Boosting Regressors (python using sklearn), averaged using equal weights. The parameters were set by hand, after very little testing.</p>
<p>A first idea of improving came after noticing a lot of the features were relative to the bulldozer category. There were six categories: &#8216;Motorgrader&#8217;, &#8216;Track Type Tractor, Dozer&#8217;, &#8216;Hydraulic Excavator, Track&#8217;, &#8216;Wheel Loader&#8217;, &#8216;Skid Steer Loader&#8217; and &#8216;Backhoe Loader&#8217;. So I segmented the data by category and trained instances of the first model (2 RFR + 2 GBR) on each subset. This generated a fair improvement.</p>
<p>I continued on this line by segmenting the data even more, based on subcategory. There were around 70 subcategories. Again, segmenting and training 70 models generated another improvement. By this time, the first model (trained on the whole data), wasn&#8217;t contributing at all compared to the other two, so I removed it from the equation. With this setup, I was on 10th place on the public leaderboard one week before the end of the competition. The hosts released the leaderboard dataset, so we could also train on it, and froze the leaderboard (no use for it when you can train on the leaderboard data).</p>
<p><strong>Putting the model on steroids</strong></p>
<p>Usually, when you want to find the best parameters for a model, you do grid search. For my &#8220;2 RFR + 2 GBR&#8221; model, I just tested a few parameters by hand. Time to put the Core i7 to work! But instead of grid seach, which tries all combinations and keeps the best, I tried all combinations and kept the best 20-30. Afterwards, I combined them using a linear model (in this case &#8211; Ridge Regression).</p>
<p>I also tried other models (besides RFR and GBR) to add to the cocktail. While nothing even approached the performance GBR was getting, some managed to improve the overall score. I kept NuSVR and Lasso, also trained on (sub)categories.</p>
<p><strong>Outcome and final thoughts</strong></p>
<p>Based on my model&#8217;s improvement over the final week (the one with the frozen leaderboard) and my estimation over my competitors&#8217; improvements, I expected a final ranking of 5th &#8211; 7th. Unfortunately, I came 16th. I&#8217;ve made two errors in my process:</p>
<p>The first one was the improper use of the auction year when training. This generated a bias in the model. Usually, I was training on auctions that took place until 2010 and trained on auctions from 2011. Nothing wrong here. Then I also trained on actions until 2011 and tested on the first part of 2012 (public leaderboard data). Nothing wrong here. For the final model, I trained on the auctions until the first part of 2012 and tested on the second part of 2012. BOOM!</p>
<p>Prices fluctuate a lot during the year. They are usually higher during spring and lower during fall. When I was training on data from a whole year, there was no bias for that year, since it was a value the model hasn&#8217;t seen in training. But when I tested on fall data from 2012 on a model trained using spring data from that same year, the estimated prices were a little higher.</p>
<p>The second error was with averaging the 20-30 small models trained on (sub)categories. In a previous contest I used neural networks for this, but the final score fluctuated too much for my taste. I also tested genetic algorithms, but I thought the scores were not very good. Ridge regression gave significantly better results. There was one small problem though: it assigned positive as well as negative weights. Usually, ensembling weights are positive and sum to one. So price estimates are averages from a lot of predictions and they generalize well to unseen cases. With negative weights, estimates are no longer averages and generalizing gets a little unpredictable.</p>
<p>For posterity, <a href="https://github.com/andreiolariu/kaggle-bulldozer" target="_blank">the code is here</a>. I recommend checking out the winning approaches <a href="https://www.kaggle.com/c/bluebook-for-bulldozers/forums/t/4368/congratulations-to-the-preliminary-winners" target="_blank">on the competition&#8217;s forum</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://webmining.olariu.org/trees-ridges-and-bulldozers-made-in-1000-ad/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
			</item>
		<item>
		<title>My talk at CICLing 2013</title>
		<link>http://webmining.olariu.org/my-talk-at-cicling-2013/</link>
					<comments>http://webmining.olariu.org/my-talk-at-cicling-2013/#respond</comments>
		
		<dc:creator><![CDATA[Andrei Olariu]]></dc:creator>
		<pubDate>Wed, 27 Mar 2013 21:18:00 +0000</pubDate>
				<category><![CDATA[Research]]></category>
		<guid isPermaLink="false">http://webmining.olariu.org/?p=129</guid>

					<description><![CDATA[This week I&#8217;m at The International Conference on Intelligent Text Processing and Computational Linguistics (CICLing 2013), where I&#8217;ll present my PhD work. Here are the slides:]]></description>
										<content:encoded><![CDATA[<p>This week I&#8217;m at The International Conference on Intelligent Text Processing and Computational Linguistics (<a href="http://www.cicling.org/2013/" target="_blank">CICLing 2013</a>), where I&#8217;ll present my PhD work. Here are the slides:</p>
<p><iframe loading="lazy" allowfullscreen="true" allowtransparency="true" frameborder="0" height="723" id="talk_frame_40822" mozallowfullscreen="true" src="//speakerdeck.com/player/5a0f167079500130ace9123138154d22" style="border:0; padding:0; margin:0; background:transparent;" webkitallowfullscreen="true" width="880"></iframe></p>
]]></content:encoded>
					
					<wfw:commentRss>http://webmining.olariu.org/my-talk-at-cicling-2013/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Event Recommendation Contest on Kaggle</title>
		<link>http://webmining.olariu.org/event-recommendation-contest-on-kaggle/</link>
					<comments>http://webmining.olariu.org/event-recommendation-contest-on-kaggle/#comments</comments>
		
		<dc:creator><![CDATA[Andrei Olariu]]></dc:creator>
		<pubDate>Thu, 21 Feb 2013 22:13:00 +0000</pubDate>
				<category><![CDATA[Kaggle]]></category>
		<category><![CDATA[kaggle]]></category>
		<category><![CDATA[logisticregression]]></category>
		<category><![CDATA[randomforest]]></category>
		<category><![CDATA[recommend]]></category>
		<guid isPermaLink="false">http://webmining.olariu.org/event-recommendation-contest-on-kaggle</guid>

					<description><![CDATA[The Event Recommendation Engine Challenge just finished on Kaggle.com. I managed to build a good model and finished 7th. Given a dataset of users and events, we had to predict which event users will be interested in. We were given 38000 users, 3 m...]]></description>
										<content:encoded><![CDATA[<p>The <a href="https://www.kaggle.com/c/event-recommendation-engine-challenge">Event Recommendation Engine Challenge</a> just finished on Kaggle.com. I managed to build a good model and finished 7th.</p>
<p>Given a dataset of users and events, we had to predict which event users will be interested in. We were given 38000 users, 3 million events and a bunch of data about them (like friends, attendance or interest in events).</p>
<p>First thing, preprocess the data and put it in a database. I had to go for a database since I couldn&#8217;t fit everything in RAM. I chose MongoDB because it&#8217;s just so easy to set up. It wasn&#8217;t the best database choice for this task. I should try and experiment with Neo4j in the future.</p>
<p>Regarding preprocessing, the most I&#8217;ve struggled with was location. Most users had an unformatted location string. Around half of the events had a well formatted location (city, state and country), as well as GPS coordinates. At first, I used the Yahoo Placemaker API to convert user locations into coordinates. This way, I could compute distances between users and events.</p>
<p>I then noticed that external data is not allowed. No problem. With 1.6 million events having both location strings and GPS coordinates, I was able to build a database of spatial information. I could then match user locations and get some coordinates without an external API.</p>
<p>Given a (user, event) pair, these were the features I&#8217;ve used in my model:</p>
<ul>
<li>number of users attending, not attending, maybe attending and invited to the event;</li>
<li>number of friends attending, not attending, maybe attending and invited to the event;</li>
<li>location similarity between user and event;</li>
<li>number of users attending the event that have also attended events the user did;</li>
<li>similarity between the event and events the user attended, based on clusters &#8211; I used KMeans (loving <a href="http://scikit-learn.org/0.12/modules/generated/sklearn.cluster.MiniBatchKMeans.html">scikit-learn</a>) to cluster together similar events, based on words; I chose a few values for the number of clusters, in order to capture a little granularity;</li>
<li>same thing for events attended by friends;</li>
<li>same thing for events the user (or his friends) didn&#8217;t attend to;</li>
<li>time to event, apparently most important feature;</li>
<li>similarity between the event&#8217;s word distribution and the average distribution of words for events the user attended;</li>
<li>if the user was invited or not.</li>
</ul>
<p>I didn&#8217;t manage to get anything out of user age and gender. I&#8217;m still wondering if (and how) that info can be used in some useful way.</p>
<p>In order to generate results, I went for the classifier approach (two classes, interested and not interested). I also tried ranking and regression, but classifying worked best. I chose a Random Forest (again.. scikit-learn), because it was able to work with missing values. I also added Logistic Regression (on the features that didn&#8217;t have missing values) and averaged the results.</p>
<p>The <a href="https://github.com/andreiolariu/kaggle-event-recommendation">full code</a> is on github. Mind you, except the scripts main.py and model.py, all other files contain code snippets I built on the fly while exploring the data in ipython.</p>
]]></content:encoded>
					
					<wfw:commentRss>http://webmining.olariu.org/event-recommendation-contest-on-kaggle/feed/</wfw:commentRss>
			<slash:comments>10</slash:comments>
		
		
			</item>
	</channel>
</rss>
