精华内容
下载资源
问答
  • 如何预测天气预报?

    2013-01-12 20:10:19
    想用神经网络技术研究预测天气,但不知道影响天气的因素与数据, 以及如何获取这些训练数据! 求大家帮忙!
  • 使用机器学习预测天气Based on every NFL play from 2009–2017 根据2009-2017年每场NFL比赛 Ah, yes. The times, they are changin’. The leaves are beginning to fall, the weather is slowly starting to cool...

    使用机器学习预测天气

    Based on every NFL play from 2009–2017

    根据2009-2017年每场NFL比赛

    Ah, yes. The times, they are changin’. The leaves are beginning to fall, the weather is slowly starting to cool down (unless you’re where I’m at in LA, where it’s only getting hotter), and the mental transition of changing from shorts & sandals to jeans & hoodies is beginning. But, there is one other great fall tradition peeking its head over the horizon — FOOTBALL SEASON! Well, hopefully. Cause you know… Coronavirus.

    是的。 时代在变。 叶子开始掉落,天气开始慢慢降温(除非您在我在洛杉矶的地方,那里只会变得更热),从短裤和凉鞋到牛仔裤和帽衫的转变是一种精神上的转变开始。 但是,还有另一种伟大的秋季传统正在悄然兴起–足球赛季! 好吧,希望如此。 因为你知道……冠状病毒。

    I love football. I am a deeply rooted Minnesota Vikings fan, and every season I can go into Week 1 fully optimistic that “this is our year!” Because, for those who may not know, my Vikings have never… won… a Super Bowl. *sigh*

    我爱足球。 我是明尼苏达州维京人队的根深蒂固的球迷,每个赛季我都可以完全乐观地认为“今年是我们的一年!” 因为,对于那些可能不知道的人,我的维京人从来没有……赢得过……超级碗。 *叹*

    There have been 54 Super Bowls and the Vikings don’t have a single trophy. But like I said, this is our year!

    已经有54个超级碗,维京人没有一个奖杯。 但是就像我说的,这是我们的一年!

    On top of loving football, I also love working with data. And as an aspiring data scientist, I decided to take these two passions and join them together. I’m excited to share my process on answering the ever important question in the football world— can we use data to predict touchdowns?

    除了热爱足球,我还喜欢使用数据。 作为一名有抱负的数据科学家,我决定接受这两种激情并将它们融合在一起。 我很高兴与大家分享我在回答足球界日益重要的问题上的过程-我们可以使用数据来预测达阵吗?

    第1部分-目标 (Part 1— Objectives)

    I had three primary objectives for this project. First, I wanted to use a classification model to classify touchdown plays versus non-touchdown plays. This was the prediction part. One really important thing I want to note, is that these are not predicting plays in the future. The model uses data it already has to make its predictions on data it’s never seen before. I’ll expand on this in a moment.

    对于这个项目,我有三个主要目标。 首先,我想使用分类模型对触地得分与非触地得分进行分类。 这是预测部分。 我要指出的一件事是, 真正重要的是,这些都不是未来的预测。 该模型使用已经必须之前从未见过的数据进行预测的数据。 稍后我将对此进行详细说明。

    Second, I wanted to discover what the most important predictors (which I may also refer to as ‘features’) were for the machine in determining what separates a touchdown from a non-touchdown. Having this valuable information will allow me to achieve my third objective, which is to use all that I’ve learned to make data-driven recommendations for offensive and defensive coaches.

    其次,我想发现对于机器而言,最重要的预测指标(我也可以称为“特征”)是什么,它决定了将触地得分与非触地得分区分开的因素。 拥有这些宝贵的信息将使我实现我的第三个目标,那就是利用我所学到的所有知识,为进攻型和防守型教练提供数据驱动的建议。

    第2部分-数据 (Part 2— The Data)

    For anyone interested, the dataset for this project can be found on Kaggle, here. There were a couple options to choose from, but I decided to use the play-by-play data from 2009–2017 so that I could have as much data as possible to work with. This set contains every single play, from every single game, for every single team, for all of the NFL Regular Season games that were played between the 2009 and 2017 seasons. So, there is no preseason or postseason included.

    对于任何感兴趣的人,可以在Kaggle的此处找到该项目的数据集。 有两个选项可供选择,但我决定使用2009-2017年的逐次播放数据,以便可以使用尽可能多的数据。 这组包含2009年至2017赛季之间所有NFL常规赛比赛的每场比赛,每场比赛,每支球队的比赛。 因此,不包括季前赛或季后赛。

    After going through the process of preprocessing and cleaning my data, I finished up with 7,068 predictors (columns) and 407,688 entries (rows) of data to work with. So in total, there were about 2.88 billion pieces of data. Some will say, “woah! that’s a lot!”, and others will say “meh. that’s nothin.” And to each their own. But in my experience, this was by far the largest dataset I have worked with. However, I viewed that as a good thing — more data should mean high-quality and highly reproducible results.

    在完成预处理和清理数据的过程之后,我完成了7,068个预测变量(列)和407,688个数据条目(行)可以使用。 因此,总共有大约28.8亿条数据。 有人会说:“哇! 太多了!”,其他人会说“嗯。 那没什么。 并给每个人自己。 但是根据我的经验,这是迄今为止我使用过的最大的数据集。 但是,我认为这是一件好事-更多数据应意味着高质量和高度可重复的结果。

    第3部分-建模 (Part 3 — Modeling)

    Now that the data had been obtained and properly preprocessed, I could begin modeling. My first step was to determine my target variable, which was whether a play resulted in a touchdown or not (this column was a boolean — 0=False, meaning no touchdown, and 1=True, meaning a touchdown was scored.) Then, I performed a train-test split. I decided to use a 75% training/25% testing split. What this means is that the machine will learn (hence, ‘machine learning’) from 75% of the data on which predictors are most featured in both touchdown plays and non-touchdown plays (target variable). Then, the machine will use what it learned from its training process to make its predictions on the remaining 25% of the data that it has yet to see.

    现在已经获得了数据并进行了适当的预处理,我可以开始建模了。 我的第一步是确定我的目标变量,这是一个游戏是否导致触地得分(此列为布尔值-0 = False,表示无触地得分,1 = True,表示触地得分。)然后,我进行了火车测试拆分。 我决定使用75%的培训/ 25%的测试分组。 这意味着机器将从75%的数据中学习(因此称为“机器学习”),预测值在触地得分比赛和非触地得分比赛(目标变量)中最有特色。 然后,机器将使用从训练过程中学到的知识对尚未看到的剩余25%数据做出预测。

    *Quick Side Note* For anyone reading this that may be new to data science or machine learning, creating your target and performing a train-test split should always be your first two steps, no matter what kind of machine learning model you may be running.

    *快速说明*对于任何可能不了解数据科学或机器学习的人,无论您正在运行哪种机器学习模型,创建目标和执行火车测试拆分始终应该是您的前两个步骤。

    For this project, I decided to try two different types of ensemble methods, which were a decision trees model and a random forest model. A random forest is basically a bunch of different decision trees, and I figured that it would produce better results. Interestingly though, the decision trees model created much more meaningful and reliable results, and that is what I will display in this blog post.

    对于这个项目,我决定尝试两种不同类型的集成方法,即决策树模型和随机森林模型。 随机森林基本上是一堆不同的决策树,我认为它将产生更好的结果。 但是,有趣的是,决策树模型创建了更有意义,更可靠的结果,这就是我将在此博客文章中显示的内容。

    Image for post
    My Decision Tree
    我的决策树

    This is the actual decision tree from my project. Essentially, decision trees work by breaking down the samples of a particular set of data into smaller and smaller groups, which creates the tree-like structure you see above. The white box is known as the decision node, which is broken into a number of branches that is equal to the number of classes in your target variable. So, because there are two classes in my target, it is broken into two branches, 0 equaling False (non-touchdown) and 1 equaling True (touchdown). Then, each colored box is called a leaf node, which is a representation of the machine’s classification, or decision. So, the orange boxes represent plays that were not touchdowns, and the blue boxes represent plays that were touchdowns.

    这是我项目中的实际决策树。 本质上,决策树通过将一组特定数据的样本分成越来越小的组来工作,从而创建了您在上面看到的树状结构。 白框称为决策节点 ,它分为多个分支,这些分支等于您的目标变量中的类数。 因此,由于目标中有两个类,因此将其分为两个分支,0等于False(非触地得分)和1等于True(触地得分)。 然后,每个有色框称为叶节点 ,它代表机器的分类或决策 。 因此,橙色框代表的不是触地得分,蓝色框代表的不是触地得分。

    Typically, running a model with its vanilla features (or in other words, without tuning them) will result in suboptimal results. It is common to utilize something like GridSearchCV from sklearn to determine the optimal features. However, with the machine I have and the size of the dataset, GridSearch was too resource-heavy and proved to be inefficient. I instead used a smiliair tool called RandomizedSearchCV, which still took a while to run, but proved to be more efficient than GridSearch and the good old-fashioned trial & error method. In this model, I tuned two features: max_depth & min_samples_split.

    通常,运行具有原始特征的模型(或者说,不对其进行调整)将导致结果欠佳。 通常使用sklearn中的GridSearchCV之类的东西来确定最佳功能。 但是,使用我拥有的计算机和数据集的大小,GridSearch太耗资源,因此效率低下。 相反,我使用了一个名为RandomizedSearchCV的辅助工具,该工具仍然需要一段时间才能运行,但事实证明它比GridSearch和老式的反复试验方法更有效。 在此模型中,我调整了两个功能:max_depth和min_samples_split。

    • max_depth determines the maximum depth of the tree. Normally, the tree will continue to diverge until all the leaves are fulfilled, or the leaves contain fewer than the min_samples_split parameter has designated. My max_depth was set to 10.

      max_depth确定树的最大深度。 通常,树将继续发散,直到所有叶子都满足为止,或者叶子包含的数量少于min_samples_split参数指定的数量。 我的max_depth设置为10。

    • min_samples_split determines the minimum number of samples needed before breaking off into a new leaf node. This feature is cool because you can use a whole number of samples (aka an integer) or you can use a percentage of the samples (aka a float). The default value is 2… which, when working with almost 2.9 billion pieces of data, is going to do one of two things: One, create terrible results; Or two, create results that are so good, it’s almost impossible to believe. The latter happened to me. So, I set my min_samples_split to 0.25.

      min_samples_split确定在分解为新的叶节点之前所需的最少样本数。 此功能很酷,因为您可以使用全部样本(也就是整数),也可以使用一定比例的样本(也就是浮点数)。 默认值为2…,当处理近29亿条数据时,它将执行以下两项操作之一: 或两个,创造出如此出色的结果,几乎是难以置信的。 后者发生在我身上。 因此,我将我的min_samples_split设置为0.25。

    第4部分-结果 (Part 4 — Results)

    Image for post
    Top Left — Non-touchdown Predictions; Bottom right — Touchdown predictions
    左上方-非着陆预测; 右下方-触地得分预测

    Above, you will see my confusion matrix, which is a representation of how well the model did predicting touchdowns and non-touchdowns. The purple boxes are what is important to focus on because the top-left represents “true negatives”, which means correctly predicted non-touchdowns, and the bottom right represents “true positives”, which means correctly predicted touchdowns. Overall, the testing accuracy was 93%, which is excellent (and also believable!)

    在上方,您将看到我的混淆矩阵,该矩阵表示模型预测着陆和非着陆的效果。 紫色框是需要重点关注的地方,因为左上角代表“真实否定”,这意味着正确预测的非触地得分,右下角代表“真实正向”,这意味着正确预测的触地得分。 总体而言,测试精度为93%,这非常好(也是令人信服的!)

    For those that are curious, the random forest model that I ran with the same parameter tuning (max_depth & min_samples_split) predicted 90% of non-touchdowns correctly, only 55% of touchdowns correctly, and had an overall testing accuracy of 89%. Like I said in the intro, this definitely was a surprise to me.

    对于那些好奇的人,我使用相同的参数调整(max_depth和min_samples_split)运行的随机森林模型正确地预测了90%的非触地得分,正确地预测了55%的非触地得分,并且总体测试准确性为89%。 就像我在介绍中所说的那样,这绝对让我感到惊讶。

    Image for post
    Feature Importance for Decision Tree Model
    决策树模型的特征重要性

    Objective #1 has been achieved, so now we’re on to objective #2: what are the important features? So, remember how I said that there were 7,068 features for the machine to learn from? Well, it turns out that there were only 5 — yes, five — that really mattered. That’s .0007% of the features. Woah! Of these five features, two had positive influences on touchdowns and three had negative influences on touchdowns:

    目标1已经实现,所以现在我们进入目标2: 重要特征是什么? 因此,还记得我说过要为机器学习的7,068项功能吗? 好吧,事实证明只有5个-是的, 五个 -确实很重要。 这就是功能的0.007%。 哇! 在这五个功能中,两个对触地得分有正面影响,三个对触地得分有负面影响:

    • Goal To Go — Was the ball placed on the opponents 10 yard line or closer? Influence: Positive. It’s much easier to score from 10 yards out than 90 yards out.

      要进球 –球是放在对手10码线上或更近的位置上吗? 影响: 积极 。 从10码以外的地方得分比90码以外的地方容易得多。

    • Yards Gained — Did the offense gain positive yardage? Influence: Positive. Gaining positive yardage means you’re moving in the right direction, thus increasing the chance to score a touchdown.

      乱码 —进攻是否获得了正码数? 影响: 积极 。 获得正码数意味着您朝着正确的方向前进,从而增加了达阵得分的机会。

    • First Down — Did the play result in a first down? Influence: Negative. Gaining first downs is a good thing for an offense. However, a play ruled as a touchdown is not also considered a first down. Therefore, you can’t have a touchdown and a first down on the same play.

      第一回合 -比赛是否导致第一​​回合? 影响: 负面 。 获得先攻是对进攻的好事。 但是,被视为触地得分的比赛也不会被视为首发。 因此,您不能在同一场比赛中触地得分和先击球。

    • Interception Thrown — Was there an interception thrown on the play? Influence: Negative. On offense, if you turn the ball over, you can’t score. One thing I find interesting is that fumbles weren’t nearly as important as interceptions were.

      拦截拦截 -剧中是否有拦截? 影响: 负面 。 进攻时,如果您将球翻过来,就无法得分。 我发现有趣的一件事是,骗局并不像拦截一样重要。

    • Yard Line (100) — Imagine the field being one 100 yard field, as opposed to two 50 yard halves. The 1 would be the offense’s one yard line, the 50 would be midfield, and the 99 would be the opponent’s one yard line. Where is the ball on the field? Influence: Negative. This is kind of the opposite of Goal to Go, in a sense. Most offensive plays happen on the offense’s own side of the field, let alone inside their opponent’s 10 yard line. The more distance needed, the harder it is to score.

      码线(100) -假设该字段是一个100码的字段,而不是两个50码的一半。 1是进攻方的一码线,50是中场,而99是对手的一码线。 球场上的球在哪里? 影响: 负面 。 从某种意义上讲,这与“ Goal to Go”相反。 大多数进攻战术发生在进攻方自己的领域,更不用说在对手的10码线内了。 需要的距离越长,得分就越困难。

    第5部分-数据驱动的建议 (Part 5 — Data-Driven Recommendations)

    Now that we have all of these fantastic insights, how can this information be applied? I believe that the group that would most benefit from this analysis would be coaches, both on offense and on defense.

    既然我们拥有所有这些奇妙的见解,那么如何应用这些信息? 我相信从分析中受益最大的是教练,无论是进攻还是防守。

    进攻教练 (Offensive Coaches)

    • Get big plays, but don’t get carried away — We’ve seen that gaining positive yardage has a positive influence on being able to score touchdowns. However, that doesn’t mean you need to go bombs away every play. Scout the defense, attack their weaknesses, and move the ball downfield. Typically, more yards equals more points.

      发挥重要作用,但不要束手无策 —我们已经看到,获得正码数对能够触地得分有积极影响。 但是,这并不意味着您每次玩都需要炸掉炸弹。 侦察防守,攻击他们的弱点,并将球移至低位。 通常,更多的码等于更多的点。

    • When you’re in the money zone, you got to make a deposit! — If you get the ball inside your opponent’s 10 yard line, you gotta score. Period. Inside the 10 is your easiest chance to score because of the short distance, so you got to take advantage of those opportunities when they present themselves.

      当您处于货币区时,您必须进行存款! —如果将球传到对手10码线内,您就可以得分。 期。 十杆之内是最容易得分的机会,这是因为距离很短,所以当他们展现自己时,您必须利用这些机会。

    • Limit turnovers, especially interceptions — You can’t score if you don’t have the ball. That’s good old-fashioned football 101 right there. Personally, I believe interceptions have a much stronger negative influence than fumbles because interceptions tend to be returned for more yards than fumbles do. This correlates with the Yard Line (100) feature explained above, in that the closer your offense can be to your opponent’s end zone, the easier it will be to score.

      限制失误,尤其是拦截 -如果没有球,就无法得分。 那就是那辆不错的老式足球101。 就我个人而言,我认为拦截比骗局具有更大的负面影响,因为拦截往往比骗局返回更多码。 这与上文所述的“围场线(100)”特征相关,因为您的进攻越接近对手的终点区域,得分就越容易。

    防守教练 (Defensive Coaches)

    • Use controlled, precise aggression to force interceptions — Defensive players love playing defense because they love to hit people! But, so many times we have seen defenses get burned for big plays when they are too aggressive. You want to put pressure on the offense so that you can force bad decisions, poor execution, and turnovers (ahem, interceptions). Offenses are throwing the ball more than ever, so there are plenty of opportunities to force quarterbacks into making mistakes.

      使用可控的,精确的进攻来强制拦截 -防守球员喜欢打防守,因为他们喜欢打人! 但是,很多时候我们都看到,防守过于激进时,他们的防守就会被大打大闹。 您想对进攻施加压力,以便您可以做出错误的决定,执行不力和失误(糟糕,拦截)。 进攻比以往任何时候都更为重要,因此有很多机会迫使四分卫犯错。

    • Limit yardage — I know, duh, right? That’s the defense’s job. But, the data verifies how important this is. Just like how on offense there is a positive correlation between yards gained and touchdowns scored, the same effect is felt in the opposite direction. If you limit how many yards the offense gains, you control where the ball is on the field, and you will limit the amount of touchdowns the offense can score.

      限制码数 -我知道,对不对? 那是国防部的工作。 但是,数据验证了这一点的重要性。 就像在进攻端获得的码数和触地得分之间有正相关关系一样,在相反的方向上也能感觉到相同的效果。 如果您限制进攻获得多少码,则可以控制球在场上的位置,并且可以限制进攻得分的触地得分数量。

    结论 (Conclusion)

    I had so much fun working on this project. I have always been a nerd for football stats, and I think it’s truly amazing that we have technology now where we can use that statistical information to create high-value insights in order to increase performance. At the end of the day, it is up to both the coaches and the players to execute their game-plan against their opponent. But, taking advantage of technology and knowledge like this to create the best gameplan possible will create the ultimate advantage. I hope you enjoyed reading! Go Vikings!

    我在这个项目上工作非常有趣。 我一直是足球统计专家的书呆子,我认为我们拥有现在可以使用统计信息来创造高价值洞察力以提高绩效的技术确实令人惊讶。 归根结底,教练和球员都必须执行对对手的比赛计划。 但是,利用这样的技术和知识来创造最佳的游戏计划将创造最终的优势。 希望您喜欢阅读! 去维京人!

    #Skol

    #斯科尔

    Image for post
    https://media3.giphy.com/media/f9R7zN83GuYataDz3W/giphy-downsized-large.gifhttps://media3.giphy.com/media/f9R7zN83GuYataDz3W/giphy-downsized-large.gif

    Github Repo

    Github回购

    翻译自: https://medium.com/the-sports-scientist/how-to-use-machine-learning-to-predict-touchdowns-12c3fa4cf3d8

    使用机器学习预测天气

    展开全文
  • 使用机器学习预测天气by Flavio H. Freitas Flavio H.Freitas着 如何使用机器学习根据文章标题预测喜欢和分享 (How to predict likes and shares based on your article’s title using Machine Learning) ...

    使用机器学习预测天气

    by Flavio H. Freitas

    Flavio H.Freitas着

    如何使用机器学习根据文章标题预测喜欢和分享 (How to predict likes and shares based on your article’s title using Machine Learning)

    Choosing a good title for an article is an important step in the writing process. The more interesting the title seems, the higher the chance a reader will interact with the whole thing. Furthermore, showing the user content they prefer (to interact with) increases the user’s satisfaction.

    为文章选择一个好的标题是写作过程中的重要一步。 标题似乎越有趣,读者与整个事物进行交互的机会就越高。 此外,显示他们喜欢(与之交互)的用户内容可以提高用户的满意度。

    This is how my final project from the Machine Learning Engineer Nanodegree specialization started. I just finished it, and I feel so proud and happy ? that I wanted to share with you some insights I’ve had about the whole flow. Also, I promised Quincy Larson this article when I finished the project.

    这就是我来自机器学习工程师纳米学位专业的最终项目的开始方式。 我刚完成,就感到如此自豪和幸福 ? 我想与您分享我对整个流程的一些见解。 另外,我在完成项目时向Q uincy Larson承诺了这篇文章。

    If you want to see the final technical document click here. If you want the implementation of the code, check it out here or fork my project on GitHub. If you just want an overview using layperson’s terms, this is the right place — continue reading this article.

    如果要查看最终技术文档, 请单击此处 。 如果您想执行代码,请在此处查看或在GitHub上分叉我的项目。 如果您只想使用通俗易懂的术语进行概述,那么这里是正确的地方-继续阅读本文。

    Some of the most used platforms to spread ideas nowadays are Twitter and Medium (you are here!). On Twitter, articles are normally posted including external URLs and the title, where users can access the article and demonstrate their satisfaction with a like or a retweet of the original post.

    如今,用于传播思想的一些最常用的平台是Twitter和Medium(您在这里!)。 在Twitter上,通常会发布包含外部URL和标题的文章,用户可以在其中访问文章并通过对原始帖子的赞或转发来表明其满意。

    Medium shows the full text with tags (to classify the article) and claps (similar to Twitter’s likes) to show how much the users appreciate the content. A correlation between these two platforms can bring us valuable information.

    中号显示带有标签(对文章进行分类)和拍手(类似于Twitter的赞)的全文,以显示用户对内容的欣赏程度。 这两个平台之间的关联可以为我们带来有价值的信息。

    该项目 (The project)

    The problem that I defined was a classification task using supervised learning: Predict the number of likes and retweets an article receives based on the title.

    我定义的问题是使用监督学习的分类任务: 根据标题预测文章收到的喜欢和转发的次数。

    Correlating the number of likes and retweets from Twitter with a Medium article is an attempt to isolate the effect of the number of reached readers and the number of Medium claps. Because the more the article is shared on different platforms, the more readers it will reach and the more Medium claps it will (likely) receive.

    将来自Twitter的点赞和转发的次数与“中型”文章相关联,是一种尝试将达到的读者数量和“中型”拍手数量的影响分开的尝试。 由于在不同平台上分享的文章越多,读者就会越多,并且(可能)会收到更多的中奖。

    Using only the Twitter statistic, we’d expect that the articles reached initially almost the same number of readers (those readers being the followers of the freeCodeCamp account on Twitter). Their performance and interactions, therefore, would be limited to the characteristics of the tweet — for example, the title of the article. And that is exactly what we want to measure.

    我们仅使用Twitter统计信息,就可以预期文章最初吸引的读者人数几乎相同(这些读者是Twitter上freeCodeCamp帐户的追随者)。 因此,它们的性能和交互作用将仅限于该推文的特性,例如,文章标题。 而这正是我们要衡量的。

    I chose the freeCodeCamp account for this project because the idea was to limit the scope of the subject of the articles and better predict the response on a specific field. The same title can perform well in one category (e.g. Technology), but not necessarily in a different one (e.g. Culinary). Also, this account posts the title of the original article and the URL on Medium as the tweet content.

    我之所以选择该项目的freeCodeCamp帐户 ,是因为其想法是限制文章主题的范围,并更好地预测特定领域的响应。 同一标题在一个类别(例如技术)中可以表现良好,但不一定在另一个类别(例如烹饪)中表现良好。 另外,此帐户将原始文章的标题和URL张贴在Medium上作为推文内容。

    数据看起来如何? (How does the data look?)

    The first step of this project was to get the information from Twitter and Medium and then correlate it. The dataset can be found here and it has 711 data points. This is how the dataset looks like:

    该项目的第一步是从Twitter和Medium获取信息,然后将其关联。 数据集可以在这里找到,它具有711个数据点。 数据集如下所示:

    分析和学习数据 (Analyzing and learning with the data)

    After analyzing the dataset and plotting some graphics, I found interesting information about it. For these analyses, the outliers were removed, and I just considered the 25% top performers for each feature (retweet, like, and clap).

    在分析数据集并绘制一些图形之后,我发现了有关它的有趣信息。 对于这些分析, 离群值被删除了,我只是考虑了每个功能(转推,喜欢和鼓掌)中表现最好25%

    So let’s take a look at what the numbers say for freeCodeCamp articles written on Medium and shared on Twitter.

    因此,让我们看一下这些数字对在Medium上写并在Twitter上共享的freeCodeCamp文章的含义。

    好的标题长度是多少? (What is a good title length?)

    Writing titles that have a length greater than 50 and less than 110 characters helps to increase the chances of a successful article.

    撰写长度超过50个字符且少于110个字符的标题有助于增加文章成功的机会。

    标题中有多少个单词? (What is a good number of words in the title?)

    The most effective number of words in the title is 9 to 17. To optimize the number of retweets and likes, try something from 9 to 18 words, and for claps from 7 to 17.

    标题中最有效的单词数是9到17 。 要优化转发和点赞的次数,请尝试输入9到18个单词,拍手范围为7到17个单词。

    哪些类别最适合标记? (Which are the best categories to tag?)

    Programming, Tech, Technology, JavaScript and Web Development are categories you should consider when tagging your next article. They appear for all the three features as a good indicator.

    编程技术技术JavaScriptWeb开发是标记下一篇文章时应考虑的类别。 对于所有这三个功能,它们都可以作为一个很好的指示。

    最好使用哪些单词? (Which are the best words to use?)

    In this lexical analysis, you’ll notice that some words get much more attention on the freeCodeCamp community than others. If the intention is to make the articles reach further in numbers, talking about JavaScript, React or CSS will increase how much it’s appreciated. Using the words “learn” or “guide” to describe will also make the probability higher.

    在此词法分析中,您会注意到,在FreeCodeCamp社区中,某些单词比其他单词受到更多关注。 如果希望使文章的数量更多,那么谈论JavaScript,React或CSS将会增加它的赞赏程度。 使用“学习”或“指南”一词来描述也将使概率更高。

    使用机器学习 (Using Machine Learning)

    OK! After taking a look at the data and extracting some information from it, the goal was to create a Machine Learning model that makes predictions of the number of retweets, likes, and claps based on the title of the article.

    好! 在查看了数据并从中提取了一些信息之后,目标是创建一个机器学习模型,该模型根据文章的标题来预测转发,喜欢和拍手的数量。

    Predicting the number of retweets, likes, and claps of an article can be treated as a classification problem, and that is a common task of machine learning (ML). But for this, we need to use the output as discrete values (a range of numbers). The input will be the title of the articles with each word as a token (t1, t2, t3, … tn), the title length, and the number of words in the title.

    预测文章的转发,喜欢和拍手的数量可以视为分类问题,而这是机器学习(ML)的常见任务。 但是为此,我们需要将输出用作离散值(数字范围)。 输入将是文章的标题,每个单词作为标记(t1,t2,t3,…tn),标题长度和标题中的单词数。

    The ranges for our features are:

    我们的功能范围是:

    • Retweets: 0–10, 10–30, 30+

      转推:0-10、10-30、30 +
    • Likes: 0–25, 25–60, 60+

      喜欢:0–25、25–60、60 +
    • Claps: 0–50, 50–400, 400+

      拍手:0–50、50–400、400 +

    And finally, after preprocessing our dataset and evaluating some models (everything fully described here), we reached the conclusion that the MultinomialNB model performed better for retweets reaching an accuracy of 60.6%. Logistic regression reached 55.3% for likes and 49% for claps.

    最后,在对数据集进行预处理并评估了一些模型( 此处已全面描述)后,我们得出的结论是,MultinomialNB模型对转发的性能更好,达到60.6%的准确性。 对喜欢的Logistic回归达到55.3%,对拍手的Logistic回归达到49%。

    As an experiment for this article, I ran the prediction of the title of this article and the model predicted that:

    作为本文的实验,我对本文标题进行了预测,该模型预测:

    It will have 10–30 retweets and 25–60 favorites on Twitter and 400+ claps on Medium.

    在Twitter上将有10–30条转发和25–60条收藏夹,在Medium将有400多个拍手。

    How is this prediction? ?

    这个预测如何? ?

    Follow me if you want to read more of my articles ? And if you enjoyed this article, be sure to like it give me a lot of claps — it means the world to the writer.

    如果您想阅读更多我的文章,请 关注我而且,如果您喜欢这篇文章,请确保喜欢它给了我很多鼓掌-这对作家来说意味着世界。

    Flávio H. de Freitas is an Entrepreneur, Engineer, Tech lover, Dreamer and Traveler. Has worked as CTO in Brazil, Silicon Valley and Europe.

    FlávioH. de Freitas是一位企业家,工程师,技术爱好者,梦想家和旅行者。 曾在巴西硅谷和欧洲担任首席技术官

    翻译自: https://www.freecodecamp.org/news/how-to-predict-likes-and-shares-based-on-your-articles-title-using-machine-learning-47f98f0612ea/

    使用机器学习预测天气

    展开全文
  • 天气数据集爬取 爬取思路: 确定目标(目标网站:大同历史天气预报 2020年5月份) 请求网页(第三方库 requests) 解析网页(数据提取) 保存数据(这里以 .csv格式存储到本地) import...

    天气数据集爬取

     爬取思路:

    • 确定目标(目标网站:大同历史天气预报 2020年5月份)

    • 请求网页(第三方库 requests)

    • 解析网页(数据提取)

    • 保存数据(这里以 .csv 格式存储到本地)

    import requests

    from bs4  import BeautifulSoup

    import pandas  as pd

    def get_data (url) :

    # 请求网页(第三方 requests)

    resp = requests.get(url)

    # 对于获取到的 HTML 二进制文件进行 'gbk' 转码成字符串文件

    html = resp.content.decode( 'gbk' )

    # 通过第三方库 BeautifulSoup 缩小查找范围(同样作用的包库还有re模块、xpath等)

    soup = BeautifulSoup(html, 'html.parser' )

    # 获取 HTML 中所有<tr>…</tr>标签,因为我们需要的数据全部在此标签中存放

    tr_list = soup.find_all( 'tr' )

    # 初始化日期dates、气候contains、温度temp值

    dates,contains,temp = [],[],[]

    for data  in tr_list[ 1 :]:   # 不要表头

    # 数据值拆分,方便进一步处理(这里可以将获得的列表输出[已注释],不理解的读者可运行查看)

    sub_data = data.text.split()

    # print(sub_data)

    # 观察上一步获得的列表,这里只想要获得列表中第二个和第三个值,采用切片法获取

    dates.append(sub_data[ 0 ])

    contains.append( ',' .join(sub_data[ 1 : 3 ]))

    # print(contains)

    # 同理采用切片方式获取列表中的最高、最低气温

    temp.append( ',' .join(sub_data[ 3 : 6 ]))

    # print(temp)

    # 使用 _data 表存放日期、天气状况、气温表头及其值

    _data = pd.DataFrame()

    # 分别将对应值传入 _data 表中

    _data[ '日期' ] = dates

    _data[ '天气状况' ] = contains

    _data[ '气温' ] = temp

    return _data

    # 爬取目标网页(大同市2020年5月份天气[网站:天气后报])

    data_5_month = get_data( 'http://www.tianqihoubao.com/lishi/datong/month/202005.html' )

    # 拼接所有表并重新设置行索引(若不进行此步操作,可能或出现多个标签相同的值)

    data = pd.concat([data_5_month]).reset_index(drop =  True )

    # 将 _data 表以 .csv 格式存入指定文件夹中,并设置转码格式防止乱花(注:此转码格式可与 HTML 二进制转字符串的转码格式不同)

    data.to_csv( 'F:/DaTong5Mouth.csv' ,encoding= 'utf-8' )

    数据可视化

    数据可视化用到了可视化工具。

    其要点包含有:读取数据、数据清洗、数据处理、可视化工具的使用。

    # 数据可视化

    from matplotlib  import pyplot  as plt

    import pandas  as pd

    # 解决显示中文问题

    plt.rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]

    # 第一步:数据读取

    data = pd.read_csv( 'F:/DaTong5Mouth.csv' )

    # 第二步:数据处理(由于我们知道文本内容,不存在脏数据,故忽略数据清理步骤)

    data[ '最高气温' ] = data[ '气温' ].str.split( '/' ,expand= True )[ 0 ]

    data[ '最低气温' ] = data[ '气温' ].str.split( '/' ,expand= True )[ 1 ]

    data[ '最高气温' ] = data[ '最高气温' ].map( lambda x:x.replace( '℃,' , '' ))

    data[ '最低气温' ] = data[ '最低气温' ].map( lambda x:x.replace( '℃,' , '' ))

    dates = data[ '日期' ]

    highs = data[ '最高气温' ]

    lows = data[ '最低气温' ]

    # 画图(折线图)

    # 设置画布大小及比例

    fig = plt.figure(dpi= 128 ,figsize=( 10 , 6 ))

    # 设置最高温最低温线条颜色及宽度等信息

    L1,=plt.plot(dates,lows,label= '最低气温' )

    L2,=plt.plot(dates,highs,label= '最高气温' )

    plt.legend(handles=[L1,L2],labels=[ '最高气温' , '最低气温' ], loc= 'best' ) # 添加图例

    # 图表格式

    # 设置图形格式

    plt.title( '2020年5月上旬大同天气' ,fontsize= 25 )   # 字体大小设置为25

    plt.xlabel( '日期' ,fontsize= 10 )    # x轴显示“日期”,字体大小设置为10

    fig.autofmt_xdate()  # 绘制斜的日期标签,避免重叠

    plt.ylabel( '气温' ,fontsize= 10 )   # y轴显示“气温”,字体大小设置为10

    plt.tick_params(axis= 'both' ,which= 'major' ,labelsize= 10 )

    # plt.plot(highs,lows,label = '最高气温')

    # 修改刻度

    plt.xticks(dates[:: 1 ])   # 由于数据不多,将每天的数据全部显示出来

    # 显示折线图

    plt.show()

    模型预测数据

    1、单变量线性回归

    模型一:单变量线性回归模型

    import numpy  as np

    import pandas  as pd

    import matplotlib.pyplot  as plt

    # 解决中文问题(若没有此步骤,表名字及横纵坐标中的汉语将无法显示[具体会显示矩形小方格])

    plt.rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]

    # 将数据从上一步存入的 .csv 格式文件中读取

    data = pd.read_csv( r'F:\DaTong5Mouth.csv' )

    # 由于最高气温与最低气温中有 / 分隔,故将其分开,即“气温”列由一列变为两列——“最高气温”和“最低气温”

    data[ '最高气温' ] = data[ '气温' ].str.split( '/' ,expand= True )[ 0 ]

    # 我们要对数值进行分析,所以将多余的单位 ℃ 从列表中去掉,只保留数值部分

    data[ '最高气温' ] = data[ '最高气温' ].map( lambda x:x.replace( '℃,' , '' ))

    # 日次操作同理,这里不再赘述

    data[ '日期' ] = data[ '日期' ].map( lambda x:x.replace( '2020年05月0' , '' ))

    data[ '日期' ] = data[ '日期' ].map( lambda x:x.replace( '日' , '' ))

    # 不理解的小伙伴可运行下两行代码查看运行结果(这里先注释掉了)

    # print(data['日期'])

    # print(data['最高气温'])

    def initPlot () :

    # 先准备好一块画布

    plt.figure()

    # 生成图表的名字

    plt.title( '2020年5月上旬大同天气' )

    # 横坐标名字

    plt.xlabel( '日期' )

    # 纵坐标名字

    plt.ylabel( '当日最高气温' )

    # 表内有栅格(不想要栅格把此行注释掉即可)

    plt.grid( True ) 

    return plt

    plt = initPlot()   # 画图

    # 传入对应日期及其最高气温参数

    xTrain = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])

    yTrain = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])

    # k是黑色,.是以点作为图上显示

    plt.plot(xTrain, yTrain,  'k.' )

    # 将图显示出来

    plt.show()

    可以看到:

    • 最高气温随着日期的变化,大致呈现线性变化(最近气温下降);

    • 如果根据现有的训练数据能够拟合出一条直线,使之与这些训练数据的各点都比较接近,那么根据该直线,就可以计算出在10号或者11号的温度情况(气温受到影响因素较多,故这里仅预测为数不多的数据)。

    解决方案:

    • 采用Python scikit-learn库中提供的sklearn.linear_model.LinearRegression对象来进行线性拟合。

    • 根据判别函数,绘制拟合直线,并同时显示训练数据点。

    • 拟合的直线较好的穿过训练数据,根据新拟合的直线,可以方便的求出最近日期下对应的最高气温(预测结果)。

    import numpy  as np

    import pandas  as pd

    import matplotlib.pyplot  as plt

    from sklearn.linear_model  import LinearRegression

    # 解决中文问题(若没有此步骤,表名字及横纵坐标中的汉语将无法显示[具体会显示矩形小方格])

    plt.rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]

    # 将数据从上一步存入的 .csv 格式文件中读取

    data = pd.read_csv( r'F:\DaTong5Mouth.csv' )

    # 由于最高气温与最低气温中有 / 分隔,故将其分开,即“气温”列由一列变为两列——“最高气温”和“最低气温”

    data[ '最高气温' ] = data[ '气温' ].str.split( '/' ,expand= True )[ 0 ]

    # 我们要对数值进行分析,所以将多余的单位 ℃ 从列表中去掉,只保留数值部分

    data[ '最高气温' ] = data[ '最高气温' ].map( lambda x:x.replace( '℃,' , '' ))

    # 日次操作同理,这里不再赘述

    data[ '日期' ] = data[ '日期' ].map( lambda x:x.replace( '2020年05月0' , '' ))

    data[ '日期' ] = data[ '日期' ].map( lambda x:x.replace( '日' , '' ))

    # 不理解的小伙伴可运行下两行代码查看运行结果(这里先注释掉了)

    # print(data['日期'])

    # print(data['最高气温'])

    # 传入对应日期及其最高气温参数

    # # 应以矩阵形式表达(对于单变量,矩阵就是列向量形式)

    xTrain = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]

    # 为方便理解,也转换成列向量

    yTrain = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])

    # 创建模型对象

    model = LinearRegression()

    # 根据训练数据拟合出直线(以得到假设函数)

    hypothesis = model.fit(xTrain, yTrain)

    # 截距

    print( "theta0=" , hypothesis.intercept_)

    # 斜率

    print( "theta1=" , hypothesis.coef_)

    # 预测2020年5月10日的最高气温

    print( "预测2020年5月10日的最高气温:" , model.predict([[ 10 ]]))

    # 也可以批量预测多个日期的气温,注意要以列向量形式表达(有余数据集量少,故间隔时间长气温可能有较大差异)

    # 此处仅利用模型表示,不代表真实值(假设要预测10号、11号、12号的天气)

    xNew = np.array([ 0 , 10 ,  11 ,  12 ])[:, np.newaxis]

    yNew = model.predict(xNew)

    print( "预测新数据:" , xNew)

    print( "预测结果:" , yNew)

    def initPlot () :

    # 先准备好一块画布

    plt.figure()

    # 生成图表的名字

    plt.title( '2020年5月上旬大同天气' )

    # 横坐标名字

    plt.xlabel( '日期' )

    # 纵坐标名字

    plt.ylabel( '当日最高气温' )

    # 表内有栅格(不想要栅格把此行注释掉即可)

    plt.grid( True )

    return plt

    plt = initPlot()   # 画图

    # k是黑色,.是以点作为图上显示

    plt.plot(xTrain, yTrain,  'k.' )

    # 画出通过这些点的连续直线

    plt.plot(xNew, yNew,  'g--' )

    # 将图显示出来

    plt.show()

    模型评价:

    拟合出来的判别函数效果如何:对训练数据的贴合度如何?对新数据的预测准确度如何?

    可通过残差(residuals)和R方(r-squared)判断, 在Python中如何对单变量线性回归模型的效果进行评估。

    手动计算:

    假设hpyTrain代表针对训练数据的预测最高气温值,hpyTest代表针对测试数据的预测最高气温值。

    • 训练数据残差平方和:ssResTrain = sum((hpyTrain - yTrain) ** 2)

    • 测试数据残差平方和:ssResTest = sum((hpyTest - yTest) ** 2)

    • 测试数据偏差平方和:ssTotTest = sum((yTest - np.mean(yTest)) ** 2)

    • R方:Rsquare = 1 -ssResTest / ssTotTest

    LinearRegression对象提供的方法:

    • 训练数据残差平方和:model._residues

    • R方:model.score(xTest,yTest)

    import numpy  as np

    import pandas  as pd

    import matplotlib.pyplot  as plt

    from sklearn.linear_model  import LinearRegression

    # 解决中文问题(若没有此步骤,表名字及横纵坐标中的汉语将无法显示[具体会显示矩形小方格])

    plt.rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]

    # 将数据从上一步存入的 .csv 格式文件中读取

    data = pd.read_csv( r'F:\DaTong5Mouth.csv' )

    # 由于最高气温与最低气温中有 / 分隔,故将其分开,即“气温”列由一列变为两列——“最高气温”和“最低气温”

    data[ '最高气温' ] = data[ '气温' ].str.split( '/' ,expand= True )[ 0 ]

    # 我们要对数值进行分析,所以将多余的单位 ℃ 从列表中去掉,只保留数值部分

    data[ '最高气温' ] = data[ '最高气温' ].map( lambda x:x.replace( '℃,' , '' ))

    # 日次操作同理,这里不再赘述

    data[ '日期' ] = data[ '日期' ].map( lambda x:x.replace( '2020年05月0' , '' ))

    data[ '日期' ] = data[ '日期' ].map( lambda x:x.replace( '日' , '' ))

    # 不理解的小伙伴可运行下两行代码查看运行结果(这里先注释掉了)

    # print(data['日期'])

    # print(data['最高气温'])

    # 传入对应日期及其最高气温参数

    # # # 应以矩阵形式表达(对于单变量,矩阵就是列向量形式)

    # xTrain = np.array(data['日期'])[:, np.newaxis]

    # # 为方便理解,也转换成列向量

    # yTrain = np.array(data['最高气温'])

    xTrain = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]   # 训练数据(日期)

    yTrain = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])         # 训练数据(最高气温)

    xTest = np.array([ 3 , 6 , 9 , 10 , 11 ])[:,np.newaxis]           # 测试数据(日期)

    yTest = np.array([ 28 , 27 , 22 , 20 , 19 ])                     # 测试数据(最高气温)

    # 创建模型对象

    model = LinearRegression()

    # 根据训练数据拟合出直线(以得到假设函数)

    hypothesis = model.fit(xTrain, yTrain)

    hpyTrain = model.predict(xTrain)

    # 针对测试数据进行预测

    hpyTest = model.predict(xTest)

    # 手动计算训练数据集残差

    ssResTrain = sum((hpyTrain - yTrain) **  2 )

    print(ssResTrain)

    # Python计算的训练数据集残差

    print(model._residues)

    # 手动计算测试数据集残差

    ssResTest = sum((hpyTest - yTest) **  2 )

    # 手动计算测试数据集y值偏差平方和

    ssTotTest = sum((yTest - np.mean(yTest)) **  2 )

    # 手动计算R方

    Rsquare =  1 - ssResTest / ssTotTest

    print(Rsquare)

    # Python计算的训练数据集的R方

    print(model.score(xTest, yTest))

    # corrcoef函数是在各行元素之间计算相关性,所以x和y都应是行向量

    print(np.corrcoef(xTrain.T, yTrain.T))   # 计算训练数据的相关性

    print(np.corrcoef(xTest.T, yTest.T))     # 计算测试数据的相关性

    def initPlot () :

    # 先准备好一块画布

    plt.figure()

    # 生成图表的名字

    plt.title( '2020年5月上旬大同天气' )

    # 横坐标名字

    plt.xlabel( '日期' )

    # 纵坐标名字

    plt.ylabel( '当日最高气温' )

    # 表内有栅格(不想要栅格把此行注释掉即可)

    plt.grid( True )

    return plt

    plt = initPlot()

    plt.plot(xTrain, yTrain,  'r.' )           # 训练点数据(红色)

    plt.plot(xTest, yTest,  'b.' )             # 测试点数据(蓝色)

    plt.plot(xTrain, hpyTrain,  'g-' )         # 假设函数直线(绿色)

    plt.show()

    查看上述拟合效果:

    • 红色为训练数据点,蓝色为测试数据点,绿色为判别函数(拟合直线);

    • 计算出的R方为0.833,效果良;

    • 计算出训练数据的相关性为-0.763,测试数据的相关性为-0.968。可以发现,根据数据集的不同,日期与最高气温之间的相关性波动较大。这也能解释为何针对测试数据的R方事实上不够理想。

    2、多变量线性回归

    在单变量线性回归中,最高气温仅与日期有关(尝试可知,这显然是极不合理的),按照这一假设,其预测的结果并不令人满意(R方=0.833)。因此在多变线性回归模型中再引入一个新的影响因素:最低气温(此处要注意和最高气温一样,计算前先利用 .map 方法将 ℃ 置空,仅将最低气温调整成数值,以便能够进行数值计算)。

    模型二:基于LinearRegression实现的多变量线性回归模型

    • 与单变量线性回归类似,但要注意训练数据此时是(是训练数据条数,是自变量个数)

    • 针对测试数据的预测结果,其R方约为0.466,这时我们发现还没有单变量量线性回归R方值大,说明拟合效果差于单变量线性回归。这是什么问题呢?经过思考,我认为最高气温的影响因素不能拿日期和最低气温来衡量,也就是说,最高气温的走势依据情况特殊而复杂,不能单靠日期和最低气温等片面的为数不多的方面来进行拟合。

    import numpy  as np

    import pandas  as pd

    import matplotlib.pyplot  as plt

    from sklearn.linear_model  import LinearRegression

    # 解决中文问题(若没有此步骤,表名字及横纵坐标中的汉语将无法显示[具体会显示矩形小方格])

    plt.rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]

    # 将数据从上一步存入的 .csv 格式文件中读取

    data = pd.read_csv( r'F:\DaTong5Mouth.csv' )

    # 由于最高气温与最低气温中有 / 分隔,故将其分开,即“气温”列由一列变为两列——“最高气温”和“最低气温”

    data[ '最高气温' ] = data[ '气温' ].str.split( '/' ,expand= True )[ 0 ]

    # 我们要对数值进行分析,所以将多余的单位 ℃ 从列表中去掉,只保留数值部分

    data[ '最高气温' ] = data[ '最高气温' ].map( lambda x:x.replace( '℃,' , '' ))

    data[ '最低气温' ] = data[ '气温' ].str.split( '/' ,expand= True )[ 1 ]

    # 我们要对数值进行分析,所以将多余的单位 ℃ 从列表中去掉,只保留数值部分

    data[ '最低气温' ] = data[ '最低气温' ].map( lambda x:x.replace( '℃,' , '' ))

    # 日次操作同理,这里不再赘述

    data[ '日期' ] = data[ '日期' ].map( lambda x:x.replace( '2020年05月0' , '' ))

    data[ '日期' ] = data[ '日期' ].map( lambda x:x.replace( '日' , '' ))

    # 不理解的小伙伴可运行下两行代码查看运行结果(这里先注释掉了)

    # print(data['日期'])

    # print(data['最高气温'])

    # print(data['最低气温'])

    # 传入对应日期及其最高气温参数

    # # # 应以矩阵形式表达(对于单变量,矩阵就是列向量形式)

    # xTrain = np.array(data['日期'])[:, np.newaxis]

    # # 为方便理解,也转换成列向量

    # yTrain = np.array(data['最高气温'])

    # 训练集

    xTrain = np.array([ 1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ])   # 无需手动添加Intercept Item项

    yTrain = np.array([[ 33 ,  8 ], [ 35 ,  9 ], [ 28 ,  4 ], [ 20 ,  4 ], [ 26 ,  6 ], [ 27 , 10 ], [ 23 , 10 ], [ 22, 7 ], [ 22 , 3 ]])

    # 测试集

    xTest = np.array([ 3 ,  6 ,  9 ,  10 ,  11 ])

    yTest = np.array([[ 28 ,  4 ], [ 27 ,  10 ], [ 22 ,  3 ], [ 20 ,  5 ], [ 19 ,  7 ]])

    # 创建模型对象

    model = LinearRegression()

    # 根据训练数据拟合出直线(以得到假设函数)

    model.fit(yTrain, xTrain)

    # 针对测试数据进行预测

    hpyTest = model.predict(yTest)

    print( "假设函数参数:" , model.intercept_, model.coef_)

    print( "测试数据预测结果与实际结果差异:" , hpyTest - xTest)

    print( "测试数据R方:" , model.score(yTest, xTest))

    模型三:基于成本函数和梯度下降实现的多变量线性回归模型

    • 经过模型三的拟合,我们发现R方仅为0.164,还不如模型二的预测结果呢。而根据理论知识我们知道,这个模型预测结果应该是线性回归模型中预测拟合效果较好的一种,低的这个R方值经过思考,可进一步说明最高气温的影响因素不仅仅取决于日期和最低气温,甚至我们可推断出可能与日期及最低气温值等影响因素无关。

    • 通过运行结果发现“50000次循环后,计算仍未收敛”。这说明①在未对自变量归一化处理的情况下,运算出现异常,无法收敛;②设置了过大的学习速率,会导致计算不收敛。

    import numpy  as np

    import pandas  as pd

    import matplotlib.pyplot  as plt

    import bgd_resolver

    from sklearn.linear_model  import LinearRegression

    # 解决中文问题(若没有此步骤,表名字及横纵坐标中的汉语将无法显示[具体会显示矩形小方格])

    plt.rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]

    def costFn (theta, X, y) : # 成本函数

    temp = X.dot(theta) - y

    return (temp.T.dot(temp)) / ( 2 * len(X))

    def gradientFn (theta, X, y) : # 根据成本函数,分别对x0,x1...xn求导数(梯度)

    return (X.T).dot(X.dot(theta) - y) / len(X)

    # 将数据从上一步存入的 .csv 格式文件中读取

    data = pd.read_csv( r'F:\DaTong5Mouth.csv' )

    # 由于最高气温与最低气温中有 / 分隔,故将其分开,即“气温”列由一列变为两列——“最高气温”和“最低气温”

    data[ '最高气温' ] = data[ '气温' ].str.split( '/' ,expand= True )[ 0 ]

    # 我们要对数值进行分析,所以将多余的单位 ℃ 从列表中去掉,只保留数值部分

    data[ '最高气温' ] = data[ '最高气温' ].map( lambda x:x.replace( '℃,' , '' ))

    data[ '最低气温' ] = data[ '气温' ].str.split( '/' ,expand= True )[ 1 ]

    # 我们要对数值进行分析,所以将多余的单位 ℃ 从列表中去掉,只保留数值部分

    data[ '最低气温' ] = data[ '最低气温' ].map( lambda x:x.replace( '℃,' , '' ))

    # 日次操作同理,这里不再赘述

    data[ '日期' ] = data[ '日期' ].map( lambda x:x.replace( '2020年05月0' , '' ))

    data[ '日期' ] = data[ '日期' ].map( lambda x:x.replace( '日' , '' ))

    # 不理解的小伙伴可运行下两行代码查看运行结果(这里先注释掉了)

    # print(data['日期'])

    # print(data['最高气温'])

    # print(data['最低气温'])

    # 传入对应日期及其最高气温参数

    # # # 应以矩阵形式表达(对于单变量,矩阵就是列向量形式)

    # xTrain = np.array(data['日期'])[:, np.newaxis]

    # # 为方便理解,也转换成列向量

    # yTrain = np.array(data['最高气温'])

    # 训练集

    xTrain = np.array([ 1 ,  2 ,  3 ,  4 ,  5 ,  6 ,  7 ,  8 ,  9 ])   # 无需手动添加Intercept Item项

    yTrainData = np.array([[ 33 ,  8 ], [ 35 ,  9 ], [ 28 ,  4 ], [ 20 ,  4 ], [ 26 ,  6 ], [ 27 , 10 ], [ 23 , 10], [ 22 , 7 ], [ 22 , 3 ]])

    yTrain = np.c_[yTrainData, np.ones(len(yTrainData))]

    np.random.seed( 0 )

    init_theta = np.random.randn(yTrain.shape[ 1 ])

    theta = bgd_resolver.batch_gradient_descent(costFn, gradientFn, init_theta, yTrain, xTrain)

    print( "theta值" , theta)

    # 测试集

    xTest = np.array([ 3 ,  6 ,  9 ,  10 ,  11 ])

    yTestData = np.array([[ 28 ,  4 ], [ 27 ,  10 ], [ 22 ,  3 ], [ 20 ,  5 ], [ 19 ,  7 ]])

    yTest = np.c_[yTestData, np.ones(len(yTestData))]

    print( "测试数据预测值与真实值的差异:" , xTest.dot(theta) - xTest)

    rsquare = bgd_resolver.batch_gradient_descent_rsquare(theta, yTest, xTest)

    print( "测试数据R方:" , rsquare)

    3、以"线性回归"的方式来拟合高阶曲线

    这一部分我们分别使用一阶曲线(直线)、二阶曲线和三阶曲线进行拟合,并检查拟合效果。

    在拟合数据点时,一般来说,对于一个自变量的,拟合出来是一条直线;对于两个自变量的,拟合出来时一个直平面。这种拟合结果是严格意义上的“线性”回归。但是有时候,采用“曲线”或“曲面”的方式来拟合,能够对训练数据产生更逼近的效果。这就是“高阶拟合”。

    首先,我们查看要拟合的数据:

    import numpy  as np

    import matplotlib.pyplot  as plt

    # 解决中文问题(若没有此步骤,表名字及横纵坐标中的汉语将无法显示[具体会显示矩形小方格])

    plt.rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]

    xTrain = np. array ([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]   # 训练数据(日期)

    yTrain = np. array ([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])         # 训练数据(最高气温)

    xTest = np. array ([ 3 , 6 , 9 , 10 , 11 ])[:,np.newaxis]           # 测试数据(日期)

    yTest = np. array ([ 28 , 27 , 22 , 20 , 19 ])                     # 测试数据(最高气温)

    plotData = np. array (np.linspace( 0 ,  15 ,  30 ))[:,np.newaxis]           # 作图用的数据点

    def initPlot():

    plt.figure()

    plt.title( '2020年5月上旬大同天气' )

    plt.xlabel( '日期' )

    plt.ylabel( '气温' )

    plt.grid( True )

    return plt

    plt = initPlot()

    plt.plot(xTrain, yTrain,  'r.' )           # 训练点数据(红色)

    plt.plot(xTest, yTest,  'b.' )             # 测试点数据(蓝色)

    plt.show()

    模型四:一阶线性拟合

    from sklearn.linear_model import LinearRegression

    # 线性拟合

    linearModel = LinearRegression()

    linearModel.fit(xTrain, yTrain)

    linearModelTrainResult = linearModel.predict(plotData)

    # 计算R方

    linearModelRSquare = linearModel.score(xTest, yTest)

    print("线性拟合R方:", linearModelRSquare)

    plt = initPlot()

    plt.plot(xTrain, yTrain, 'r.')           # 训练点数据(红色)

    plt.plot(xTest, yTest, 'b.')             # 测试点数据(蓝色)

    plt.plot(plotData, linearModelTrainResult, 'y-')            # 线性拟合线

    plt.show()

    模型五:二阶曲线拟合

    • PolynomialFeatures.fit_transform提供了将1阶数据扩展到高阶数据的方法;

    • 训练样本和测试样本都需要进行扩充。

    from sklearn.preprocessing import PolynomialFeatures

    from sklearn.linear_model import LinearRegression

    # 二阶曲线拟合  theta0 + theta1*x + theta2*x*x   x*x => z     theta0+theta1*x+theta2*z

    quadratic_featurizer = PolynomialFeatures(degree=2)

    xTrain_quadratic = quadratic_featurizer.fit_transform(xTrain)

    print(xTrain_quadratic)     # 查看扩展后的特征矩阵

    quadraticModel = LinearRegression()

    quadraticModel.fit(xTrain_quadratic, yTrain)

    # 计算R方(针对测试数据)

    xTest_quadratic = quadratic_featurizer.fit_transform(xTest)

    quadraticModelRSquare = quadraticModel.score(xTest_quadratic, yTest)

    print("二阶拟合R方:", quadraticModelRSquare)

    # 绘图点也同样需要进行高阶扩充以便使用曲线进行拟合

    plotData_quadratic = quadratic_featurizer.fit_transform(plotData)

    quadraticModelTrainResult = quadraticModel.predict(plotData_quadratic)

    plt = initPlot()

    plt.plot(xTrain, yTrain, 'r.')           # 训练点数据(红色)

    plt.plot(xTest, yTest, 'b.')             # 测试点数据(蓝色)

    plt.plot(plotData, quadraticModelTrainResult, 'g-')         # 二阶拟合线

    plt.show()

    模型六:三阶曲线拟合

    from sklearn.preprocessing import PolynomialFeatures

    from sklearn.linear_model import LinearRegression

    # 三阶曲线拟合

    cubic_featurizer = PolynomialFeatures(degree=3)

    xTrain_cubic = cubic_featurizer.fit_transform(xTrain)

    cubicModel = LinearRegression()

    cubicModel.fit(xTrain_cubic, yTrain)

    plotData_cubic = cubic_featurizer.fit_transform(plotData)

    cubicModelTrainResult = cubicModel.predict(plotData_cubic)

    # 计算R方(针对测试数据)

    xTest_cubic = cubic_featurizer.fit_transform(xTest)

    cubicModelRSquare =  cubicModel.score(xTest_cubic, yTest)

    print("三阶拟合R方:", cubicModelRSquare)

    plt = initPlot()

    plt.plot(xTrain, yTrain, 'r.')           # 训练点数据(红色)

    plt.plot(xTest, yTest, 'b.')             # 测试点数据(蓝色)

    plt.plot(plotData, cubicModelTrainResult, 'p-')             # 三阶拟合线

    plt.show()

    综上对比我们发现,一阶拟合R方约为0.833,二阶拟合R方约为0.218,三阶拟合R方约为0.800。很显然,得到的拟合R方值并不是随着阶数的增高而增大,同前理,说明日期和最低气温并不是最高气温的影响因素。这正与我们常识所知的结论相吻合。因此,想要预测天气值就错综而复杂,不得片面考虑一个或为数不多的几个因素,且不应考虑到与气温影响因素无关的影响变量:比如说像上例中所提及的日期、最低气温等。

    4、线性回归预测天气

    模型七:线性回归预测模型

    使用sklearn.linear_model.LinearRegression处理。

    无需对自变量进行归一化处理,也能得到一致的结果。针对训练数据的R方约为0.583。

    (1)装载并查看数据信息

    import numpy  as np

    xTrain = np. array ([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]   # 训练数据(日期)

    yTrain = np. array ([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])         # 训练数据(最高气温)

    # 查看天气统计数据

    print ( "天气数据统计:" )

    print ( "最低:%.2f, 最高:%.2f, 平均:%.2f, 中位数:%.2f, 标准差:%.2f" %

    (np.min(yTrain), np.max(yTrain), np.mean(yTrain), np.median(yTrain) ,np.std(yTrain)))

    (2)使用LinearRegression,没有进行归一化预处理

    ''' 使用LinearRegression,没有进行归一化预处理 '''

    import numpy  as np

    from sklearn.linear_model  import LinearRegression

    train_data = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]   # 训练数据(日期)

    train_temp = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])[:, np.newaxis]       # 训练数据(最高气温)

    xTrain = np.array(train_data[:,  0 : 2 ])

    yTrain = np.array(train_temp[:,  -1 ])

    xTrain = np.c_[xTrain, np.ones(len(xTrain))]

    model = LinearRegression()

    model.fit(xTrain, yTrain)

    (3)使用LinearRegression,进行归一化预处理 

    ''' 使用LinearRegression,进行归一化预处理 '''

    import numpy  as np

    from sklearn.linear_model  import LinearRegression

    def normalizeData (X) :

    # 每列(每个Feature)分别求出均值和标准差,然后与X的每个元素分别进行操作

    return (X - X.mean(axis= 0 ))/X.std(axis= 0 )

    train_data = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]   # 训练数据(日期)

    train_temp = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])[:, np.newaxis]       # 训练数据(最高气温)

    xTrain = np.array(train_data[:,  0 : 2 ])

    yTrain = np.array(train_temp[:,  -1 ])

    xTrain = normalizeData(xTrain)

    xTrain = np.c_[xTrain, np.ones(len(xTrain))]         # 归一化完成后再添加intercept item列

    model = LinearRegression()

    model.fit(xTrain, yTrain)

    print( "LinearRegression计算R方:" , model.score(xTrain, yTrain))

    使用自定义的批量梯度下降法:

    • 在未对自变量归一化处理的情况下,运算可能出现异常,无法收敛,但这里没有出现;

    • 归一化处理后,能够得到与LinearRegression类似的结果,即R方值约为0.582;

    • 因此,不考虑影响因素合不合理情况下这种预测结果实质上准确率不容乐观。

    1:使用自定义BGD,未作归一化处理(可能无法收敛,但这里没有出现无法收敛情况)

    ''' 使用自定义BGD,未作归一化处理,可能无法收敛 '''

    import numpy  as np

    import bgd_resolver

    def costFn (theta, X, y) :

    temp = X.dot(theta) - y

    return (temp.T.dot(temp)) / ( 2 * len(X))

    def gradientFn (theta, X, y) :

    return (X.T).dot(X.dot(theta) - y) / len(X)

    train_date = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]   # 训练数据(日期)

    train_temp = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])[:, np.newaxis]       # 训练数据(最高气温)

    xTrain = np.array(train_date[:,  0 : 2 ])

    yTrain = np.array(train_temp[:,  -1 ])

    xTrain = np.c_[xTrain, np.ones(len(xTrain))]

    init_theta = np.random.randn(xTrain.shape[ 1 ])

    # 如果数据不进行Normalize,则下面的梯度算法有可能不收敛

    theta = bgd_resolver.batch_gradient_descent(costFn, gradientFn, init_theta, xTrain, yTrain)

    rsquare = bgd_resolver.batch_gradient_descent_rsquare(theta, xTrain, yTrain)

    print( "梯度下降法计算R方:" , rsquare)

    2:使用自定义BGD,作归一化处理

    ''' 使用自定义BGD,作归一化处理 '''

    import numpy  as np

    import bgd_resolver

    def normalizeData (X) :

    # 每列(每个Feature)分别求出均值和标准差,然后与X的每个元素分别进行操作

    return (X - X.mean(axis= 0 ))/X.std(axis= 0 )         

    def costFn (theta, X, y) :

    temp = X.dot(theta) - y

    return (temp.T.dot(temp)) / ( 2 * len(X))

    def gradientFn (theta, X, y) :

    return (X.T).dot(X.dot(theta) - y) / len(X)

    train_date = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]   # 训练数据(日期)

    train_temp = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])[:, np.newaxis]       # 训练数据(最高气温)

    xTrain = np.array(train_date[:,  0 : 2 ])

    yTrain = np.array(train_temp[:,  -1 ])

    xTrain = np.c_[xTrain, np.ones(len(xTrain))]

    init_theta = np.random.randn(xTrain.shape[ 1 ])

    # 如果数据不进行Normalize,则下面的梯度算法有可能不收敛

    theta = bgd_resolver.batch_gradient_descent(costFn, gradientFn, init_theta, xTrain, yTrain)

    rsquare = bgd_resolver.batch_gradient_descent_rsquare(theta, xTrain, yTrain)

    print( "梯度下降法计算R方:" , rsquare)

    5、线性回归的其它计算方法 

    模型八:基于协方差-方差公式实现的线性回归模型

    事实上,使用该方法计算出来的判别函数参数,与LinearRegression对象的计算结果一致。

    ''' 使用协方差-方差公式计算线性回归权重参数,并与LinearRegression结果对比 '''

    import numpy  as np

    from sklearn.linear_model  import LinearRegression

    xTrain = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]   # 训练数据(日期)

    yTrain = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])      # 训练数据(最高气温)

    model = LinearRegression()

    hypothesis = model.fit(xTrain, yTrain)

    print( "LinearRegression theta1=" , hypothesis.coef_)

    print( "LinearRegression theta0=" , hypothesis.intercept_)

    # cov函数是在各行元素之间计算协方差,所以x和y都应是行向量

    theta1 =  np.cov(xTrain.T, yTrain, ddof= 1 )[ 1 , 0 ] / np.var(xTrain, ddof= 1 )

    theta0 = np.mean(yTrain) - theta1 * np.mean(xTrain)

    print( "Least Square theta1=" , theta1)                    # 通过最小二乘法公式计算的斜率

    模型九:基于成本函数和批量梯度下降算法实现的线性回归模型

    成本函数:

    • 在使用训练数据来训练模型时,用于定义判别函数与实际值的误差。成本函数计算结果越小,说明该模型与训练数据的匹配程度越高;

    • 设定了某个模型后,只要给定了成本函数,就可以使用数值方法求出成本函数的最优解(极小值),从而确定判别函数模型中各个系数。

    梯度下降:

    梯度下降是迭代法的一种,可以用于求解最小二乘问题(线性和非线性都可以)。在求解机器学习算法的模型参数,即无约束优化问题时。

    ''' 使用批量梯度下降算法优化线性回归权重参数 '''

    import numpy  as np

    import matplotlib.pyplot  as plt

    import bgd_resolver     # 来自bgd_resolver.py文件

    def costFn (theta, X, y) : # 定义线性回归的成本函数

    temp = X.dot(theta) - y

    return temp.dot(temp) / ( 2 *len(X))

    def gradientFn (theta, X, y) : # 根据成本函数,分别对x0和x1求导数(梯度)

    return (X.T).dot(X.dot(theta) - y) / len(X)

    xTrain = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]   # 训练数据(日期)

    yTrain = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])      # 训练数据(最高气温)

    xTrain_ext = np.c_[np.ones(len(xTrain)), xTrain]         # 第一列补充0。注意返回的第一个权重参数将对应theta0

    np.random.seed( 0 )

    theta_init = np.random.randn(xTrain_ext.shape[ 1 ])

    theta = bgd_resolver.batch_gradient_descent(costFn, gradientFn, theta_init, xTrain_ext, yTrain, learning_rate= 0.005 , tolerance= 1e-12 )

    print( "BGD theta1=" , theta[ 1 ])

    print( "BGD theta0=" , theta[ 0 ])

    def initPlot () :

    plt.figure()

    plt.title( '2020.05 WEATHER' )

    plt.xlabel( 'date' )

    plt.ylabel( 'maximum temperature' )

    plt.grid( True )

    return plt

    plt = initPlot()

    plt.plot(xTrain, yTrain,  'k.' )

    plt.plot(xTrain, xTrain_ext.dot(theta),  'g-' )

    plt.show()

    模型十:基于SGDRegressor随机梯度下降算法的实现

    sklearn.linear_model.SGDRegressor对象提供了使用随机梯度下降算法进行线性回归的实现。

    • SGDRegressor对于数据集较大的情形比较合适,如果样本较少(例如本例),其效果一般不好;

    • 可以观察到,每次运行时,其优化结果并不相同。

    ''' 使用SGDRegressor随机梯度下降算法优化线性回归权重参数 '''

    %matplotlib inline

    import numpy  as np

    import matplotlib.pyplot  as plt

    from sklearn.linear_model  import SGDRegressor

    xTrain = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])[:, np.newaxis]   # 训练数据(日期)

    yTrain = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])      # 训练数据(最高气温)

    regressor = SGDRegressor(loss= 'squared_loss' , max_iter= 2000 ) 

    regressor.fit(xTrain, yTrain)

    # 每次运行,得到的结果并不相同

    theta0 = regressor.intercept_[ 0 ]

    theta1 = regressor.coef_[ 0 ]

    print( "SGD theta1=" , theta1)

    print( "SGD theta0=" , theta0)

    def initPlot () :

    plt.figure()

    plt.title( '2020.05 DaTong WEAThER' )

    plt.xlabel( 'Date' )

    plt.ylabel( 'maximum temperature' )       

    plt.grid( True )

    return plt

    plt = initPlot()

    plt.plot(xTrain, yTrain,  'k.' )

    plt.plot(xTrain, theta0 + theta1 * xTrain,  'g-' )               

    plt.show()

    6、对数几率回归

    查看数据图像

    其中最高气温影响因素日期用 + 表示,最低气温用· 表示。

    import numpy  as np

    import matplotlib.pyplot  as plt

    # 解决中文问题

    plt.rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]

    def initPlot () :

    plt.figure()

    plt.title( '2020年5月上旬大同天气' )

    plt.xlabel( '日期' )

    plt.ylabel( '最低温度' )

    return plt

    plt = initPlot()

    factor1 = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])     # 从trainData中获取下标索引第2列(passed)值为1的所有行的第0列元素

    factor2 = np.array([ 8 , 9 , 4 , 4 , 6 , 10 , 10 , 7 , 3 ])

    plt.plot(factor1, 'r+' )

    plt.plot(factor2, 'ko' )

    plt.show()

     模型十一:使用LogisticRegression进行逻辑回归模型

    • 设置逻辑回归算法的某些属性:model = LogisticRegression(solver='lbfgs'),使用lbfgs算法来执行回归计算。默认使用liblinear。注意,这两种算法的结果并不相同

    • 执行计算:model.fit(X, y)

    • 执行预测:model.predict(newX),返回值是newX矩阵中每行数据所对应的结果。如果是1,则表示passed;如果是0,则表示unpassed

    • 获得模型参数值:theta0 = model.intercept_[0] theta1 =model.coef_[0,0] theta2 = model.coef_[0,1]

    • 决策边界线

    决策边界线可视为两种类别数据点的分界线。在该分界线的一侧,所有数据点都被归为passed类(1),另一侧的所有数据点都被归为unpassed类(0);

    对于本例来说,决策边界线是一条直线(在案例2中进行了说明)。

    ''' 使用LogisticRegression进行逻辑回归 '''

    import numpy  as np

    import matplotlib.pyplot  as plt

    from sklearn.linear_model  import LogisticRegression

    # 解决中文问题

    plt.rcParams[ 'font.sans-serif' ] = [ 'SimHei' ]

    xTrain = np.array([[ 1 , 8 ],[ 2 , 9 ],[ 3 , 4 ],[ 4 , 6 ],[ 5 , 10 ],[ 6 , 10 ],[ 7 , 10 ],[ 8 , 7 ],[ 9 , 3]])         

    yTrain = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])

    # print(xTrain)

    model = LogisticRegression(solver= 'lbfgs' )    # 使用lbfgs算法。默认是liblinear算法

    model.fit(xTrain, yTrain)

    newFactors = np.array([[ 2 ,  9 ],[ 5 ,  10 ],[ 9 ,  3 ],[ 10 ,  5 ]])

    print( "预测结果:" )

    print(model.predict(newFactors))

    # 获取theta计算结果

    theta = np.array([model.intercept_[ 0 ], model.coef_[ 0 , 0 ], model.coef_[ 0 , 1 ]])

    def initPlot () :

    plt.figure()

    plt.title( '2020年5月上旬大同天气' )

    plt.xlabel( '日期' )

    plt.ylabel( '最低温度' )

    return plt

    plt = initPlot()

    factor1 = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])     # 影响因素1:日期

    factor2 = np.array([ 8 , 9 , 4 , 4 , 6 , 10 , 10 , 7 , 3 ])   # 影响因素2:最低气温

    plt.plot(factor1, 'r+' )

    plt.plot(factor2, 'ko' )

    boundaryX = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ])                  # 绘制决策边界线(每天日期)

    boundaryY = -(theta[ 1 ] * boundaryX + theta[ 0 ]) / theta[ 2 ]    # 根据决策边界线的直线公式和x值,计算对应的y值

    plt.plot(boundaryX, boundaryY,  'b-' )

    plt.show()

    模型十二:基于成本函数和梯度下降算法进行逻辑回归模型

    ''' 使用梯度下降算法进行逻辑回归 '''

    import numpy  as np

    import matplotlib.pyplot  as plt

    import bgd_resolver

    def normalizeData (X, column_mean, column_std) :

    return (X - column_mean) / column_std

    def sigmoid (z) :

    return 1. / ( 1 + np.exp(-z))

    def costFn (theta, X, y) :

    temp = sigmoid(X.dot(theta))

    cost = -y.dot(np.log(temp)) - ( 1 - y).dot(np.log( 1 - temp))

    return cost / len(X)

    def gradientFn (theta, X, y) :

    return xTrain.T.dot(sigmoid(xTrain.dot(theta)) - yTrain) / len(X)

    def initPlot () :

    plt.figure()

    plt.title( '2020.5 DaTong Weather' )

    plt.xlabel( 'Date' )

    plt.ylabel( 'Temp' )

    return plt

    xTrain = np.array([[ 1 , 8 ],[ 2 , 9 ],[ 3 , 4 ],[ 4 , 6 ],[ 5 , 10 ],[ 6 , 10 ],[ 7 , 10 ],[ 8 , 7 ],[ 9 , 3 ]])

    # 计算训练数据每列平均值和每列的标准差

    xTrain_column_mean = xTrain.mean(axis= 0 )

    xTrain_column_std = xTrain.std(axis= 0 )

    xTrain = normalizeData(xTrain, xTrain_column_mean, xTrain_column_std)       # 如果不进行归一化处理,计算过程中可能产生溢出(但似乎仍可以收敛)

    x0 = np.ones(len(xTrain))

    xTrain = np.c_[x0, xTrain]           # 需手动追加Intercept Item列

    yTrain = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])

    np.random.seed( 0 )

    init_theta = np.random.random( 3 )     # 随机初始化theta

    theta = bgd_resolver.batch_gradient_descent(costFn, gradientFn, init_theta, xTrain, yTrain,  0.005 ,  0.00001 )

    # 预测若干数据,也需要先归一化,使用之前训练数据的mean和std

    newFactors = np.array([[ 2 ,  9 ],[ 5 ,  10 ],[ 9 ,  3 ],[ 10 ,  5 ]])

    newFactors = normalizeData(newScores, xTrain_column_mean, xTrain_column_std)

    x0 = np.ones(len(newFactors))

    newFactors = np.c_[x0, newFactors]  

    print( "预测结果:" )

    print(sigmoid(newFactors.dot(theta)))

    plt = initPlot()

    factor1 = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])     # 影响因素1:日期

    factor2 = np.array([ 8 , 9 , 4 , 4 , 6 , 10 , 10 , 7 , 3 ])   # 影响因素2:最低气温

    plt.plot(factor1, 'r+' )

    plt.plot(factor2, 'ko' )

    # 绘制决策边界线

    boundaryX = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ])

    # 因为之前进行了归一化,因此边界线上点的x坐标也需要先归一化。x坐标对应的列索引是0

    normalizedBoundaryX = (boundaryX - xTrain_column_mean[ 0 ]) / xTrain_column_std[ 0 ]

    # 下面计算出来的边界线上的y坐标normalizedBoundaryY是经过归一化处理的坐标

    normalizedBoundaryY = (theta[ 0 ] * normalizedBoundaryX + theta[ 1 ] ) / theta[ 1 ]

    # boundaryY才是将归一化坐标还原成正常坐标。y坐标对应的列索引是1

    boundaryY = xTrain_column_std[ 1 ] * normalizedBoundaryY + xTrain_column_mean[ 1 ]

    plt.plot(boundaryX, boundaryY,  'b-' )

    plt.show()

    模型十三:基于scipy.optimize优化运算库实现对数几率回归模型

    • 使用minimize库函数;

    • 需要提供jac参数,并将其设置为梯度计算函数;

    • scipy.optimize库中提供的算法会比我们自己实现的算法更高效、灵活、全面;

    • 本例中没有对数据进行归一处理,因此导致minimize方法执行过程中溢出(尽管可能也能收敛)。请自行添加归一化处理功能。

    ''' 使用minimize来优化逻辑回归求解 '''

    import numpy  as np

    import matplotlib.pyplot  as plt

    import scipy.optimize  as opt

    # 定义全局变量

    xTrain = np.array([[ 1 , 8 ],[ 2 , 9 ],[ 3 , 4 ],[ 4 , 6 ],[ 5 , 10 ],[ 6 , 10 ],[ 7 , 10 ],[ 8 , 7 ],[ 9 , 3 ]])

    x0 = np.ones(len(xTrain))

    xTrain = np.c_[x0, xTrain]

    yTrain = np.array([ 33 , 35 , 28 , 20 , 26 , 27 , 23 , 22 , 22 ])

    def sigmoid (z) :

    return 1. / ( 1 + np.exp(-z))

    # Cost Function以theta为参数

    def costFn (theta, X, y) :

    temp = sigmoid(xTrain.dot(theta))

    cost = -yTrain.dot(np.log(temp)) - ( 1 - yTrain).dot(np.log( 1 - temp))

    return cost / len(X)

    # Gradient Function以theta为参数

    def gradientFn (theta, X, y) :

    return xTrain.T.dot(sigmoid(xTrain.dot(theta)) - yTrain) / len(X)

    np.random.seed( 0 )

    # 随机初始化theta,计算过程中可能产生溢出。

    # 可以尝试将init_theta乘以0.01,这样可以防止计算溢出

    init_theta = np.random.random(xTrain.shape[ 1 ])

    result = opt.minimize(costFn, init_theta, args=(xTrain, yTrain), method= 'BFGS' , jac=gradientFn, options={ 'disp' :  True })

    theta = result.x             # 最小化Cost时的theta

    def initPlot () :

    plt.figure()

    plt.title( '2020.5 DaTong Weather' )

    plt.xlabel( 'Date' )

    plt.ylabel( 'Temp' )

    return plt

    plt = initPlot()

    factor1 = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ])     # 影响因素1:日期

    factor2 = np.array([ 8 , 9 , 4 , 4 , 6 , 10 , 10 , 7 , 3 ])   # 影响因素2:最低气温

    plt.plot(factor1, 'r+' )

    plt.plot(factor2, 'ko' )

    boundaryX = np.array([ 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ])                      # 绘制决策边界线

    boundaryY = (theta[ 1 ] * boundaryX + theta[ 0 ]) / theta[ 2 ]

    plt.plot(boundaryX,boundaryY,  'b-' )

    plt.show()

    综上可以观察到,所有数据点并不明显分成两个类别。

    线性回归主要都是针对训练数据和计算结果均为数值的情形。而在本例中,结果不是数值而是某种分类:这里分成日期和最低气温两类。而且发现,两类并不显示有明显的分界线。这进一步说明最高气温的影响因素不是日期和最低气温。

     

    总结

     我们通过数据爬取并用十三种预测模型最终得出结论:最高气温的影响因素与日期和最低气温毫无关联(由上可知会出现很荒谬的、与理论不符的结论,进而判断);而这一结论与我们常识正好相符合,也就说明在此方面,实验成功!

    展开全文
  • 还记得我写的这篇文档吗? 《PostgreSQL 大表自动 freeze 优化思路》 https://yq.aliyun.com/articles/50411文章主要针对如何优化大表的freeze调度来减少IO风暴的问题,请注意... 本文要给大家讲的是预测风暴,掌握...

    还记得我写的这篇文档吗? 《PostgreSQL 大表自动 freeze 优化思路》
    https://yq.aliyun.com/articles/50411
    文章主要针对如何优化大表的freeze调度来减少IO风暴的问题,请注意只是减少,不是避免。

    作为一名有追求的PGer,要时刻保持警惕,生于忧患、死于安乐;
    本文要给大家讲的是预测风暴,掌握了预测能力,才能未雨绸缪,淡定的面对暴风雨。
    _

    预测 IO 风暴

    如何预测此类(prevent wrapped vacuum freeze) IO 风暴的来临呢?
    首先需要测量几个维度的值。
    .1. 表的大小以及距离它需要被强制vacuum freeze prevent wrap的年龄

    .2. 每隔一段时间的XID值的采样(例如每分钟一次),采样越多越好,因为需要用于预测下一个时间窗口的XID。(其实就是每分钟消耗多少个事务号的数据)

    .3. 通过第二步得到的结果,预测下一个时间窗口的每分钟的pXID(可以使用线性回归来进行预测)
    预测方法这里不在细说,也可以参考我以前写的一些预测类的文章。

    预测的结论包括 未来一段时间的总Freeze IO量,以及分时的Freeze IO量。
    预测结果范例
    Freeze IO 时段总量
    screenshot
    Freeze IO 分时走势
    _

    详细的预测过程

    .1.
    每隔一段时间的XID值的采样(例如每分钟一次),采样越多越好,因为需要用于预测下一个时间窗口的XID。(其实就是每分钟消耗多少个事务号的数据)

    vi xids.sh
    #!/bin/bash
    export PATH=/home/digoal/pgsql9.5/bin:$PATH
    export PGHOST=127.0.0.1
    export PGPORT=1921
    export PGDATABASE=postgres
    export PGUSER=postgres
    export PGPASSWORD=postgres
    
    psql -c "create table xids(crt_time timestamp, xids int8)"
    for ((i=1;i>0;))
    do
    # 保留1个月的数据
    psql -c "with a as (select ctid from xids order by crt_time desc limit 100 offset 43200) delete from xids where ctid in (select ctid from a);"
    psql -c "insert into xids values (now(), txid_current());"
    sleep 60
    done
    
    chmod 500 xids.sh
    
    nohup ./xids.sh >/dev/null 2>&1 &

    采集1天的数据可能是这样的

    postgres=# select * from xids ;
              crt_time          | xids 
    ----------------------------+------
     2016-06-12 12:36:13.201315 | 2020
     2016-06-12 12:37:13.216002 | 9021
     2016-06-12 12:38:13.240739 | 21022
     2016-06-12 12:39:13.259203 | 32023
     2016-06-12 12:40:13.300604 | 42024
     2016-06-12 12:41:13.325874 | 52025
     2016-06-12 12:42:13.361152 | 62026
     2016-06-12 12:43:15.481609 | 72027
    ...

    .2.
    表的大小以及距离它需要被强制vacuum freeze prevent wrap的年龄

     (因为freeze是全集群的,所以需要把所有库得到的数据汇总到一起)     
    vi pred_io.sh
    
    #!/bin/bash
    export PATH=/home/digoal/pgsql9.5/bin:$PATH
    export PGHOST=127.0.0.1
    export PGPORT=1921
    export PGDATABASE=postgres
    export PGUSER=postgres
    export PGPASSWORD=postgres
    
    psql -c "drop table pred_io; create table pred_io(crt_time timestamp, bytes int8, left_live int8);"
    for db in `psql -A -t -q -c "select datname from pg_database where datname <> 'template0'"`
    do
    psql -d $db -c " copy (
    select now(), bytes, case when max_age>age then max_age-age else 0 end as xids from 
    (select block_size*relpages bytes, 
    case when d_max_age is not null and d_max_age<max_age then d_max_age else max_age end as max_age,
    age from
    (select 
    (select setting from pg_settings where name='block_size')::int8 as block_size, 
    (select setting from pg_settings where name='autovacuum_freeze_max_age')::int8 as max_age, 
    relpages, 
    substring(reloptions::text,'autovacuum_freeze_max_age=(\d+)')::int8 as d_max_age,
    age(relfrozenxid) age
    from pg_class where relkind in ('r', 't')) t) t
    ) to stdout;" | psql -d $PGDATABASE -c "copy pred_io from stdin"
    done
    
    . ./pred_io.sh

    得到的数据可能是这样的

    postgres=# select * from pred_io limit 10;
              crt_time          | bytes  | left_live 
    ----------------------------+--------+-----------
     2016-06-12 13:24:08.666995 | 131072 | 199999672
     2016-06-12 13:24:08.666995 |  65536 | 199999672
     2016-06-12 13:24:08.666995 |      0 | 199999672
     2016-06-12 13:24:08.666995 |      0 | 199999672
     2016-06-12 13:24:08.666995 |      0 | 199999672
     2016-06-12 13:24:08.666995 |      0 | 199999672
    ...

    .3.
    预测XIDs走势(略),本文直接取昨天的同一时间点开始后的数据。

    create view v_pred_xids as 
    with b as (select min(crt_time) tbase from pred_io), 
           a as (select crt_time + interval '1 day' as crt_time, xids from xids,b where crt_time >= b.tbase - interval '1 day')  
    select crt_time, xids - (select min(xids) from a) as xids from a ;     

    数据可能是这样的,预测未来分时的相对XIDs消耗量

              crt_time          | xids 
    ----------------------------+------
     2016-06-13 12:36:13.201315 |    0
     2016-06-13 12:37:13.216002 |    100
     2016-06-13 12:38:13.240739 |    200
     2016-06-13 12:39:13.259203 |    300
     2016-06-13 12:40:13.300604 |    400

    .4.
    结合pred_io与v_pred_xids 进行 io风暴预测
    基准视图,后面的数据通过这个基准视图得到

    create view pred_tbased_io as
    with a as (select crt_time, xids as s_xids, lead(xids) over(order by crt_time) as e_xids from v_pred_xids)
    select a.crt_time, sum(b.bytes) bytes from a, pred_io b where b.left_live >=a.s_xids and b.left_live < a.e_xids group by a.crt_time order by a.crt_time;

    未来一天的总freeze io bytes预测

    postgres=# select min(crt_time),max(crt_time),sum(bytes) from pred_tbased_io ;
                min             |            max             |   sum    
    ----------------------------+----------------------------+----------
     2016-06-13 12:36:13.201315 | 2016-06-14 12:35:26.104025 | 19685376
    (1 row)

    未来一天的freeze io bytes分时走势
    得到的结果可能是这样的

    postgres=# select * from pred_tbased_io ;
              crt_time          |  bytes   
    ----------------------------+----------
     2016-06-13 12:36:13.201315 |    65536
     2016-06-13 12:37:13.216002 |   581632
     2016-06-13 12:38:13.240739 |        0
     2016-06-13 12:39:13.259203 |        0
     2016-06-13 12:40:13.300604 |        0
     2016-06-13 12:41:13.325874 |        0
     2016-06-13 12:43:15.481609 |   106496
     2016-06-13 12:43:24.133055 |     8192
     2016-06-13 12:45:24.193318 |        0
     2016-06-13 12:46:24.225559 |    16384
     2016-06-13 12:48:24.296223 | 13434880
     2016-06-13 12:49:24.325652 |    24576
     2016-06-13 12:50:24.367232 |   401408
     2016-06-13 12:51:24.426199 |        0
     2016-06-13 12:52:24.457375 |   393216
    ......

    小结

    主要用到什么?
    .1. 线性回归
    .2. with语法
    .3. 窗口函数
    .4. xid分时消耗统计
    .5. 强制prevent wrap freeze vacuum的剩余XIDs统计

    展开全文
  • 在现代工业中,对准确,简单的预测工具和技术的需求显而易见。 介绍 (Introduction) What is a time series? A series of numbers representing some quantity that changes with time. For example — The revenue...
  • 导语:Google 正在积极研究如何改进全球天气预报模型。   准确预测未来几分钟到几周的天气是一项基本的科学挑战。很多气象机构目前采用的预报是基于大气的物理模型,但这些模型本身受到计算要求的限制且对物理...
  • 科学家们长期以来一直在研究如何准确预测天气,而云层及其大气加热和湿润是一个挑战。这可能会阻止建立准确的气候模型,但正确预测天气变化,以及温室气体浓度对政策制定者至关重要。 论文的第一作者,地球研究所和...
  • 使用机器学习预测天气(第二部分)

    万次阅读 2018-01-03 11:24:10
    概述  这篇文章我们接着前一篇文章...这篇文章我们将使用上一篇文章处理好的数据,建立线性回归模型来预测天气。为了建立线性回归模型,我要用到python里非常重要的两个机器学习相关的库:Scikit-Learn和StatsModels
  • REF 虽然只有一个小时,不过还是很神奇,不知道精确度如何
  • Problem Description "Man, this year has the worst weather ever!", David said as he sat crouched in the small cave where we had sought shelter from yet another sudden rainstorm. ...
  • 在第一篇文章中,我们探讨了如何连接一个树莓派给IBM Bluemix,IBM沃森和Node-RED和第二,我们给我们的树莓派与IBM沃森的文本到语音声音 。 如果你没有看过那些只是还没有,我建议你阅读它们,然后再返回这里! 在...
  • 多城市天气预测 开发人员经常要负责从另一个应用程序的API检索数据并在自己的上下文中使用它们。 第三方API允许开发人员通过向URL发出带有特定参数的请求来访问其数据和功能。 您面临的挑战是构建一个将在浏览器中...
  • 现在要做的就是,确定forecaster如何采纳experts的意见来做预测。首先,我们规定一些notations,同时描述整个过程。 我们标记Experti在时刻t做得预测做fi,t∈{0,1}; Forecaster根据Experts的意见,按照某种方式...
  • raspberry pi 在构建具有令人难以置信的潜力的设备时,IBM Bluemix和... 在第一篇文章中,我们探讨了如何将Raspberry Pi与IBM Bluemix,IBM Watson和Node-RED连接起来 ;在第二篇文章中,我们为Raspberry Pi提供了I...
  • 气候变化万千,我们的行动也会因天气不同而改变,那么在不清楚天气状况的情况下,如何预测未来几天我们的行动呢? 本文选自《大数据时代的算法:机器学习、人工智能及其典型实例》。 高温天气与行为概率 夏季是...
  • 导语:Google 正在积极研究如何改进全球天气预报模型。 准确预测未来几分钟到几周的天气是一项基本的科学挑战,它可以对社会的许多方面产生广泛影响。 很多气象机构目前采用的预报是基于大气的物理模型。尽管在...
  • 这项研究的目的是预测各种天气情况如何导致事故,这将使保险公司,运输当局以及市民受益。 在这个项目中,我们将预测事故是否会发生? ,使用各种参数,例如车辆的速度,降水强度,风向,相对于天气的道路状况,...
  • Huybers的论文“从太平洋海表温度对美国东部炎热的天气的长距离预测”相关联 有关代码的查询,请通过mckinnon AT ucar DOT edu与Karen McKinnon联系。 大多数代码是.m文件,要在Matlab中运行。有两个.ncl文件,它们...
  • 如何预测 一个可帮助Powershop用户根据当地天气预测和控制其用电量的Web应用程序。 如何设置 要求: node.js npm 运行npm install 运行node app.js
  • 作者 | 荣仔!最靓的仔!责编 | 王晓曼出品 | CSDN博客天气数据集爬取爬取思路:确定目标(目标网站:大同历史天气预报 2020年5月份)请求网页(第三方库 requests)解...
  • FlightCaster 的预报是基于交通统计局的数据、联邦航空局航空交通管制系统指令中心的警报、FlightStats(一个发布航班运营状况信息的网站)的数据、美国气象局的天气预报等所发布的。这些数据都是公开数据,有需要的...
  • 专家能否在预测方面做得更好,甚至试图避免更多自然灾害或更有效地减少资源损失? 答案是肯定和否定。有时我们知道龙卷风会袭来,我们无法防止这种情况造成的损失。我们知道洪水会因飓风而发生,当地人可以努力有效...
  • 预测天气是一个非常非常困难的主题,因为影 响天气的因素太多,而Kaggle的这份数据也不负众望,是一份非常难也非常难得的数据集,难到用一般的机器学习算法(如SVM,LR)在这个数据集上都不会有太好的结果。...
  • 当我输入邮编,并不起作用,只会显示,我在this.state.zipcode设置的27403城市的天气, 另外如何用formap或者foreach 拿到数组 ``` import React from 'react'; import './App.css'; const apiKey = '53df5b52...
  • 数据到底如何搞定电影票房预测

    千次阅读 2014-11-13 10:39:15
    转载自: 摘要: 基于对搜索行为、社交媒体等数据的深入分析,可以测量亿万用户的...Google如何通过搜索行为预报流感爆发?这些有趣的问题背后,其实都隐藏着大数据的影子。基于对搜索行为、社交媒体等数据的深入
  • 我主要是是想做数据预测,比如天气状况(pm2.5等等),单用前面的样本(24小时pm2.5等影响数据)很难一个模型完整预测未来的24小时pm2.5数据(只有前几个小时比较准确)。我采用的方式是将原来的24小时数据扩大为48小时...
  • 当然是天气预报。 你期待什么? georgia.forecast是一种工具,用于收集和绘制国家气象局对 2021 年 1 月 5 日星期二的预报,该日乔治亚州计划为其美国参议院席位举行两次决选。 如何使用 只需启动并浏览实时数据。...

空空如也

空空如也

1 2 3 4 5 ... 11
收藏数 217
精华内容 86
关键字:

如何预测天气