Categories
アナリティクス

Googleタグマネージャーを使う場合のコンテンツセキュリティポリシーの設定

Googleタグマネージャーは今では一般的なツールとなっていますが、 ブラウザなどによるセキュリティ関連の新しい仕様によって、あるときから急にタグマネージャーが使えないといったことが起きたりします。

コンテンツセキュリティポリシー(CSP)とは

そのうちの1つでよくあるのがコンテンツセキュリティポリシー(Content Security Policy:CSP)です。ざっくり説明すると、 Webサイト・ページはクロスサイトスクリプティング(XSS)などに対する脆弱性があるのですが、ファイルやスクリプトなどのリソースを拒否・受け入れする仕様です。

つまり、ページで「特定のサイトからのスクリプト(ファイル)しか使わないので、ほかはすべて拒否します」といった宣言をし、ブラウザはそれをもとにスクリプトの取捨選択をするといった感じです。

GoogleタグマネージャーやGoogleアナリティクスも例外ではなく、ここで宣言をしておかないと使えなくなり、Chromeなどのブラウザのコンソールには下記のようなエラーが表示されます。

コンテンツセキュリティポリシーの設定と種類

コンテンツセキュリティポリシーの設定

CSPの設定方法は主に HTTPレスポンスヘッダと<meta>タグの2種類あります。(他にもありますが割愛します)

  • HTTPヘッダー:Content-Security-Policy: default-src ‘self’
  • metaタグ:<meta http-equiv=”Content-Security-Policy” content=”default-src ‘self'”>

上記の default-src ‘self’ の部分をディレクティブと呼び、複数のディレクティブを設定する場合は;でつなげます。

ちなみに、上記の設定は「すべてのコンテンツを自身のドメイン(サブドメインは除く)から取得する」ということを表しています。

コンテンツセキュリティポリシーの制御対象

CSPでは制御対象のリソースを指定できます。主なものは以下になります。

  • script-src:Javascriptの読み込み
  • style-src:CSSの読み込み
  • frame-src:<iframe>による読み込み
  • default-src :設定がない場合に適用

Googleタグマネージャーへの影響

このようにCSPでリソースの取得の制限をしているので、このWebサイトから見たら外部に当たるGoogleタグマネージャーやGoogleアナリティクスも対象になってしまいます。

下記の例では、すべてのコンテンツを自身のドメイン (サブドメインを除く)からのみ許可しているため、 GoogleタグマネージャーやGoogleアナリティクスのスニペット(スクリプト)は無効になります。

<meta http-equiv="Content-Security-Policy" content="default-src 'self'">

Googleタグマネージャーが使えるようにするためのCSPの設定

基本設定

Googleタグマネージャーを使えるようにするには、まず最初にCSPのscript-src に ‘unsafe-inline’ を追加します。

script-src: 'unsafe-inline' https://www.googletagmanager.com
img-src: https://www.googletagmanager.com

非セキュアな場合はimg-srcディレクティブのGoogleタグマネージャーをhttpにします。

script-src: 'unsafe-inline' https://www.googletagmanager.com
img-src: http://www.googletagmanager.com

カスタム JavaScript変数

カスタムJavaScript変数を使用している場合はscript-src: ‘unsafe-eval’も追加する必要があります。

script-src: 'unsafe-eval'

プレビュー モード

Googleタグマネージャーのプレビューモードを使う場合は、さらにCSPに下記のディレクティブを追加します。

script-src: https://tagmanager.google.com
style-src: https://tagmanager.google.com https://fonts.googleapis.com
img-src: https://ssl.gstatic.com https://www.gstatic.com
font-src: https://fonts.gstatic.com data:

非セキュアな場合はscript-src: https://tagmanager.google.comのプロトコルをhttpに変更してください。

Googleアナリティクスを使えるようにするためのCSPの設定

Googleアナリティクスを使用する場合はgoogle-analytics.comもCSPの設定に加えなければなりません。

script-src: https://www.google-analytics.com https://ssl.google-analytics.com
img-src: https://www.google-analytics.com
connect-src: https://www.google-analytics.com

非セキュアな場合はscript-src ディレクティブで https://ssl.google-analytics.comを削除して構いません。

Web開発者との情報共有が大切

Gerd AltmannによるPixabayからの画像

このCSPの設定は通常はWeb開発者が行っていますが、彼らはタグマネージャーやアナリティクスについてはあまり気にしていません。そのため、CSPの設定を追加しても連絡が来ないことはよくあります。

その一方で、Web分析者やタグマネージャーの設定者もCSPなんてふだんは気にしないですし、内容もわかりません。コンソールにエラーが出ても通常は無視するでしょう。

アナリティクスにイベントやページビューが出てこないことはすぐに気づきますが、その原因を探すのは難しいです。

ですので、問題を防ぐにはふだんからWeb開発者との情報共有が大切です。コミュニケーションを取っておくことで、Web開発者から「今度CSPの設定を入れることになりました。CSPとは・・・・」といったことを教えてもらうことで、「タグマネージャーやアナリティクスに影響がでるかもしれない」と気づくことができます。

]]>
Categories
ビザ 英語

ニュージーランドでワーホリ成功例その1

これまで、ワーキングホリデービザを使って ニュージーランドに来たけどうまく行かなかった例を紹介してきました。

今回は逆に成功(とは行かないまでもよく考えて行動した)例を紹介します。

学生ビザ&友達で現地を視察

Dさんは、日本で社会人経験がある20代なかばの女性です。親友(Eさん)がニュージーランドで働くということになったので、思い切って本人も仕事を辞めてニュージーランドへ来ることにしました。

多くの人がこの時点でワーキングホリデービザを取得してしまうのですが、彼女の良いところは最初に学生ビザでニュージーランドへ入国したところです。

学生ビザでも働ける

知ってて当然と思うかもしれませんが、学生ビザでも一定の条件を満たしていればアルバイトは可能です。語学学校へ通わないといけないのでその分の学費かかってしまいますが、ニュージーランドでは学費程度の金額はアルバイトで稼げます。

Dさんは学校に通い始めて2~3週間後に学校の近くのレストランで仕事を見つけてすぐに働き始めました。学校のすぐ近くなので、移動時間や交通費も気にする必要はありませんでした。(ニュージーランドではバイト、正社員に関係なく交通費は基本出ません)

ビザの期限の心配せずに現地を視察

ワーキングホリデービザで来てしまうと、現地を理解したり、職探しの間にビザの期間がどんどん短くなってしまいます。しかも、もしもその都市が気に入らなかったり職が見つからなかった場合、また別の都市へ行って同じことを繰り返さなければなりません。

学生ビザでも現地を理解することは可能ですし、語学学校の同級生などで他の街へ旅行したことがある人も結構います。学校によっては永住権保有者の語学サポートを受け入れているので(彼らの学費はほぼ無料)、現地のリアルな情報も入ってきます。

私も語学学校に通っていた頃に、 クイーンズタウンの語学学校に通う中国人留学生が短期間だけオークランドの私のクラスに来ていた事がありました。そこで彼からクイーンズタウンの情報を教えてもらいました。

また、別の同級生は永住権を持っており、仕事もしていないのである意味暇つぶしに学校に来ていました。なので毎週末は家族で旅行したり、レストラン巡りをしていたので、情報収集ができました。

学校卒業後に放浪し、1年後にワーホリでニュージーランドへ

Dさんは語学学校に約半年間通い、その後ニュージーランドだけでなくオーストラリアなど数カ国を旅行して帰国しました。

帰国する前にワーホリの話は聞いてなかったので、「日本で仕事を辞めて次を決める前に海外へ行きたかった」程度なのかと勝手に想像していたのですが、それから約1年後に、Dさんの親友のEさんから「Dさんは今○○(オークランドのジャパレス)で働いてますよ」と連絡がありました。

そのお店は我が家から来るまで10分くらいの日本食レストランで、以前にも行ったことがあったのですが、全く気づきませんでした。

それからちょっとして、そのお店に行くとDさんが厨房で働いていました。

選択肢の多さと自分の判断の重要性

Gerd AltmannによるPixabayからの画像

これを読んで「結局ジャパレスかよ!」って思うかもしれませんが、前回紹介したジャパレス勤務のC君とは違い、Dさんの場合はオークランドだけでなくいくつかの街を実際に旅行して比較検討した結果オークランドを選んでいます。

選択肢が1つしかないところから選ぶのと、複数ある中から選ぶのでは大違いです。検討したときに「なぜここにしたのか?」という理由が明確だと、そこで自分がやりたいことや目標がはっきりするので、結果も変わってくるでしょう。

Dさんはまだワーホリ期間中なので今後どうなるかはまだわかりませんが、ワーホリをするまでの道のりとしてはとても良い方法だったと思います。

]]>
Categories
ビザ 英語

ニュージーランドでワーホリ失敗例(ジャパレス勤務)

前回前々回でワーキングホリデービザでニュージーランドに来た人の失敗例を紹介しました。第3回目の今回は、前回と比べるとマシですが、もっともよくあるパターンなので紹介したいと思います。

日本にいる間に就活。入国後すぐ仕事

C君(20代男性)は日本で調理師の経験があり、その経験を生かしてワーホリでニュージーランドへ来る前にインターネットで就活をしており、すでに勤務先が決まった状態でニュージーランドへ来ました。就活時間でビザの期間を使わずに済んだのはとても大きいと思います。

勤務先はオークランドでも結構有名な庶民的な日本食レストランで、現地の人たちも好んで訪れるので、週末になると1時間待ちになることもあるくらい人気のお店です。

ニュージーランドに慣れるまでは、職探しで無駄に時間を浪費するより 、日本人経営者のレストラン(通称ジャパレス)で働くのは、個人的にはありだと思います。

ですが、期間を決めておくべきですね。

英語が不要な環境で生活

人気のお店なので週休1日(ワーホリの後半は週休2日に増えてました)でした。しかも飲食業には定番の休みは平日ということもあり、最初の数カ月間は休日はほとんど部屋にこもっていました。

同僚たちとは仲良くやっていたようで、仕事終わりに一緒に飲んだり、休日に遊びに行ったりしていましたが、同僚はほとんど日本人なので英語を話す機会もなければ勉強する必要もありませんでした。

英語のテキストは自室においてありましたがほとんど勉強してなかったようです。

そうなるとなんのためにワーホリへ来たのか?ということになります。これは彼に限らずワーホリで来る日本人の大半に共通する問題点です。後で述べますが、これが彼のその後にも影響します。

ワークビザを取らずに帰国

約8ヶ月ほど同じお店で働き続けたC君に、ビザについて話した事がありました。彼の職種や給料、過去の仕事経験が十分で勤務先のサポートもありそうなので、ワークビザ(しかも英語力の証明が不要なWork To Residenceビザ)が取れそうということがわかりました。

ですが、それから1ヶ月後、彼は仕事を辞めて日本へ帰国することを選びました。理由は、

  1. ニュージーランドは飽きた
  2. 日本で自分がやりたい仕事がしたい

ということでした。1つ目については以前のブログ(ニュージーランドでワーホリ失敗例(すぐ帰国した現役大学生))でも書きましたが、20代にとってニュージーランドは刺激が足りないので飽きてしまうという話はよく聞きます。ですが、「ニュージーランドに飽きた 」と言えるほど体験したのかが疑問でした。

2つ目のしごとについても、彼がやりたい仕事はニュージーランドにもあるのですが、あまり調べていませんでした。

手段が目的

C君が、ニュージーランドで仕事をして「ニュージーランドが自分に合わない」という結論に達した事自体は構わないのですが、ジャパレスで日本人に囲まれて働くだけで、もっと色々経験して判断できたはずが、結局ワーホリと言う名のバイト生活でしかありませんでした。

日本人によくあるのですが、「ワーホリでニュージーランドへ来る」という手段が目的になってしまって、本当の目的がないまま来ている人が多く見受けられます。

ワーキングホリデービザだけでなく、20代の若い1年間という時間自体が本当にもったいないので、「ニュージーランドで1年間過ごしてどうなりたいか?」というゴールを決めておくことをおすすめします。

]]>
Categories
ビザ 英語

ニュージーランドでワーホリ失敗例(語学学校半年通学)

前回は、語学学校を卒業してからわずか1ヶ月で帰国してしまったワーホリを紹介しました。ワーホリ失敗例を書く理由も前回の記事に書いていますのでそちらを読んでもらえると嬉しいです。

今回のワーホリ失敗談は、ワーホリで来たのに語学学校に半年間も通ったBさんです。

大学卒業後すぐにワーホリ

Bさんは日本の4年制大学を卒業した直後(4月上旬)にオークランドへやってきました。卒業直後に来るということは、就活に失敗した可能性が高いのですが、卒業してしまうと「新卒採用」枠には応募できないので、卒業してしまったのがまず失敗でした。

目的・ゴール・ワーホリ後のキャリアパスが未定

彼女はそもそもワーホリに来た目的が、英語を学ぶこと以外はあまり決まっていませんでした。「それなら語学留学でいいんじゃない?」と思ってしまいましたが、来てしまったのであえてそれは言いませんでした。

また、ワーホリ後に帰国したあとにどうしたいのか?どうなりたいのか?といったキャリアパスも全く考えていませんでした。22~3の子に「キャリアパスを考えろ」というのは少々ハードルが高いかもしれませんが、せっかくのワーホリを使うのだから、そこまで考えてから来るべきだと思いました。

英語力が足りなくて語学学校に半年通学

彼女の3つ目の失敗は英語力です。よく「英語ができなくてもワーホリは楽しかった」という話も聞きますが、正直そのワーホリの1年間は学生がアルバイトして旅行する程度でしかありません。「人生観が変わった」という話も聞きます。それはたしかにありますが、英語を話せていろいろな経験をできたほうが人生観はもっと変わるでしょう。

Bさんの場合、ワーホリで来たのに語学学校へ約半年ほど通っていました。その間、現地人の家にホームステイはしていましたが、英語を学ぶだけの生活になってせっかくのワーキングホリデービザを有効に活用できませんでした。

ニュージーランドに来たことがなかった

もう1つの彼女の失敗は、ニュージーランドへ来たことがなかったということです。大学時代に時間はあったはずですので、ニュージーランドはもちろん、オーストラリアやカナダ、イギリスなどのワーホリ可能な国へ実際に旅行して、比較検討すべきでした。

仮にニュージーランドにするにしても、オークランドだけでなく、首都のウェリントン、南島最大の都市のクライストチャーチ、観光街のクイーンズタウンなど複数の都市があるので、それらを実際に行ってみてから決めるべきでした。

彼女も語学学校に通って半年弱の頃に「オークランドは飽きた」と嘆いていました。このあたりは前回、ワーホリ実質1ヶ月で帰国したA君と同じですね。

帰国後はホテル勤務

Bさんは、語学学校卒業後、 オークランド市内のレストランで半年間アルバイトをして、最後の数週間は北島・南島を観光して帰国しました。

帰国後すぐに就職活動をしてホテルで働いています。ですが、英語を使うことはあまりないそうです。

「今度はオーストラリアにワーホリへ行きたい」と言っていたので、彼女にとって今回のワーホリは失敗ではなかったかもしれませんが、

  • 目的を決めておく
  • ニュージーランドを調べておく
  • 英語力を来る前に身につけておく(もしくは語学留学後にワーホリビザを取得)

といった事ができていれば、もっと充実したワーホリ生活を送れていた思います。

]]>
Categories
ビザ 英語

ニュージーランドでワーホリ失敗例(すぐ帰国した現役大学生)

ワーキングホリデーの失敗例を書く理由

私の家にはワーホリや留学生をフラットメイト(日本で言うシェアハウス)として受けて入れて数年が経ちました。その中でいろいろな人がいたのですが、ワーキングホリデー(ワーホリ)期間を最後まで使って仕事や旅行を楽しんだ人もいれば、逆にわずか数ヶ月で帰国した人もいました。

ワーホリは人生で1回しか使えないし30歳までしか使えない、という限られたビザなので、無駄にはしたくはありませんよね?その機会を無駄にしてもらいたくないので、失敗例を書く事にしました。

私の家に来た人たちの中から、今回はワーホリを途中リタイヤしたA君について紹介したいと思います。

現役大学生が語学学校3ヶ月通学

A君は当時大学3年生で、3年生の秋にニュージーランドへ彼女と一緒にワーホリへ来ました。最初の3ヶ月はクライストチャーチの語学学校に3ヶ月通いました。

何人ものワーホリを見てきましたが、現役大学生がワーホリに来て語学学校に通うほど無駄なことはありません。「大学生なら時間がたくさんあるので、日本にいる間に学んでおけば良いのに」といつも思います。

それと彼ら、彼女らの多くに共通しているのは、学校を卒業しても英語力はたかが知れてて仕事には使えない、ということです。

話を戻して、A君はA君だけオークランドに移動して私の家に住むことになり、彼女はそのままクライストチャーチに残っていました。この時点でA君はは仕事は決まっていなかったので、仕事探しから始まります。

近所の日本食レストランで週5勤務

幸運(?)にも就活数日目に私の家から徒歩5分のところにある日本食レストランでバイトすることになりました。しかし、そのお店の店員ほぼ全員日本人で担当は厨房。つまり、英語を話す機会がまったくありません。

しかも、週5で昼間と夜の両方とも勤務だったので、朝11時前に家を出て、ランチタイム後に1度帰宅して、夕方また出勤して、夜10時頃に帰宅。まかないがでるので食事をすることもなく部屋にこもって、SNSやYoutubeを楽しむ生活でした。

しかもオークランドへ来たばかりなのでそもそも友達がいないし、 休みも平日しか無いので友達と外出もできませんでした。結局英語を話す機会が全くありませんでした。

わずか4ヶ月で帰国。理由は「退屈」

語学留学3ヶ月のあと、オークランドへ来て我が家に住み始めて1ヶ月後のある日。「彼女と一緒に帰国することに決めました」と連絡がありました。

私は止める気は全くありませんでしたが、あまりにも早いことだったので理由を聞きました。すると、

「ニュージーランドは退屈だから」

ということでした。たしかにニュージーランドは退屈で、しかも若者が楽しめるような場所は無いに等しいです。車がなければショッピングモールへ行くのも面倒です。だから彼の気持ちも理解できたので、「たしかに退屈だよね」と答えるだけにしました。

ニュージーランドにエンタメや刺激を求めてはいけない

ニュージーランドという国は日本と比べると遊べるところも少ないです。下の写真がニュージーランド最大の都市オークランドですが、オークランドの中心地以外では夜10時には大抵のお店は閉まってしまいます。そのため、夜遊びも一部の地域を除きほとんどありません。

なので、ワーホリの職場で盛り上がるか、Meet upなどのイベントに参加しないとなかなか遊べる機会がありません。

ニュージーランドと言えば「自然宝庫」を連想すると思いますが、半分は当たってて、オークランドも2ヶ月住んでいたらある程度の名所やスポットを制覇できて飽きてしまいます。

NZといって連想する風景

そういった点で20歳前後の若者にはニュージーランドはとても退屈な国です。だから、よっぽど強い思い入れがない限り20代前半にニュージーランドへワーキングホリデーに来るのはおすすめしません。

]]>
Categories
サッカー 英語

サッカー好きにおすすめの英語リスニング用Youtube動画2

前回はネイティブの英語に慣れるのにおすすめなサッカーYoutube動画を紹介しました。今回は、英語でサッカー戦術や歴史を学べる動画を紹介します。

Guardiola’s Barcelona 2010/11 Tactics | Pep Guardiola’s Greatest Team? | Football Made Simple

まず最初は「 Football Made Simple 」というチャンネルです。こちらは2019年頃から開始しているので古くはありませんが、毎月数本アップしており各動画の中身はかなり濃いです。ですがどの動画もだいたい10分程度なので挫折しにくいです。

この動画のポイント

  • 戦術が詳しく映像と図で紹介されている
  • 移籍や選手の獲得などの説明が丁寧
  • コンテンツがプレミアリーグやリーガの強豪チーム中心なので理解しやすい

です。特にバルセロナとマンチェスターU、アーセナルが多いので、これらのクラブのファンにはおすすめです。

欠点ではありませんが、アクセントや口調からしてネイティブスピーカーではなく、ヨーロッパのドイツや東欧あたりの出身かと思いますので、早口の英語のリスニング教材としては向いていません。

What is a Mezzala? | Tifo Football

2つ目は、「Tifo Football」チャンネルです。「Man City’s Big Weakness: Shots From Outside The Box」や「What is a Mezzala?」ようにアナリティクスの話もありますが、チームの歴史や選手やコーチ、オーナーなどに特化した動画が多いのが特徴です。

この動画のポイント

  • 1本あたりの動画が5分前後で見やすい
  • クラブの歴史や選手の紹介などが詳しい
  • クラブの財政やサッカー界のルールなどの動画もある

How Would Pochettino Set Up Newcastle United | Starting XI, Formation & Transfers | Statman Dave

3つ目は「Statman Dave」チャンネルです。私は最近はこのチャンネルの動画をみることが多いです。ネイティブの英語だけど丁寧でしっかり話してくれるので聞き取りやすいです。10分以上の動画も結構多いのですが、挫折することなく見れます。

この動画のポイント

  • 移籍話や補強のポイントなど戦術の話が多い
  • 概要欄に説明がびっしり書かれているので精読の勉強にもなる
  • 映像や図、文章が動画にたくさん盛り込まれているので理解しやすい

最後に

今回は3つのチャンネルを紹介しました。もし、皆さんのおすすめの動画やチャンネルがありましたらコメントにて紹介してもらえると嬉しいです。

]]>
Categories
データサイエンス

学習曲線(Learning Curve)で過学習、学習不足を検証

前回はvalidation_curveでパラメータの範囲を絞り込む方法を使ってGridSearchCVの実行時間削減に挑戦しました。各パラメータの最適値についてはGridSearchCVで求めることはできるようになりました。

その一方で、学習データ数によって学習不足だったり過学習を起こしていないか?という心配が出てきます。サンプル数が少なかったり、学習データのパラメータが多すぎると過学習を起こしてしまって、検証データにうまく適応できてない、ということはよくあるので、過学習のチェックは必須でしょう。

そこで使うのが学習曲線(learning_curve)です。learning_curveはサンプル数を変えながら学習データと検証データの正解率について、

  • 両者がどのくらいの正解率に着地するか?(=漸近線)
  • 両者の乖離はどれくらいか?

といった観点で比較・検証していきます。

Learning Curveのサンプル

それではさっそく、Learning Curveのコードを書いていきます。今までと同様にKaggleのTitanic課題のデータを使っていますので、学習データと検証データの作り方については過去の記事を参考にしてください。

今回のモデルはランダムフォレストのデフォルトを使ってみます。learning_curve関数の引数は以下になります。

  • estimator:検証したいモデル
  • X :入力データ
  • y : 出力データ
  • train_sizes : 試したいサンプル数([100, 200, 300, …, 1000])
  • cv : バリデーションデータセットを作成する際の分割方法(デフォルトは5-fold法)
from sklearn.model_selection import learning_curve
clf = RandomForestClassifier()
train_sizes, train_scores, test_scores = learning_curve(estimator = clf, X = X_train,train_sizes=train_sizes, y = y_train, cv=10, n_jobs=1)
train_mean = np.mean(train_scores, axis=1)
train_std  = np.std(train_scores, axis=1)
test_mean = np.mean(test_scores, axis=1)
test_std  = np.std(test_scores, axis=1)

learning_curveは学習データの結果と検証データの結果の2つの結果をそれぞれ配列で返します。そこでこれらの結果を比較するためにグラフ化します。

import matplotlib.pyplot as plt
train_scores_mean = np.mean(train_scores, axis=1)
train_scores_std = np.std(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)
test_scores_std = np.std(test_scores, axis=1)
plt.figure()
plt.title("Learning Curve")
plt.xlabel("Training examples")
plt.ylabel("Score")
# Traing score と Test score をプロット
plt.plot(train_sizes, train_scores_mean, 'o-', color="r", label="Training score")
plt.plot(train_sizes, test_scores_mean, 'o-', color="g", label="Validation score")
# 標準偏差の範囲を色付け
plt.fill_between(train_sizes, train_scores_mean - train_scores_std, train_scores_mean + train_scores_std, color="r", alpha=0.2)
plt.fill_between(train_sizes, test_scores_mean - test_scores_std, test_scores_mean + test_scores_std, color="g", alpha=0.2)
# Y軸の範囲
plt.ylim(0.7, 1.0)
# 凡例の表示位置
plt.legend(loc="best")
plt.show()

これだけでは検証データの正解率が上がっていないのはわかりますが、だから何?と言った感じで、どうしたら良いのかがわかりませんね。

Learning Curveの使い方

Learning Curveの結果は大きく3つに分けられます。

成功パターン(両方とも高い正解率で収束)

学習データ、検証データともに高い正解率に収束し、サンプル数が増えても検証データが下がることがない場合は成功パターンと言えます。

学習不足パターン(両方とも低い正解率)

学習データと検証データが近づいているものの、正解率が低い場合は学習不足が考えられます。このような学習不足の場合はパラメータを増やすのが一般的です。

過学習(学習データだけ高い正解率)

学習データの正解率だけ高くて、検証データの正解率が低い場合、過学習を起こしている可能性が高いです。これが発生するのは主にサンプル数が少なくて、パラメータ数が多すぎる場合です。

こちらは検証データの正解率が0.83くらいで頭打ちになっていることがわかります。このことからサンプル数を増やしても正解率が上がらないことが予想されます。

この場合は、パラメータが多すぎる可能性が高いので、パラメータを減らしてみる事をオススメします。

一方、下記の場合は、サンプル数が1400の時点でも、それ以降正解率が上がり続ける可能性がありそうです。このような場合はサンプル数を増やして再度検証するのが良いでしょう。

Learning Curveでモデル作成後の過学習の検証に使う

Learning Curveは過学習の検証に使うのが多いようです。そのため、使う流れとしては、GridSearchCVなどでモデルを作成後で、このLearning Curveで過学習の可能性がある場合は、パラメータの変更が必要になってきます。

次回はパラメータ(特徴量)の選定方法について紹介したいと思います。

]]>
Categories
データサイエンス

validation_curveでGridSearchCVとRandomForestClassifierのパラメータチューニング

前回はGridSearchCVを使って、ランダムフォレスト(RandomForestClassifier)のパラメータの最適解を求めました。

「GridSearchCVを使えば、いつでも最適解を出せるから楽だよね

と思ってました。

ですが、甘かったです。前回のはわずか30分程度で終わりましたが、実は最初に適当に各パラメータの候補を最大10個くらい設定して(=配列の要素数を10個)にして行ったら、2時間以上かかってしまいました。

たった数百行の学習データでパラメータも数種類しかないのに2時間だったら、私が実務で使っているのは会員データだけで3000万レコード、購入履歴は数億レコードもあるので、GridSearchCVをそのまま使うのは非現実的です。(それを全部使うことは実際はありませんが。。。)

validation_curveでパラメータの範囲を絞る

そこで使うのがvalidation_curve です。validation_curveについての詳しい説明は省略しますが、訓練データとテストデータでの正解率を比較して、ハイパーパラメータの値が小さすぎて学習不足だったり、逆に値が大きすぎて過学習を起こしたりしていないか?を確認するものです。

それでは実際に前回と同様にKaggleのTitanic課題を使って、max_depthを1,3,5,7・・・29までとして検証してみましょう

from sklearn.model_selection import validation_curve
param_range = list(range(1,30,2))
train_scores, test_scores = validation_curve(estimator = RandomForestClassifier(), X = X_train, y = y_train, param_name="max_depth", param_range=param_range, cv=5, n_jobs=1)
train_mean = np.mean(train_scores, axis=1)
train_std  = np.std(train_scores, axis=1)
test_mean = np.mean(test_scores, axis=1)
test_std  = np.std(test_scores, axis=1)
plt.plot(param_range,train_mean,label="Training score",color="black")
plt.plot(param_range,test_mean,label="Validation score",color="dimgrey")
plt.fill_between(param_range, train_mean + train_std, train_mean - train_std, alpha=0.1, color="orange")
plt.fill_between(param_range, test_mean + test_std, test_mean - test_std, alpha=0.1, color="darkblue")
plt.legend(loc="upper left")
plt.title("Validation Curve")
plt.xlabel("max_depth")
plt.ylabel("Accuracy Score")
plt.tight_layout()
plt.show();
  • Training Score:訓練データのグラフ
  • Validation Score:テストデータのグラフ( 標準偏差の範囲を色付けしています)
  • 横軸:max_depthの値(1、3、5・・・・29)
  • 縦軸(Accuracy Score):正解率

訓練データでは17あたりでほぼピークに達しているのがわかります。一方、テストデータをみると7あたりでピークいなっているのがわかりますので、GridSearchCVでは3~15くらいで検証すれば良いと推測できます。

つまり、前回のGridSearchCVではmax_depthを 3, 5, 10, 15, 20, 25, 30, 50, 100で行いましたが15や20・・・100が無駄で、その分、10以下の数値に割り当てたほうが良いということがわかります。

validation_curveを関数化

validation_curveは各パラメータについて使いますので、関数化します。今回はn_jobs=1、画像の凡例の位置を左上に固定していますが、どちらも任意です。

from sklearn.model_selection import validation_curve
import matplotlib.pyplot as plt
def func_validation_curve(model,X_train,y_train, p_name, p_range, cv ):
    train_scores, test_scores = validation_curve(estimator = model, X = X_train, y = y_train, param_name=p_name, param_range=p_range, cv=cv, n_jobs=1)
    train_mean = np.mean(train_scores, axis=1)
    train_std  = np.std(train_scores, axis=1)
    test_mean = np.mean(test_scores, axis=1)
    test_std  = np.std(test_scores, axis=1)
    plt.plot(param_range,train_mean,label="Training score",color="blue")
    plt.plot(param_range,test_mean,label="Validation score",color="red")
    plt.fill_between(param_range, train_mean + train_std, train_mean - train_std, alpha=0.1, color="cyan")
    plt.fill_between(param_range, test_mean + test_std, test_mean - test_std, alpha=0.1, color="magenta")
    plt.legend(loc="upper left")
    plt.title("Validation Curve - " + p_name)
    plt.xlabel(p_name)
    plt.ylabel("Accuracy")
    plt.tight_layout()
    plt.show();

他のパラメータでもvalidation_curveを実施

それでは他のパラメータについてもvalidation_curveを実施します。前回のGridSearchCVで算出した最適解を使って行います。

clf = RandomForestClassifier(bootstrap=True, ccp_alpha=0.0, class_weight=None, max_depth=7
                       criterion='gini', max_features=1.0,
                       max_leaf_nodes=None, max_samples=None,
                       min_impurity_decrease=0.0, min_impurity_split=None,
                       min_samples_leaf=1, min_samples_split=10,
                       min_weight_fraction_leaf=0.0, n_estimators=1000,
                       n_jobs=1, oob_score=False, random_state=1,
                       warm_start=False)

criterion

param_range = ["gini","entropy"]
func_validation_curve(clf, X_train, y_train, 'criterion', param_range, 5)

criterionはginiとentropyの2種類しかないので、GridSearchCVでは両方試して良いと思いますが、参考までにやってみました。

max_features (ノード分割する際に考慮する特徴量数)

param_range = [0.1,0.3,0.5,0.7,0.9,1.0]
func_validation_curve(clf, X_train, y_train, 'max_features', param_range, 5)

max_featuresは0.5以上が良さそうなことが伺えます。1.0になるとTraining Scoreが上がっているのに対してValidation Scoreが下がっているので、過学習を起こしているかもしれません。

min_samples_split (末端ノード内の最小サンプル数)

次にmin_samples_splitです。こちらも前回のGridSearchCVで使った範囲で行います。

param_range = [3, 5, 10, 15, 20, 25, 30, 50, 100]
func_validation_curve(clf, X_train, y_train, 'min_samples_split', param_range, 5)

っが、15以降はTraining ScoreもValidation Scoreも悪化しているので、2~20までで再度検証してみます。

これをみると2~20までほぼ横ばいなのがわかります。GridSearchCVではこの全範囲を対象にするとします。

n_estimators

前回、 n_estimatorsはやっても意味がない、ということを書きましたが、せっかくなのでn_estimatorsも検証してみましょう。

param_range = [10,20,30,50,100,250,500,750,1000]
func_validation_curve(clf, X_train, y_train, 'n_estimators', param_range, 5)

実際にやってみると100以降はほぼ横ばいです。ということで100まででもう1度検証します。

param_range = [1,5,10,20,25,50,75,100]
func_validation_curve(clf, X_train, y_train, 'n_estimators', param_range, 5)

これをみる限りでは25~150までわずかに上昇して、それ以降は下降しているように見えます。いずれにしても前回は1000で固定していたのですが、そこまで大きくする必要はなさそうです。

GridSearchCVを再実行

今回の結果をもとにGridSearchCVを再度実行してみます。結果もそうですが、時間がどれだけ短縮されるかにも着目してみます。

from sklearn.model_selection import GridSearchCV
# RandomForestClassifierで使用するパラメータ
search_params = {
     'n_estimators'      : [150],
      'criterion':['gini','entropy'],
      'max_features'      :[0.5,0.6,0.7,0,8,0.9],
      'random_state'      : [1],
      'min_samples_split' : [2, 3, 5, 7, 9, 11, 13, 15],
      'max_depth'         : [3, 5, 7, 9, 11, 13, 15],
}
# GridSearchCVのオブジェクトを作成
gs = GridSearchCV(RandomForestClassifier(), search_params, cv=5, verbose=2, n_jobs=-1)
# 学習用データを適用
gs.fit(X_train,y_train)
# 最適モデルを取得
best_clf = gs.best_estimator_
# スコアを表示
gs.best_score_

スコアは0.8330709677419355となりました。前回が 0.8406691356474798でしたので、良くなっているのがわかります。

早速これをKaggleにアップロードしてスコアを見てみましょう。

ですが、結果は前回よりも若干悪化してしまいました。

補足:各画像のタイトルで「Validation Curve」とすべきところを「Validationn Curve」としてしまいました。。。

]]>
Categories
データサイエンス

matplotlib.pyplotの'str' object is not callableエラー

謎のエラー ‘str’ object is not callable

Pythonでグラフを作成するときによく使うmatplotlib.pyplotですが、ある時、何気なくいつもどおりラベルを表示させようとしたら、‘str’ object is not callableという謎のエラーが出てました。

import matplotlib.pyplot as plt
# 中略
plt.xlabel('new label')

pyplot.xlabel(文字列)関数自体は存在するはずなのに、なぜこんなエラーが出るのか?

過去に別の呼び出し方をしていることが原因らしい

https://stackoverflow.com/questions/19442060/matplotlib-pyplot-titlestring-returns-errorhttps://stackoverflow.com/questions/50845106/matplotlib-ylabel-typeerror-str-object-is-not-callable を読むと、どうやら

plt.xlabel = 'old label'

というように、以前にすでにxlabelに文字列を挿入していたために、pyplot.xlabelが関数ではなく文字列とされてしまっていることが原因のようです。

改善策は再起動か「 Close and Halt 」

改善するには、1度終了させるしかないようなので、

  1. 保存
  2. 「File」→「Close and Halt」をクリック
  3. 再度ファイルを開く

の手順を行えばOKです。

ファイルを再度開いて実行すると、

import matplotlib.pyplot as plt
# 中略
plt.xlabel('new label')

結果がきちんと表示されました。

言われてみればなんてことない事ですが、いきなりこんなエラーが出たので焦りました。

]]>
Categories
データサイエンス

KaggleのTitanic課題をGridSearchCV+RandomForestClassifierで挑戦

前回はRandomForestClassifierでTitanic課題に挑戦しましたが、その前に行ったDecisionTreeClassifierよりも悪い結果となってしまいました。通常はRandomForestClassifierのほうが良い結果が出る傾向にあるので、パラメータのチューニングに挑戦します。

RandomForestClassifierのパラメータ

RandomForestClassiferには主に以下のようなパラメータがあります。他にもありますが今回は省略します。

n_estimators決定木の個数(≠深さ)
criterion分割基準(giniまたはentropy)
max_featuresノード分割する際に考慮する特徴量数。整数で指定した場合はその個数、小数の場合は全特徴量 数 に対する割合、autoは全特徴量 数 のルート数、log2はlog2(全特徴量数)。
max_depth決定木の深さ。過学習を避けるのが目的。
random_state乱数生成を制御するパラメータ。これを指定することで毎回発生する乱数を固定化する。
n_jobs使用するCPUのコア数。-1にすると全CPUコアを仕様。デフォルトは1となり並列実行はしない。
min_samples_split末端ノード内の最小サンプル数。整数で指定した場合は個数、小数の場合は全体に対する割合。
verbose 実行時のログ出力。verbose=1:経過時間と実行数を表示。verbose=2:各ツリーの構築に関する残りの情報を表示。

パラメータの最適解を強引に探すのがGridSearchCV

しかしながら、パラメータをチューニングといってもどこからどう手を付けて行ったら良いのか?がわかりませんし、毎回あれこれ試行錯誤するのも時間がかかります。

そこで、「わからないなら片っ端から調べて最適解を見つけよう!」というやり方がGridSearchCVです。

GridSearchCVの使い方

GridSearchCVの使い方の手順は以下のとおりです。

  1. RandomForestClassifierのパラメータを用意
  2. 予測モデルやパラメータを用いてGridSearchCVオブジェクトを作成
  3. GridSearchCVに学習用データを当てはめる
  4. 最適パラメータ、最適モデルを取得
  5. 予測

パラメータを用意

まず最初にRandomForestClassifierで試したいパラメータを用意します。今回は、とりあえず以下の6つを設定してみます。

n_estimators1000
criterion‘gini’,’entropy’
max_features0.1,0.25,0.5,0.75,1.0
random_state1
min_samples_split3, 5, 10, 15, 20, 25, 30, 50, 100
max_depth3, 5, 10, 15, 20, 25, 30, 50, 100

n_estimators、random_stateについては固定としていますが、決まった値だけを使用したい場合は、このように1つだけ値を用意すればOKです。

補足

n_estimatorsを1つだけにしている理由については、「なぜn_estimatorsやepochsをパラメータサーチしてはいけないのか」が参考になりました。

random_stateも乱数の発生を決めるものなので、1つだけで構いません。

予測モデルやパラメータを用いてGridSearchCVオブジェクトを作成

次に、GridSearchCVオブジェクトを作成します。

from sklearn.model_selection import GridSearchCV
GridSearchCV(estimator, param_grid, scoring=None, n_jobs, cv=None, verbose=0, refit=True)

GridSearchCVの主な引数は、以下の7つです。

estimatorチューニングを行うモデル(今回はRandomForestClassifier())
param_grid上記のモデルでチューニングを試したいパラメータ({パラメータ名:[値のリスト]}の辞書として入れる
scoring評価関数( ‘accuracy’, ‘precision’, ‘recall’ などを配列として入れる)
n_jobs同時使用CPU数(-1なら全CPUを使用)
cvCross validationの分割数(defaultは3分割)
verboseログの表示方法
refitTrueの場合、最適解で全学習データを使って再学習を実施

GridSearchCVに学習用データを当てはめる

GridSearchCVオブジェクトを作成したら次に学習用データを当てはめます。これはこれまで行った予測モデルと同じようにfit(説明変数,目的変数)とするだけです。

from sklearn.model_selection import GridSearchCV
gs = GridSearchCV(RandomForestClassifier(), search_params, cv=5, verbose=2, n_jobs=-1)

この時、オブジェクト作成時に設定したverboseの値によって、出力されるログが異なります。下記はVerbose=1と設定したときのログです。最初の「Fitting 5 folds for each of 810 candidates」はクロスバリデーションで5分割して、検証するパラメータの組み合わせが全部で1×2×5×1×9×9=810種類ある事を意味しています。

最適パラメータ、最適モデルを取得

終了したら最適パラメータと最適モデルを取得します。

best_param = model_tuning.best_params_
best_estimator = model_tuning.best_estimator_

最適モデルを表示すると下記のようになります。

予測

最適モデルはそのまま使えるので、テストデータを当てはめて予測します。結果は前回と同様にCSVファイルに出力します。

y_pred = best_clf.predict(test_dataset)
PassengerId = np.array(test_csv['PassengerId'].values)
my_result = pd.DataFrame(y_pred, PassengerId, columns=['Survived'])
my_result.to_csv('titanic_gridseachcv_randomforestclassifier2.csv', index_label='PassengerId', encoding='utf-8')

まとめ

今回のGridSearchCVを使ったTitanic課題用のPythonプログラムは下記のようになります。

from sklearn.model_selection import GridSearchCV
# RandomForestClassifierで使用するパラメータ
search_params = {
     'n_estimators'      : [1000],
      'criterion':['gini','entropy'],
      'max_features'      :[0.1,0.25,0.5,0.75,1.0],
      'random_state'      : [1],
      'min_samples_split' : [3, 5, 10, 15, 20, 25, 30, 50, 100],
      'max_depth'         : [3, 5, 10, 15, 20, 25, 30, 50, 100],
}
# GridSearchCVのオブジェクトを作成
gs = GridSearchCV(RandomForestClassifier(), search_params, cv=5, verbose=2, n_jobs=-1)
# 学習用データを適用
gs.fit(X_train,y_train)
# 最適モデルを取得
best_clf = gs.best_estimator_
# テストデータで予測
y_pred = best_clf.predict(test_dataset)
# Kaggleにアップロード用のCSVファイルの作成
PassengerId = np.array(test_csv['PassengerId'].values)
my_result = pd.DataFrame(y_pred, PassengerId, columns=['Survived'])
my_result.to_csv('titanic_gridseachcv_randomforestclassifier2.csv', index_label='PassengerId', encoding='utf-8')

このCSVファイルをKaggleにアップロードすると、

わずかですが新記録達成です。

GridSearchCVは時間がかかるので工夫が必要

GridSearchCVはモデルの学習を繰り返すのでその分時間がかかります。今回私の場合は、約35分で終わりましたが、その間CPUやメモリはほぼMaxでしたので、他の作業は全くできませんでした。

実を言うと、これでも各パラメータの配列の数を減らしました。今回はパラメータの組み合わせは810パターンでしたが、最初試したときは1200パターン以上あり、2時間以上かかりました。

GridSearchCVは最適解を見つけるのですが、その分時間がかかり運が悪いとフリーズすることもあります。そのため、GridSearchCVを行う前にパラメータの範囲に目星をつけておくことがとても重要です。

次回は、パラメータの範囲の見つけ方を紹介したいと思います。

]]>