Motivation

Considerations

Categorical Features

  1. categorical variables must be encoding same way as we’ve done with kNN; so use all of those techniques; the lm() function in R will automatically encode any variable that is categorical and of type “factor” but it’ll always use one-hot encoding; for that encoding, distribution does not matter, but since regression calculates “distance” (from the regression line), it’ll be sensitive to categorical variables and not work so well… decision trees will likely work better

if you encode a categorical variable into a numeric variable, such as weight-of-evidence, then it’ll have to be reasonably normally distributed, of course – as regression is a parametric statistical technique that presumes normality

if you can’t encode then omit the variable…

  1. see my answer for (1); R always uses one-hot which isn’t great if you have many levels as now you’ll get many more variables and that messes up regression – regression is not great at dealing with many dimensions (variables/columns); remember if you encode (or R encodes) a categorical variable with “n” levels, then you will introduce “n-1” new dimensions/variables/columns… this will likely reduce your Adjusted R^2 and your predictive power

Ordinal Categorical Features

  1. ordered categorical variables are best converted to a numeric column – you need to choose the numbers… example: education with levels No HS, HS, College, Graduate, Doctorate can be ordered and you could assign 0, 1, 2, 3, 4 as numeric equivalents… but now you stated that the “distance” between HS and College is 1 and Graduate and Doctorate is 1 – is that true? is that appropriate for your domain? perhaps or perhaps not… maybe the intervals are not equi-distant? maybe the encoding should be 0, 1, 3, 6, 10… domain dependent and might require some experimentation…

Transformation

[Yesterday 8:44 AM] Schedlbauer, Martin 4) no… if you transform a variable, e.g., a log-transform, that only applies to that variable… of course, if you make a prediction, you need to take the “input” variable and transform it first before inserting it into the regression equation ​[Yesterday 8:45 AM] Schedlbauer, Martin it might make more sense to log-transform one variable, not transform another because it is “normal enough”, inverse transform another, square-root transform yet another… the transform to be used depends on the initial distribution of the variable… again, experimentation is required as to which one works best… ​[Yesterday 8:46 AM] Schedlbauer, Martin building a model requires LOTS of experimentation and evaluation… also, your data might have clusters and it make make sense to split your data into the clusters and build different models for different clusters… ​[Yesterday 8:47 AM] Schedlbauer, Martin example: predicting home sales prices… you’ll likely have clusters: starter homes, condos, single family homes, really nice homes, mansions… you might not be able to build a model that predicts the price of any of those: might be better to build different models – so now you have different regression equations, or regression trees, or regression kNNs models – or ensembles of them…

now, how do you find the clusters? in the above example it was from domain knowledge – I “knew” from experience that dividing by home type might be appropriate… but, sometimes you don’t know… so, you either use visualization (like a scatter plot) or an automated cluster detection method, such as k-means (which we’ll see later in the course - it is an unsupervised machine learning method, aka a data mining method)…

Feature Scaling

scale… kind of matters for regression but not to the same extent as for kNN… still often best to normalize the scales using the same methods as we used for kNN (and will use for support vector machines and k-means clustering)… of course, you’ll do the normalization of the scales after you’ve done any categorical encoding, outlier detection, imputation, and transformation

Multicollinarity

Lastly, did you do any analysis of multicollinearity, i.e., determine if any pair of features has a strong correlation? If that’s the case, then you need to eliminate one of the two features as you are “double counting” them in the model.

Statistical Significance

The F-stat is as meaningful to interpret, as long as the overall p-value for the regression model is < 0.05 (or, I would argue, it should really be < 0.01); remember that the threshold for statistical significant of 0.05 is somewhat arbitrary and by convention… the argument recently has been that it should be less – I tend to agree with that and would argue that it should really be 0.01

Evaluation

and you definitely need to split the data into training and validation and then use the validation data to calculate MSE and/or MAD – that would be particularly important if you wanted to compare a regression model to a non-statistical model such as kNN or a regression tree as for those algorithms Adjusted R^2 is not defined and we need a different way to evaluate and compare models; MAD and/or MSE can be useful…

Summary


Files & Resources

All Files for Lesson 3.441

References

No references.

Errata

Let us know.

LS0tCnRpdGxlOiAiT3JkaW5hcnkgTGVhc3QgU3F1YXJlcyBSZWdyZXNzaW9uIgpwYXJhbXM6CiAgY2F0ZWdvcnk6IDMKICBzdGFja3M6IDAKICBudW1iZXI6IDQ0MQogIHRpbWU6IDEwCiAgbGV2ZWw6IGJlZ2lubmVyCiAgdGFnczogcmVncmVzc2lvbixvbHMsbWFjaGluZSBsZWFybmluZwogIGRlc2NyaXB0aW9uOiAiSW50cm9kdWNlcyBsaW5lYXIgcmVncmVzc2lvbiBhbmQgc3RhdGlzdGljYWwgbGVhcm5lcnMuIFNob3dzCiAgICAgICAgICAgICAgICBob3cgdG8gYnVpbGQgYW5kIGV2YWx1YXRlIGEgcmVncmVzc2lvbiBtb2RlbC4iCmRhdGU6ICI8c21hbGw+YHIgU3lzLkRhdGUoKWA8L3NtYWxsPiIKYXV0aG9yOiAiPHNtYWxsPk1hcnRpbiBTY2hlZGxiYXVlcjwvc21hbGw+IgplbWFpbDogIm0uc2NoZWRsYmF1ZXJAbmV1LmVkdSIKYWZmaWxpdGF0aW9uOiAiTm9ydGhlYXN0ZXJuIFVuaXZlcnNpdHkiCm91dHB1dDogCiAgYm9va2Rvd246Omh0bWxfZG9jdW1lbnQyOgogICAgdG9jOiB0cnVlCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvbGxhcHNlZDogZmFsc2UKICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIHRoZW1lOiBzcGFjZWxhYgogICAgaGlnaGxpZ2h0OiB0YW5nbwotLS0KCi0tLQp0aXRsZTogIjxzbWFsbD5gciBwYXJhbXMkY2F0ZWdvcnlgLmByIHBhcmFtcyRudW1iZXJgPC9zbWFsbD48YnIvPjxzcGFuIHN0eWxlPSdjb2xvcjogIzJFNDA1MzsgZm9udC1zaXplOiAwLjllbSc+YHIgcm1hcmtkb3duOjptZXRhZGF0YSR0aXRsZWA8L3NwYW4+IgotLS0KCmBgYHtyIGNvZGU9eGZ1bjo6cmVhZF91dGY4KHBhc3RlMChoZXJlOjpoZXJlKCksJy9SL19pbnNlcnQyREIuUicpKSwgaW5jbHVkZSA9IEZBTFNFfQpgYGAKCiMjIE1vdGl2YXRpb24KCiMjIENvbnNpZGVyYXRpb25zCgojIyMgQ2F0ZWdvcmljYWwgRmVhdHVyZXMKCjEpICBjYXRlZ29yaWNhbCB2YXJpYWJsZXMgbXVzdCBiZSBlbmNvZGluZyBzYW1lIHdheSBhcyB3ZSd2ZSBkb25lIHdpdGgga05OOyBzbyB1c2UgYWxsIG9mIHRob3NlIHRlY2huaXF1ZXM7IHRoZSBsbSgpIGZ1bmN0aW9uIGluIFIgd2lsbCBhdXRvbWF0aWNhbGx5IGVuY29kZSBhbnkgdmFyaWFibGUgdGhhdCBpcyBjYXRlZ29yaWNhbCBhbmQgb2YgdHlwZSAiZmFjdG9yIiBidXQgaXQnbGwgYWx3YXlzIHVzZSBvbmUtaG90IGVuY29kaW5nOyBmb3IgdGhhdCBlbmNvZGluZywgZGlzdHJpYnV0aW9uIGRvZXMgbm90IG1hdHRlciwgYnV0IHNpbmNlIHJlZ3Jlc3Npb24gY2FsY3VsYXRlcyAiZGlzdGFuY2UiIChmcm9tIHRoZSByZWdyZXNzaW9uIGxpbmUpLCBpdCdsbCBiZSBzZW5zaXRpdmUgdG8gY2F0ZWdvcmljYWwgdmFyaWFibGVzIGFuZCBub3Qgd29yayBzbyB3ZWxsLi4uIGRlY2lzaW9uIHRyZWVzIHdpbGwgbGlrZWx5IHdvcmsgYmV0dGVyCgppZiB5b3UgZW5jb2RlIGEgY2F0ZWdvcmljYWwgdmFyaWFibGUgaW50byBhIG51bWVyaWMgdmFyaWFibGUsIHN1Y2ggYXMgd2VpZ2h0LW9mLWV2aWRlbmNlLCB0aGVuIGl0J2xsIGhhdmUgdG8gYmUgcmVhc29uYWJseSBub3JtYWxseSBkaXN0cmlidXRlZCwgb2YgY291cnNlIC0tIGFzIHJlZ3Jlc3Npb24gaXMgYSBwYXJhbWV0cmljIHN0YXRpc3RpY2FsIHRlY2huaXF1ZSB0aGF0IHByZXN1bWVzIG5vcm1hbGl0eQoKaWYgeW91IGNhbid0IGVuY29kZSB0aGVuIG9taXQgdGhlIHZhcmlhYmxlLi4uCgoyKSAgc2VlIG15IGFuc3dlciBmb3IgKDEpOyBSIGFsd2F5cyB1c2VzIG9uZS1ob3Qgd2hpY2ggaXNuJ3QgZ3JlYXQgaWYgeW91IGhhdmUgbWFueSBsZXZlbHMgYXMgbm93IHlvdSdsbCBnZXQgbWFueSBtb3JlIHZhcmlhYmxlcyBhbmQgdGhhdCBtZXNzZXMgdXAgcmVncmVzc2lvbiAtLSByZWdyZXNzaW9uIGlzIG5vdCBncmVhdCBhdCBkZWFsaW5nIHdpdGggbWFueSBkaW1lbnNpb25zICh2YXJpYWJsZXMvY29sdW1ucyk7IHJlbWVtYmVyIGlmIHlvdSBlbmNvZGUgKG9yIFIgZW5jb2RlcykgYSBjYXRlZ29yaWNhbCB2YXJpYWJsZSB3aXRoICJuIiBsZXZlbHMsIHRoZW4geW91IHdpbGwgaW50cm9kdWNlICJuLTEiIG5ldyBkaW1lbnNpb25zL3ZhcmlhYmxlcy9jb2x1bW5zLi4uIHRoaXMgd2lsbCBsaWtlbHkgcmVkdWNlIHlvdXIgQWRqdXN0ZWQgUlxeMiBhbmQgeW91ciBwcmVkaWN0aXZlIHBvd2VyCgojIyMgT3JkaW5hbCBDYXRlZ29yaWNhbCBGZWF0dXJlcwoKMykgIG9yZGVyZWQgY2F0ZWdvcmljYWwgdmFyaWFibGVzIGFyZSBiZXN0IGNvbnZlcnRlZCB0byBhIG51bWVyaWMgY29sdW1uIC0tIHlvdSBuZWVkIHRvIGNob29zZSB0aGUgbnVtYmVycy4uLiBleGFtcGxlOiBlZHVjYXRpb24gd2l0aCBsZXZlbHMgTm8gSFMsIEhTLCBDb2xsZWdlLCBHcmFkdWF0ZSwgRG9jdG9yYXRlIGNhbiBiZSBvcmRlcmVkIGFuZCB5b3UgY291bGQgYXNzaWduIDAsIDEsIDIsIDMsIDQgYXMgbnVtZXJpYyBlcXVpdmFsZW50cy4uLiBidXQgbm93IHlvdSBzdGF0ZWQgdGhhdCB0aGUgImRpc3RhbmNlIiBiZXR3ZWVuIEhTIGFuZCBDb2xsZWdlIGlzIDEgYW5kIEdyYWR1YXRlIGFuZCBEb2N0b3JhdGUgaXMgMSAtLSBpcyB0aGF0IHRydWU/IGlzIHRoYXQgYXBwcm9wcmlhdGUgZm9yIHlvdXIgZG9tYWluPyBwZXJoYXBzIG9yIHBlcmhhcHMgbm90Li4uIG1heWJlIHRoZSBpbnRlcnZhbHMgYXJlIG5vdCBlcXVpLWRpc3RhbnQ/IG1heWJlIHRoZSBlbmNvZGluZyBzaG91bGQgYmUgMCwgMSwgMywgNiwgMTAuLi4gZG9tYWluIGRlcGVuZGVudCBhbmQgbWlnaHQgcmVxdWlyZSBzb21lIGV4cGVyaW1lbnRhdGlvbi4uLgoKIyMjIFRyYW5zZm9ybWF0aW9uCgpbWWVzdGVyZGF5IDg6NDQgQU1dIFNjaGVkbGJhdWVyLCBNYXJ0aW4gNCkgbm8uLi4gaWYgeW91IHRyYW5zZm9ybSBhIHZhcmlhYmxlLCBlLmcuLCBhIGxvZy10cmFuc2Zvcm0sIHRoYXQgb25seSBhcHBsaWVzIHRvIHRoYXQgdmFyaWFibGUuLi4gb2YgY291cnNlLCBpZiB5b3UgbWFrZSBhIHByZWRpY3Rpb24sIHlvdSBuZWVkIHRvIHRha2UgdGhlICJpbnB1dCIgdmFyaWFibGUgYW5kIHRyYW5zZm9ybSBpdCBmaXJzdCBiZWZvcmUgaW5zZXJ0aW5nIGl0IGludG8gdGhlIHJlZ3Jlc3Npb24gZXF1YXRpb24g4oCLW1llc3RlcmRheSA4OjQ1IEFNXSBTY2hlZGxiYXVlciwgTWFydGluIGl0IG1pZ2h0IG1ha2UgbW9yZSBzZW5zZSB0byBsb2ctdHJhbnNmb3JtIG9uZSB2YXJpYWJsZSwgbm90IHRyYW5zZm9ybSBhbm90aGVyIGJlY2F1c2UgaXQgaXMgIm5vcm1hbCBlbm91Z2giLCBpbnZlcnNlIHRyYW5zZm9ybSBhbm90aGVyLCBzcXVhcmUtcm9vdCB0cmFuc2Zvcm0geWV0IGFub3RoZXIuLi4gdGhlIHRyYW5zZm9ybSB0byBiZSB1c2VkIGRlcGVuZHMgb24gdGhlIGluaXRpYWwgZGlzdHJpYnV0aW9uIG9mIHRoZSB2YXJpYWJsZS4uLiBhZ2FpbiwgZXhwZXJpbWVudGF0aW9uIGlzIHJlcXVpcmVkIGFzIHRvIHdoaWNoIG9uZSB3b3JrcyBiZXN0Li4uIOKAi1tZZXN0ZXJkYXkgODo0NiBBTV0gU2NoZWRsYmF1ZXIsIE1hcnRpbiBidWlsZGluZyBhIG1vZGVsIHJlcXVpcmVzIExPVFMgb2YgZXhwZXJpbWVudGF0aW9uIGFuZCBldmFsdWF0aW9uLi4uIGFsc28sIHlvdXIgZGF0YSBtaWdodCBoYXZlIGNsdXN0ZXJzIGFuZCBpdCBtYWtlIG1ha2Ugc2Vuc2UgdG8gc3BsaXQgeW91ciBkYXRhIGludG8gdGhlIGNsdXN0ZXJzIGFuZCBidWlsZCBkaWZmZXJlbnQgbW9kZWxzIGZvciBkaWZmZXJlbnQgY2x1c3RlcnMuLi4g4oCLW1llc3RlcmRheSA4OjQ3IEFNXSBTY2hlZGxiYXVlciwgTWFydGluIGV4YW1wbGU6IHByZWRpY3RpbmcgaG9tZSBzYWxlcyBwcmljZXMuLi4geW91J2xsIGxpa2VseSBoYXZlIGNsdXN0ZXJzOiBzdGFydGVyIGhvbWVzLCBjb25kb3MsIHNpbmdsZSBmYW1pbHkgaG9tZXMsIHJlYWxseSBuaWNlIGhvbWVzLCBtYW5zaW9ucy4uLiB5b3UgbWlnaHQgbm90IGJlIGFibGUgdG8gYnVpbGQgYSBtb2RlbCB0aGF0IHByZWRpY3RzIHRoZSBwcmljZSBvZiBhbnkgb2YgdGhvc2U6IG1pZ2h0IGJlIGJldHRlciB0byBidWlsZCBkaWZmZXJlbnQgbW9kZWxzIC0tIHNvIG5vdyB5b3UgaGF2ZSBkaWZmZXJlbnQgcmVncmVzc2lvbiBlcXVhdGlvbnMsIG9yIHJlZ3Jlc3Npb24gdHJlZXMsIG9yIHJlZ3Jlc3Npb24ga05OcyBtb2RlbHMgLS0gb3IgZW5zZW1ibGVzIG9mIHRoZW0uLi4KCm5vdywgaG93IGRvIHlvdSBmaW5kIHRoZSBjbHVzdGVycz8gaW4gdGhlIGFib3ZlIGV4YW1wbGUgaXQgd2FzIGZyb20gZG9tYWluIGtub3dsZWRnZSAtLSBJICJrbmV3IiBmcm9tIGV4cGVyaWVuY2UgdGhhdCBkaXZpZGluZyBieSBob21lIHR5cGUgbWlnaHQgYmUgYXBwcm9wcmlhdGUuLi4gYnV0LCBzb21ldGltZXMgeW91IGRvbid0IGtub3cuLi4gc28sIHlvdSBlaXRoZXIgdXNlIHZpc3VhbGl6YXRpb24gKGxpa2UgYSBzY2F0dGVyIHBsb3QpIG9yIGFuIGF1dG9tYXRlZCBjbHVzdGVyIGRldGVjdGlvbiBtZXRob2QsIHN1Y2ggYXMgay1tZWFucyAod2hpY2ggd2UnbGwgc2VlIGxhdGVyIGluIHRoZSBjb3Vyc2UgLSBpdCBpcyBhbiB1bnN1cGVydmlzZWQgbWFjaGluZSBsZWFybmluZyBtZXRob2QsIGFrYSBhIGRhdGEgbWluaW5nIG1ldGhvZCkuLi4KCiMjIyBGZWF0dXJlIFNjYWxpbmcKCnNjYWxlLi4uIGtpbmQgb2YgbWF0dGVycyBmb3IgcmVncmVzc2lvbiBidXQgbm90IHRvIHRoZSBzYW1lIGV4dGVudCBhcyBmb3Iga05OLi4uIHN0aWxsIG9mdGVuIGJlc3QgdG8gbm9ybWFsaXplIHRoZSBzY2FsZXMgdXNpbmcgdGhlIHNhbWUgbWV0aG9kcyBhcyB3ZSB1c2VkIGZvciBrTk4gKGFuZCB3aWxsIHVzZSBmb3Igc3VwcG9ydCB2ZWN0b3IgbWFjaGluZXMgYW5kIGstbWVhbnMgY2x1c3RlcmluZykuLi4gb2YgY291cnNlLCB5b3UnbGwgZG8gdGhlIG5vcm1hbGl6YXRpb24gb2YgdGhlIHNjYWxlcyBhZnRlciB5b3UndmUgZG9uZSBhbnkgY2F0ZWdvcmljYWwgZW5jb2RpbmcsIG91dGxpZXIgZGV0ZWN0aW9uLCBpbXB1dGF0aW9uLCBhbmQgdHJhbnNmb3JtYXRpb24KCiMjIyBNdWx0aWNvbGxpbmFyaXR5CgpMYXN0bHksIGRpZCB5b3UgZG8gYW55IGFuYWx5c2lzIG9mIG11bHRpY29sbGluZWFyaXR5LCBpLmUuLCBkZXRlcm1pbmUgaWYgYW55IHBhaXIgb2YgZmVhdHVyZXMgaGFzIGEgc3Ryb25nIGNvcnJlbGF0aW9uPyBJZiB0aGF0J3MgdGhlIGNhc2UsIHRoZW4geW91IG5lZWQgdG8gZWxpbWluYXRlIG9uZSBvZiB0aGUgdHdvIGZlYXR1cmVzIGFzIHlvdSBhcmUgImRvdWJsZSBjb3VudGluZyIgdGhlbSBpbiB0aGUgbW9kZWwuCgojIyMgU3RhdGlzdGljYWwgU2lnbmlmaWNhbmNlCgpUaGUgRi1zdGF0IGlzIGFzIG1lYW5pbmdmdWwgdG8gaW50ZXJwcmV0LCBhcyBsb25nIGFzIHRoZSBvdmVyYWxsIHAtdmFsdWUgZm9yIHRoZSByZWdyZXNzaW9uIG1vZGVsIGlzIFw8IDAuMDUgKG9yLCBJIHdvdWxkIGFyZ3VlLCBpdCBzaG91bGQgcmVhbGx5IGJlIFw8IDAuMDEpOyByZW1lbWJlciB0aGF0IHRoZSB0aHJlc2hvbGQgZm9yIHN0YXRpc3RpY2FsIHNpZ25pZmljYW50IG9mIDAuMDUgaXMgc29tZXdoYXQgYXJiaXRyYXJ5IGFuZCBieSBjb252ZW50aW9uLi4uIHRoZSBhcmd1bWVudCByZWNlbnRseSBoYXMgYmVlbiB0aGF0IGl0IHNob3VsZCBiZSBsZXNzIC0tIEkgdGVuZCB0byBhZ3JlZSB3aXRoIHRoYXQgYW5kIHdvdWxkIGFyZ3VlIHRoYXQgaXQgc2hvdWxkIHJlYWxseSBiZSAwLjAxCgojIyBFdmFsdWF0aW9uCgphbmQgeW91IGRlZmluaXRlbHkgbmVlZCB0byBzcGxpdCB0aGUgZGF0YSBpbnRvIHRyYWluaW5nIGFuZCB2YWxpZGF0aW9uIGFuZCB0aGVuIHVzZSB0aGUgdmFsaWRhdGlvbiBkYXRhIHRvIGNhbGN1bGF0ZSBNU0UgYW5kL29yIE1BRCAtLSB0aGF0IHdvdWxkIGJlIHBhcnRpY3VsYXJseSBpbXBvcnRhbnQgaWYgeW91IHdhbnRlZCB0byBjb21wYXJlIGEgcmVncmVzc2lvbiBtb2RlbCB0byBhIG5vbi1zdGF0aXN0aWNhbCBtb2RlbCBzdWNoIGFzIGtOTiBvciBhIHJlZ3Jlc3Npb24gdHJlZSBhcyBmb3IgdGhvc2UgYWxnb3JpdGhtcyBBZGp1c3RlZCBSXF4yIGlzIG5vdCBkZWZpbmVkIGFuZCB3ZSBuZWVkIGEgZGlmZmVyZW50IHdheSB0byBldmFsdWF0ZSBhbmQgY29tcGFyZSBtb2RlbHM7IE1BRCBhbmQvb3IgTVNFIGNhbiBiZSB1c2VmdWwuLi4KCiMjIFN1bW1hcnkKCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKIyMgRmlsZXMgJiBSZXNvdXJjZXMKCmBgYHtyIHppcEZpbGVzLCBlY2hvPUZBTFNFfQp6aXBOYW1lID0gc3ByaW50ZigiTGVzc29uRmlsZXMtJXMtJXMuemlwIiwgCiAgICAgICAgICAgICAgICAgcGFyYW1zJGNhdGVnb3J5LAogICAgICAgICAgICAgICAgIHBhcmFtcyRudW1iZXIpCgp0ZXh0QUxpbmsgPSBwYXN0ZTAoIkFsbCBGaWxlcyBmb3IgTGVzc29uICIsIAogICAgICAgICAgICAgICBwYXJhbXMkY2F0ZWdvcnksIi4iLHBhcmFtcyRudW1iZXIpCgojIGRvd25sb2FkRmlsZXNMaW5rKCkgaXMgaW5jbHVkZWQgZnJvbSBfaW5zZXJ0MkRCLlIKa25pdHI6OnJhd19odG1sKGRvd25sb2FkRmlsZXNMaW5rKCIuIiwgemlwTmFtZSwgdGV4dEFMaW5rKSkKYGBgCgotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KCiMjIFJlZmVyZW5jZXMKCk5vIHJlZmVyZW5jZXMuCgojIyBFcnJhdGEKCltMZXQgdXMga25vd10oaHR0cHM6Ly9mb3JtLmpvdGZvcm0uY29tLzIxMjE4NzA3Mjc4NDE1Nyl7dGFyZ2V0PSJfYmxhbmsifS4K