Choose Language Hide Translation Bar

Decoding Mountain Bike Suspension: Graphs and Reviews

Full-suspension mountain bikes display a wide diversity of kinematic designs to control the motion of the rear wheel. Differences between these designs are present in functional curves such as leverage ratio, anti-rise, anti-squat, pedal kickback, and axle path. Due to the complex nature of these curves, comparing and understanding how different curve shapes will impact riding behavior is difficult.

In this paper, we begin by extracting the characteristic curves from specialized software as graphs for various models of mountain bikes. We then demonstrate JMP Scripting to import these images and perform basic image analysis, extracting the functional curves from these graphs. Additionally, we show Python scripting within JMP to collect reviews of the corresponding models from popular bike review websites. Then, using both the Functional Data Explorer and Text Explorer in JMP Pro, we examine the patterns in suspension curves that correlate with changes in the sentiment of the reviews examined. 

 

 

Jed and I are here. We're going to talk about a mountain bike suspension, and we're going to talk about some of the cool tools that we found in JMP that have helped us to understand how the suspension and some of the reviews that we see out on the Internet correlate with one another. This talk really came out of Discovery Summit last year. Jed and I met up, and I really wanted to know, "Okay, what is Functional Data Explorer? How can I use Functional Data Explorer? And what are some of the ways that it can benefit me?" Jed, knowing a bit about me, started talking about mountain bikes. That's an easy sell for me. It got me excited. That led to eventually what became this presentation.

Just a bit of disclaimer about us and about this presentation. We are not affiliated with bike companies. We are not experts in the industry by any means. We pulled some reviews from Bike Radar and looked at how they reviewed bikes. Then we pulled some suspension curves from the software called Linkage that's out and available on the Internet.

I would not use this presentation to decide which bike you should buy next. That's not our intent. Our intent is to show some of the really cool and powerful tools that exist within JMP to understand some data that might be more traditionally hard to wrap your arms around.

Before we get started here, we've got to talk a little bit about mountain bikes and how they work. On mountain bikes, you typically have front suspension and rear suspension. The front suspension is very simple. It just moves up and down along the fork in a linear fashion. The rear suspension is a lot more complicated. You've got your rear wheel and it moves up and down, and it typically has some form of a linkage that connects that movement to a shock that lives in the middle of the frame of the bike. That linkage can have a bunch of different properties that we'll go through the five that we pulled out to talk about.

But the easiest one to understand is probably the leverage ratio. That is if the wheel moves a millimeter, how much does the shock compress? Does the shock compress a millimeter as well? That would be a leverage ratio of one. If the shock compresses much less, then the leverage ratio is going to be higher, and that value changes throughout the entire travel of the wheel. As the wheel moves, that value changes, and so you get a curve or functional data that defines the linkage of your bike.

We pulled out five of these curves. The first one is anti-squat. That has to do with as the bike accelerates, what does the bike do? As you're pedaling, does your pedaling cause the bike to pitch forward, or does it cause it to sink in the travel, or does it cause it to stay relatively level? Anti-squat has to do with how the suspension reacts to that accelerating force.

Anti-rise is another one of those properties that is, okay, now when you're braking, so when you're slowing down, does the bike pitch forward on you? Does it compress in its suspension? Anti-rise is another one that's tuned by bike designers to characterize how the bike is or to improve how the bike is going to perform.

We talked a little bit about leverage ratio. This is how much as the wheel moves, how much does the shock compress? What's really interesting about leverage ratio, and we'll talk about this a little bit more towards the end of the presentation, is it's tuned with a specific shock. On bikes, there's air suspension and coil suspension, and depending on which one of those you're using, you'll see different leverage ratio curves. The important thing is that leverage ratio is tuned, but it's tuned not in isolation, but it also depends heavily on what kind of shock you're using.

Axle path is another one. As the wheel is moving up, does it move really far back, or does it move straight up and down, or does it move slightly forward? On this one, you can see the Y axis is how far the wheel has moved and the X axis is its position front to back. The wheel starts at zero. And then in this blue graph, you can see it initially moves back slightly before moving forward. You can imagine as you're going down a trail, if you're moving forward, you'd like your wheel to move back and out of the way of an obstacle rather than forward and into an obstacle. Axle path is one that's really fairly intuitive to understand in terms of how it might benefit a bike.

Then pedal kickback is the last one. This is as that wheel is moving, sometimes the distance between your pedals and the wheel will expand a little bit, and that will cause the pedals to move backwards on the rider. That's generally not a good thing. It can cause an unsetted feeling as you're riding your bike.

Those are the curves that we're interested in. That's the space that we're interested in, and we can get all of those out of linkage. The question now is, how do we get reviews? I'm back here in pre-JMP 18 land, but I can write a Python script, and I'm not going to go into detail about how this Python script works. If anybody has questions, feel free to reach out. I'm happy to answer questions. But what this does is I've got a Python script on my desktop that JMP is going to go run. That Python script is going to reach out to Bike Radar, it's going to collect a bunch of reviews, and then generate a couple of JMP data tables that we can look at.

The first one of them is this summary table. This provides a bunch of metadata about the bike review. It tells us what bike it is, and if it's a full review, or a long-term review, or a first ride review, what the publish date was. It gives us some short-term comments, what the overall score was, and then URL and what kind of bike and what the author was. Then we end up with the meat of the review here. This again gives us the bike, the specific section, and then the text of the review.

There's three components of each review that we collected here. We've got the climbing section of the review, we've got a descending section of the review, and then the last one is we've got the conclusion section of the review. For each bike, we've got each one of those sections, so we can look at, does the bike climb well? Does it go up the mountain well? Does it descend well? Does it come down well? And then overall, how did the reviewer feel about that bike?

We've talked about the two components that we're going to use to do our analysis here. We've got the curves, and we can generate those with this linkage software, and we've got the reviews.

But now, how do we take all of that and put it into a form that JMP can understand and that we can actually do some analysis with? To do that, what we've got out of our linkage thing is we've got an image. The question is, how do we get that image into a form that JMP can understand?

What's cool about JMP, and that I learned rather recently, is that it will actually open up images. You've got to run a little bit of JSL to do that. But if you do that, you can get an image, and then you can get a table out that gives you X and Y locations. That is where the pixel is at in space or in the image, and then it'll give you the red, green, and blue values of each one, each pixel in the image.

That's great. That still doesn't really get us what we want. We need this curve, but we can get a lot closer. If we could pick out all of the blue values, that would let us... Okay, we can get all the blue values, and then if we can map those into this graph space, we could generate a curve.

I really like Workflow Builder. It makes my life a lot easier because I can just do things graphically and get results, and so I built a quick workflow that does a K means clustering. This image is nice because there's only three colors in it. If we generate three groups and then save the formula for those clusters to the table, now we can get a graph that is the X and Y positions from this table, and then we can color them by the cluster formula. You can see we've got cluster formula one, is all of our blue pixels. We can use that to start to say, "Okay, here are the blue pixels. Now, what are those positions? We know what their global position is in the image. We've got to map those into their position on this graph."

Again, I'm not going to go into this in depth because it's a bit into the weeds, but I'll show you what the final script that we came up with looks like.

It shows the image, and then it says, "Okay, you've got to give me the Xmin and the Xmax and the Ymin and the Ymax for that graph." I'm going to punch in that it goes from zero to 130, and then it goes from 0.45 to 1.35. Click Okay. What we end up with is... Got to drag everything over here. We end up with a data table that has our X values, our Y values, and then the property and the bikes that we're looking at. This is just a sample image. But you can see, here's the graph that we started with. Here's our extracted graph. We did that by entering in these values, looking at the blue pixels, and then just calculating, "Okay, given our global position, here's how that maps into that zero to 130-millimeter space that we defined."

Needless to say, this isn't a perfect process, but it does a pretty good job of laying out, here are the curves for each one. It takes a little while. Jed and I both spent a couple of hours one evening typing in numbers, but after a while, we've got all of our curves that we can use to look at.

Now we'll talk about, "Okay, what did we do with the text? How did we get the text into a form that we could use?"

Thanks, Landon. As Landon said, we have the text, and we have the files saved as three separate CSV files: one for climbing, one for the conclusion, and one for the descending portion. Those I've saved on the desktop. If you're not aware, there is a really nice feature called Import multiple files. We used that. But again, for time's sake, I'm going to cheat a little and just run the script to do it. This essentially just imported all three of these files into one JMP file for me. With a little bit of right-click recode magic, I can change that file name to conclusion, descending and climbing.

Now I have my data formatted and ready to go. What do I mean by ready to go? We need to change this text in each of these fields into numbers, something that we can manipulate and do statistics with. One of my favorite and less-used features of JMP is the Text Explorer. It's actually really, really simple. If you have text in a column, then, well, it's the text. We can just basically ignore everything else because we're not going to use anything else. This is a fairly simple task to do.

By the way, I should mention that the sentiment analysis is a JMP Pro thing. If you do have JMP Pro, then you can use this sentiment analysis, which essentially goes through all of the text and assigns a score of sentiment or a feeling score to it. Right away, we can see that the reviewers are generally positive about these bicycles.

But one thing that I want to point out is that there's this notion of text curation. I scroll down to this pedal bob, it sounds weird. It's not somebody telling Bob to pedal. In mountain biking, this notion of pedal bobbing is when the suspension bobs up and down as you pedal, and it's a bad thing. Does JMP take this weird word pedal bob into account? Not by default, but it's really easy to add. I'm going to do that with the sentiment analysis. I'm going to manage these sentiment terms. I can come in and if I can type, I can type pedal bob. I can give it a score of minus 50, I can add that in. Then notice that when I hit okay here, that score will change just a little bit. This is, while it's an easy thing, it is also time-consuming.

I have a number of terms. This was actually Landon on a Saturday, went through the document and did all the curation and saved the terms for sentiments into a text file. Did this basically manually once. Then JMP will put them on the clipboard and I can control V to paste them in. When I hit Okay here, now we get an adjustment. I can do that same thing with the negation and an intensifier terms with files, just text files. But rather than make you watch me copy-paste, I'm just going to take a little shortcut here.

Now this is with all of those localized for this corpus or this set of documents. We have the language ready, and so we're going to start trusting these scores. Now that I trust the scores, I want to do something with them. In order to do something with them, the easiest way is probably just to go to the red triangle and hit Save document scores. When I do that, then go to the table, this table that did have just our text before now has a few extra columns that are numbers of positive and negative sentiment and as well as an overall sentiment.

Now I'm almost ready. The only thing I really need to do from this point on is maybe use the tabulate function to separate out the data a little bit better so that for climbing, I get overall positive and negative. Same with conclusion, overall positive and negative and descending. If I make this into a data table, now I have the data ready to do something with. I have each bicycle, and then for climbing, descending, and overall. But what that means is I can do something like use the Graph Builder to look at overall descending versus climbing. I could say, "Well, here are the bikes. If I were making conclusions, here are the bikes that are good at both of those." Long as short of it is now I'm ready to do some work with this, and it is treated as data with a value for how good it is. With that, let's go back to Landon.

Okay. Thank you, Jed. I've got that same table that Jed produced, so we can see we've got the bike, and then we've got our overall sentiment, our positive, our negative sentiment for each of our climbing, descending, and conclusion categories. We've got that. Then the other thing that we've done is we've gone through all of our images, and we've generated this curves table.

Right now this table is for each bike, we've got the property. We've got anti-squat. If I scroll through this, you can see there's anti-rise and rear path and all of our different properties. Then we've got... Our X is how far the bike is into the travel, and our Y is the value of that property at that point in the travel.

One thing we did is we noticed that there's a lot of variation in these bikes. Some of these bikes have 100 millimeters of travel or the wheel can move 100 millimeters, and some of the bikes have 180 millimeters of travel. That was causing us some problems, so we actually normalized all of our travels from zero to one. So rather than looking at how far has the wheel moved, we're looking at what proportion of the travel the bike is in. Is it 50% of the way through its full travel, or is it at the minimum?

Now, to look at this in Functional Data Explorer, we'd like to have it formatted a bit differently. What we're going to do is we're going to make our travel value an ordinal value, and then we can come in here to our tabulate friend. Jed and I, we made a lot of use to tabulate in this project. But we can take the bike and then we can say where we add on our travel, and we can grab the property, and then we can get, "Okay, what is the Y value here?"

We make that into a data table, and it looks a little bit messy in that the travel location for each one of our values isn't necessarily aligned, so you've got a bunch of missing values here where I've got a value for pedal kickback, but not for anything else. Then I've got a value for leverage ratio, but not for anything. It turns out that doesn't look super pretty, but it doesn't actually cause any problems. When we put this in Functional Data Explorer, it's going to handle those missing values really well. It's not going to cause any problems for us. And so we're just fine with it.

Then the other thing that we can do is we need to join this table here. We need to join it with our table that has all of our bike review scores. And the easiest way to do this is a virtual join. You can come here, and you can call link ID, and then you can come over here and you can make a link reference and do that just so that I've got a clean system. I'm going to pull that up.

You can see, here's all of our curve data. We've got the bike, where it's at in its travel, what the mean anti-rise, anti-squat, leverage ratio, pedal kickback, and rear path are. Then we've also got over here all of our sentiment scores.

Now, we want to take this into Functional Data Explorer, and we want to start to say, how do these sentiments relate to the shape of the curves? If we come in here to Specialized Modeling Functional Data Explorer, we'll just look at one of them right now. We'll look at our rear path. Our X input is going to be our normalized travel, and then we're going to take our bike name as the ID. Then the real magic is if we take all of our sentiment scores and we add them into our supplementary field.

Now when Functional Data Explorer runs, these curves are really nice because they're really smooth and they're generated from linkages, and so B-Splines fit them really, really well. We can fit B-Splines to all of these and we see, okay, most of the variation is in shape function one. If we look down here on our diagnostic plot, we can see there's a lot of variation along the component one. There's not a lot of variation along component two. Then we can hover here, and we can see, "Okay, this is a bike that if we look at it, it has an axle path that moves forward a lot. And here on the other end, we have an axle path that moves back a lot. Those are our two extremes.

Now once we've done that, we can come up here to our B-Spline on additional data. Because we added those Z additional factors, we can do this functional DOE analysis. What that gives us is now it builds the relationship between the sentiment scores and what the rear path looks like. This is a bit hard to read because these terms are so long. But these first three, this is our overall sentiment for climbing, this is our positive sentiment, and this is our negative sentiment for climbing.

If we were to only care about climbing, and we want really good overall sentiment for climbing, and really good or really low negative sentiment for climbing, here's what our bike looks like, or here's what our rear path looks like. You can see this is a rear path that's pretty standard. It's not moving really far forward, and it's not moving really far back. So you can get an idea for a rear path. We can repeat this process for each one of the different one of our paths. That's what we've done, and we've saved off these prediction formulas.

Then the last thing that we did is we took all of those and combined them together and built a profiler that will show us, given all of our reviews and all of our curves that we've put together, how do the reviews and the curves link up?

Here's our conclusion section, so positive, negative, and overall conclusion, and then you've got positive, negative, and overall climbing, and positive, negative, and overall descending scores. So let's look at, "Okay, we want a bike that really favors descending." So we're going to, okay, overall on descending. We don't want a lot of negative on descending, and we want high positives on descending.

What does that do? If we compare this rear path to the rear paths that we saw earlier, this one arcs back a lot more. That makes sense. That's something that corresponds to a bike where that rear wheel is going to move back and out of the way when you run into something on the trail. When you're going down and you hit a rock, that rear wheel is going to move out of the way.

The other one that I'll point out is this leverage ratio. I alluded to this earlier. We've got different types of shocks in mountain bikes. You've got coil shocks and you've got air suspension shocks. Without getting into the details, this is the kind of leverage ratio that you would expect to see for a coil shock. If you were to go look at all of the downhill focused bikes, they all have coil shocks. The big trend in the industry right now is let's put coil shocks on downhill bikes because it performs really well, and our data shows that as well.

We can also look at the inverse. We don't care so much about descending now, but we want really good climbing. We want to send a bike to the World Cup. Our rear path now looks a bit different, and our anti-rise looks a bit different. Our leverage ratio, this is a leverage ratio that is much more common with an air suspension, which is what you would see on a climbing-focused bike because it's going to be a lot lighter. It's going to perform a lot better for that category of biking.

The idea here is that, again, we're not trying to show, "Okay, this is the exact way that you should design a bike," but we're showing, "Okay, we've got some really complicated data." We've got reviews coming from reviewers on a website. We've got curves that are coming in as graphs and using JMP, we can pull all of this it together and we can synthesize it into a dashboard that does a really quite good job of helping us understand, "Okay, here's how reviews and these leverage ratios link up," and here's some information that helps us wrap our arms around and be a bit more rigorous than just the, "Well, I think it should be like this," view.

That's what we had to share. Again, if anybody has any questions, feel free to reach out. Thank you for your time.