ABC157C Guess The Number

問題

https://atcoder.jp/contests/abc157/tasks/abc157_c

方針

整数が存在しないNGケースは以下の二つの場合である。

  • 矛盾する条件が存在する
  • 1桁目に0が指定されている

NGの場合、入力を全て受け付けた後に-1を出力する。

並行して、各桁の条件を記録しておく。

  • 記録があれば、その通り出力する
  • 記録がない場合は
    • 1桁目であれば1を出力する
    • それ以外は0を出力する

ポイント

  • NGケースのフラグ付け
  • 条件の記録
    を一つのループの中で並行して行なっている。

コード

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
N, M = map(int, input().split())
cand = ['*'] * N # 候補を記憶しておくリスト
mn = '' # 最小値、およびNGフラグ
for m in range(M):
s, c = map(int, input().split())
if s==1 and c==0 and N > 1: # NG:1桁目に0が指定されている。ただしN=1ならセーフ。
mn = '-1'
if cand[s-1] == '*' or cand[s-1] == str(c):
cand[s-1] = str(c)
else: # NG:矛盾する条件が存在する
mn = '-1'

if mn == '-1': # NGのフラグが立っているので-1を出力
print (mn)
exit()

for i in range(N):
if cand[i]=='*': # 記録がない場合
if i==0 and N > 1::
mn+='1' # 1桁目であれば1。ただしN=1は例外。
else:
mn+='0' # それ以外は0
else:
mn+=cand[i] # 記録があれば、条件通り出力
print (mn)

連載「scikit-learnで学ぶ機械学習」を始めます

はじめに

近年の機械学習ブームもあり、機械学習を始めたいと思っている方も多いのではないでしょうか。

そこで、scikit-learnで学ぶ機械学習というタグで連載記事を書いていこうと思います。

この記事では

  • なぜ、機械学習を学ぶためにscikit-learnを使うのか
  • 今後、連載で扱う内容
    について書いていきたいと思います。

    scikit-learnとは

    なぜ、機械学習を学ぶためにscikit-learnを使うのか

    機械学習はプログラミングしながら学んだ方が良いから

    機械学習はその名の通り、機械に学習をさせます。

ここでいう、機械とはすなわちコンピュータプログラムのことです。

つまり、機械学習という技術のアウトプットでは、プログラムに落とし込むプロセスがあります。

(一部の理論研究などは除きます)

そのため、アルゴリズムの学習段階から、プログラムを動かして学ぶと非常に効率が良いです。

もちろん、仕事として使うためには数式の理解も必要ですが、実装しながらあるいは実装して概略を理解した後

でも十分と言えるでしょう。

scikit-learnでは、主要なアルゴリズムが豊富だから

これはscikit-learnのチートシートで、

質問に答えていくとどのようなアルゴリズムを選択すれば良いかがわかります。

(https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html)

凄そうな図ですが、これでも実装されているアルゴリズムの極一部です。

scikit-learnはとにかくアルゴリズムが豊富で、主要なものはほぼ揃っていると考えて良いです。

そのため、教科書に出てくるような概念は、大体scikit-learnで実装されているので、

scikit-learnも絶好の教材というわけです。

scikit-learnは、現場でも使われるので実践的だから

scikit-learnは機械学習のライブラリとしては、(他の言語含めても)ほぼ一強です。

つまり、業務で機械学習を使うとなった場合、かなりのケースでscikit-learnを利用することになるでしょう。

そのため、scikit-learnのスキルを身につけておく事で、とても市場価値が上がると言えます。

ただし、scikit-learnの弱点は、Deep Learningをカバーしていない点です。

その点は、TensorFLowやPyTorchなどの深層学習ライブラリでカバーする必要があります。

今後、連載で扱う内容

本家のユーザガイドで整理されている構成に準拠して、8つのテーマを扱います。

  1. Supervised learning
  2. Unsupervised learning
  3. Model selection and evaluation
  4. Inspection
  5. Visualizations
  6. Dataset transformations
  7. Dataset loading utilities
  8. Computing with scikit-learn

Supervised learning

教師あり学習。ロジスティック回帰について学びます。

第1回「教師あり学習」

Unsupervised learning

教師なし学習。クラスタリングについて学びます。

第2回「教師なし学習」

Model selection and evaluation

モデル選択と評価。学習したモデルの評価について学びます。

第3回「モデル選択と評価」

Inspection

検査。どの特徴量が重要であるかを解釈する方法について学びます。

第4回「検査」

Visualizations

可視化。評価結果を素早く可視化する方法について学びます。

第5回「可視化」

Dataset transformations

データセット変換。データの前処理について学びます。

第6回「データセット変換」

Dataset loading utilities

データセット読み込みユーティリティ。アヤメデータのロードについて学びます。

第7回「データセット読み込みユーティリティ」

Computing with scikit-learn

scikit-learnによる計算。増分学習について学びます。

第8回「scikit-learnによる計算」

終わりに

他にも様々なテーマでまとめ記事を書いているのでよろしければご覧ください。

まとめ記事の一覧

記事情報

  • 投稿日:2020年2月29日
  • 最終更新日:2020年5月23日

多次元配列を生成してNumpyに変換

多次元のリストをnumpy.ndarrayに変換する方法をまとめます。

九九の表をnumpy.ndarrayで得たいとしましょう。

その場合、numpy.ndarrayをfor文の中で生成するのではなく、最後に一括して変換を行います。

都度、変換してしまうととても遅くなります。

1
2
3
4
5
6
7
import numpy as np
table = [] # 空のリストを用意
for i in range(1,10):
row = [] # ループの度に、空のリストを用意
for j in range(1,10):
row.append(i*j) # 内側のリストに要素を追加
table.append(row) # 外側のリストに要素を追加
1
2
3
4
5
6
7
8
9
10
>>> table
[[1, 2, 3, 4, 5, 6, 7, 8, 9],
[2, 4, 6, 8, 10, 12, 14, 16, 18],
[3, 6, 9, 12, 15, 18, 21, 24, 27],
[4, 8, 12, 16, 20, 24, 28, 32, 36],
[5, 10, 15, 20, 25, 30, 35, 40, 45],
[6, 12, 18, 24, 30, 36, 42, 48, 54],
[7, 14, 21, 28, 35, 42, 49, 56, 63],
[8, 16, 24, 32, 40, 48, 56, 64, 72],
[9, 18, 27, 36, 45, 54, 63, 72, 81]]

変換を行う際はnp.array()としてあげるだけで大丈夫です。

1
2
3
4
5
6
7
8
9
10
11
>>> table = np.array(table)
>>> table
array([[ 1, 2, 3, 4, 5, 6, 7, 8, 9],
[ 2, 4, 6, 8, 10, 12, 14, 16, 18],
[ 3, 6, 9, 12, 15, 18, 21, 24, 27],
[ 4, 8, 12, 16, 20, 24, 28, 32, 36],
[ 5, 10, 15, 20, 25, 30, 35, 40, 45],
[ 6, 12, 18, 24, 30, 36, 42, 48, 54],
[ 7, 14, 21, 28, 35, 42, 49, 56, 63],
[ 8, 16, 24, 32, 40, 48, 56, 64, 72],
[ 9, 18, 27, 36, 45, 54, 63, 72, 81]])

データ分析とは何か?機械学習との関係について

はじめに

昨今、データ分析という言葉をよく耳にするようになりました。

データ分析とは一体どんなもので、機械学習とはどういう関係にあるのか。

データ分析のプラットフォームであるKaggleにも触れながら解説してみたいと思います。

データ分析とは

データ分析の目的

「データ分析の主目的は、より良い決定を下すこと」です。

※データサイエンティストの中でも注目度が高い書籍「スケーラブルデータサイエンス」より

つまり、データに基づいた決定を下すためのあらゆる営みがデータ分析と言えるわけですが、これでは少し抽象的です。

そもそも、データに基づいた決定にはどんなものがあるでしょうか。

具体例

ほんの一例ですが、

  • 住宅ローンの審査
  • 中古車の査定
  • ネットニュースが本物かフェイクかの判定
  • Q&Aの質問および回答が適切か

など、企業(時には個人)の多くの営みが、データに基づいた判断と言えるでしょう。

(逆に、大きな組織がデータに基づかない判断をしているとすれば、それはとてもリスクに思えます。)

決定を行うのは誰か

次に、データに基づいた決定を誰が行うのかという視点があります。

  • プログラム
  • 人間
  • ハイブリッド

似た意思決定を大量に行う必要がある場合は、プログラムでの決定が向いています。
例えば、

  • 自動審査
  • 株の自動取引
    などがその例と言えるでしょう。

パターン化しにくいケースや大きな判断は、人間の決定が向いています。
例えば、

  • 事業戦略の判断
    などがあります。

難易度が高い、あるいはセンシティブなタスクはハイブリッドな決定が向いています。

  • 採用活動の書類チェック
    などがあります。

データ分析のプロセス

あまり一般的ではないかもしれませんが、私はデータ分析は以下の3つのプロセスに分解できると考えています。

  1. 探索的データ解析(EDA)
  2. 特徴量エンジニアリング
  3. モデリング
  • 人間が決定では、1のプロセス
  • プログラムやハイブリッドな決定では、1,2,3全てのプロセス
    が求められます。

順に見ていきましょう。

探索的データ分析(EDA)

探索的データ分析とは、データをインタラクティブに触りながら、統計量を確認したり可視化を行う工程です。

一体どんなデータなのかを人の頭で理解できるようにするためのプロセスと言えるでしょう。

具体的な手法としては、

  • 統計値(平均、分散)
  • 外れ値
  • 散布図
  • ヒストグラム
    などがあります。

特徴量エンジニアリング

プログラムにデータを処理させるための準備のプロセスです。
具体的な手法としては、

  • one-hot encoding
  • TF-IDF
  • 対数変換
  • 主成分分析(PCA)
    などがあります。

生のデータを与えるのではなく、より情報の密度が高いデータに変換してから与えることで、優れた判断ができることがあります。

特徴量エンジニアリングは人間の仕事です。

探索的データ分析で得た仮説を元に、プログラムがその仮説をうまく捉えられるように、このプロセスを行います。

やや余談ですが、近年流行している深層学習(Deep Learning)ではこの役割が小さくなったと言われています。

具体的には、画像処理が顕著です。

とはいえ、このプロセスはデータ分析において依然として重要です。

特徴量エンジニアリングを題材にした書籍もあるくらいです。

(ページ数は多くないので、サクッと読めます。)

モデリング

プログラムにどんなアルゴリズムで処理をさせるかを決めるプロセスです。

具体的には

  • 線形回帰
  • ロジスティック回帰
  • ニューラルネットワーク
    • CNN
    • LSTM
    • Transformeer
  • 決定木
    • LightGBM
    • Random Forest
      などがあります。

あるいは、これらを組み合わせることもあります。

(アンサンブル学習と言います。)

プロセスとしては、特徴量エンジニアリングと分けましたが、実際には両者の関係は密接で

モデルによって適切な特徴量が異なる場合もあるということは覚えておいてください。

ここまでのまとめ

  • データ分析の主目的は、より良い決定を下すこと
  • データ分析の文脈では、決定を行うのは誰かという視点を意識する
  • データ分析のプロセスは「EDA」「特徴量エンジニアリング」「モデリング」に分類される

データ分析と機械学習の関係とは

ここまでの話を理解できると、両者の関係をスムーズに説明できます。

データ分析のプロセス「3. モデリング」で用いるアルゴリズムが、基本的に機械学習の技術です。

時には、ここで単純な統計量やルールベースに基づいたモデルを用いることもありますが、

現実のタスクは複雑で、ルールでの記述は困難です。そこで、データを集めてその問題をクリアするのが機械学習となるわけです。

機械学習自体の説明は、巷に溢れているかと思いますので他に譲ります。

特徴量エンジニアリングは、その後のプログラムによる処理を前提としているので、特徴量エンジニアリングを含めて機械学習の技術として取り扱うこともあります。

(そもそも昨今は、機械学習の定義自体が関連技術に向けて広がっているように思います。)

Kaggleとの関係とは

データ分析プラットフォームであるKaggleとここまでの話はどう結びつくでしょうか。

Kaggleのコンペティションでは基本的に、課題とデータが与えられ、より高精度な予測をすることが目的です。

その際に、予測結果(もしくはソースコード)が求められますので、

データ分析のプロセスで言うプログラムによる決定となり、

  1. 探索的データ解析(EDA)
  2. 特徴量エンジニアリング
  3. モデリング

全てのスキルが求められます。

そのため、kaggleはデータ分析のためのスキルを養う絶好の場と言えます。

以下は強豪Kagglerが執筆した書籍で、2020年2月現在のKaggleの決定版と言える書籍です。

ちなみに、2020年2月現在はまだ発売前ですが、下記の書籍も著者の顔ぶれを見ると素晴らしい書籍になっていると思います。

Kaggleで勝つデータ分析の技術に比べると、初学者向けの書籍といえます。

オンライン学習サービスUdemyでもKaggleについて学ぶことができます。

【Kaggleで学ぼう】Python と Keras で学ぶディープラーニング開発入門

Kaggleでは得られないこと

Kaggleでは

  1. 探索的データ解析(EDA)
  2. 特徴量エンジニアリング
  3. モデリング
    全てのスキルを養える一方で、課題とデータは与えられます。

実世界のデータサイエンスでは、課題を発見し、どのようなデータを集めれば良いかというスキルも必要です。

その点だけは注意が必要ですが、1~3のスキルを養いプロセスを高速に回せる、あるいはイメージできるようにしておくことで、

効率よく、課題を発見し、どのようなデータを集めれば良いかを判断できるようにもなるでしょう。

まとめ

データ分析とは何かについてまとめ

  • 機械学習
  • Kaggle
    との関連性を整理しました。

良いデータ分析ライフを!

記事情報

  • 投稿日:2020年2月27日
  • 最終更新日:2020年3月26日

ARC010A 名刺交換

問題

https://atcoder.jp/contests/arc010/tasks/arc010_1

方針

  • 愚直に条件のチェックや、名刺の消費・補充を実装する

ポイント

  • 名刺が足りなくなった場合、exit()する
  • そうでない場合、最後にcompleteを出力する

コード

1
2
3
4
5
6
7
8
9
10
11
12
13
N, M, A, B = map(int, input().split())
usage = []
for m in range(M):
usage.append(int(input()))

for i,u in enumerate(usage):
if N <= A:
N += B
N -= u
if N < 0:
print (i+1)
exit()
print ('complete')

ads.txtの設置

ads.txt

未設定の場合は、Google Adsenseのコンソールにて

「収益に重大な影響が出ないよう、ads.txt ファイルをダウンロードして、次の各サイトのルートレベルのドメインにアップロードしてください。」

という注意が出ており、設定を行う必要がある。

ドキュメントルート

ads.txtをwebサーバのドキュメントルート直下に置けば良い。

(この方法なら、サブディレクトリに配置する形でWebサイトをWordPressで構築している場合などでも設定が可能だ。)

Apacheのドキュメントルート

/var/www/html/

Nginxのドキュメントルート

/usr/share/nginx/html

ドキュメントルートを変更している場合

下記の設定ファイルを確認して下さい。

Apacheの場合

/etc/httpd/conf/httpd.conf

Nginxの場合

/etc/nginx/nginx.conf

Google Cloud Associate Cloud Engineer 教材まとめ

どんな教材を使ったか、合格してみての感想を振り返ります。

使った教材

書籍

Google Cloud Platform エンタープライズ設計ガイド

GCPの各サービスを広く浅く扱っています。

Associate Cloud Engineerでは、GCPの全体像について広い理解が求められます。

そういう意味で、一番最初に目を通していただきたい書籍です。

全てを理解しようとするのではなく、学ぶべき内容を俯瞰するために読んでみてください。

また、試験の直前に読み直すのもおすすです。紙媒体であっても、単行本サイズなので持ち運びやすくて便利です。

プログラマのためのGoogle Cloud Platform入門 サービスの全体像からクラウドネイティブアプリケーション構築まで

こちらは1冊目に比べると、より実践的な本です。

コードを動かしながら読み進めていくスタイルのため、知識がとても定着しやすいと思います。

GCPはGUIやAPIの仕様が、度々変わりますので、書籍の通りには動かないかもしれません。

適宜、補完しながら読み進めていくといいでしょう。

試験の概要と試験ガイド

これらの内容には必ず目を通しましょう。

https://cloud.google.com/certification/cloud-engineer?hl=ja
https://cloud.google.com/certification/guides/cloud-engineer?hl=ja

試験では、どういう技術が扱われるのかを大まかに理解することが大切です。

これらの概要やガイドを使って、定期的に確認し勉強方法に穴がないかを確認しましょう。

模擬試験

Googleが公式に模擬試験を公開しています。

https://cloud.google.com/certification/practice-exam/cloud-engineer?hl=ja

最後に採点結果と解説が見れるので、これをpdf化しておくと良いでしょう。

正解の選択肢だけではなく、不正解の選択肢についてもその理由を理解すると良いと思います。

問題数は20問で、何度受けても内容が変わることはありません。

  • 学習の初期に一回
  • 試験日の直前に一回

受けると良いと思います。

公式ドキュメント

GCPの資格では、公式ドキュメントの内容が非常に役に立ちます。

とはいえ、こうls行きドキュメントの量は膨大で全てを読むことは現実的ではありません。

そこで、他の教材で学習する際の辞書のような役割として利用するのがベストです。

必要に応じて、チュートリアルなどで手を動かすと理解が深まるでしょう。

Qwiklabs

Qwiklabsはハンズオン形式で進められる教材です。

Qwiklabs側で、ハンズオンのプロジェクトがオンデマンドに作成されるので、環境構築等の煩わしさがありません。

例えば以下のような講座があります。

GCPの基礎

Qwiklabsは有料ですので、そこにお金をかけたくないという方は、
GCPの300ドル分クーポン+公式チュートリアルで、代替しても良いと思います。

Coursera

Courseraは、講義をオンラインで受講できるサービスです。

例えば以下のような講座があります。

Google Cloud Platform Fundamentals: Core Infrastructure

音声は英語ですが、日本語字幕もあるので特に問題はないと思います。

Courseraも有料ですが無料期間もあるので、良さそうなら継続するという形で登録してみるといいでしょう。

頑張れば、無料期間中に進めることも可能です。

Courseraの素晴らしい点は、公式アプリがありオフラインに動画を保存できる点です。

筆者は家でダウンロードをしておいて、通勤通学時間中に動画を視聴するという方法で学習していました。

合格した感想

資格全般に言えることですが、資格自体にそこまでの意味があったとは思いません。

しかし、Googleの資格は勉強の過程で、かなり実践的なスキルを身に付けることができると思いました。

ぜひ、皆さんも取得にチャレンジしてください!

おまけ

記念品

GCPの資格に合格すると記念品をもらうことができます。

記念品の内容は、その時によるのですが、過去には

  • PCケース
  • リュック
  • パーカー
    などがありました。

いずれも限定品で、品質も高いので合格のモチベーションの一つになります!

ABC156C Rally

はじめに

問題

https://atcoder.jp/contests/abc156/tasks/abc156_c

方針

  • 全探索を行う
    • 集会の場所をjと仮定して、消費する体力の総和を求める
      • これを考えられる全てのjについて試し、最小値を取れば良い

        ポイント

  • 明らかに、1以上100以下の座標で集会を開くべきである。

コード

1
2
3
4
5
6
7
8
9
N = int(input())
X = list(map(int, input().split()))
costs = [] # 最後に最小値を取りたいので、結果を溜めておくリストを作成
for j in range(1,101):
cost = 0 # 各ループごとに初期化する
for x in X:
cost += (x-j)**2 # i番目の人が座標jで集会に参加するコストを、costに足しこむ
costs.append(cost) # リストに追加
print (min(costs)) # 最小値を出力

竸プロの「list(map(int, input().split()))」って何?

はじめに

Pythonで競技プログラミングする際に

1
list(map(int, input().split()))

のようなコードをよく見ると思います。

今回はこのコードの意味について解説します。

利用シーン

このコードは、数値のリストを標準入力から受け取る際に用います。

1
list(map(int, input().split()))

例えば、以下のような入力をとると

1
3 4 5
1
2
>>> list(map(int, input().split()))
[3, 4, 5]

数値のリストを得ることが出来ました。

以後も、断りがない限り同じように

1
3 4 5

を入力とします。

ステップを追って解説

input()

標準入力を文字列として受け取ります。

1
2
>>> input()
'3 4 5'

input().split()

splitで文字列を区切り文字で分割し、リスト化出来ます。

1
2
>>> input().split()
['3', '4', '5']

区切り文字を指定することもできますが、省略すると半角スペース改行で分割されるので、今回は省略しているわけです。

詳細は下記の解説をご参照ください。
Python splitの使い方まとめ

map(int, input().split())

高階関数mapは第一引数の処理を、第二引数のシーケンスの各要素に適用します。

つまり、文字列のリストの各要素を整数のリストに変換しています。

1
2
>>> map(int, input().split())
<map at 0x110c8f860>

何か、奇妙なものが得られました。
これはmapオブジェクトと呼ばれるものです。

これをリストに変換する必要があります。

list(map(int, input().split()))

リストへの変換はlist()とするだけでOK

1
2
>>> list(map(int, input().split()))
[3, 4, 5]

これで整数のリストを得ることが出来ました!

このようにlist(map(...))の構文はよく利用します。

下記の解説の中ではlamndaと組み合わせて使ったりもしています。

Python 内包表記とlambdaの書き方

おわりに

MENTAというサービスでプログラミング学習のサポートをしています。競技プログラミングについてもサポートできるので、ご興味がある方はぜひMENTAのDMでご連絡いただければと思います。

ARC056A みんなでワイワイみかん

はじめに

整数除算や剰余の学習ができる問題です。

問題

https://atcoder.jp/contests/arc056/tasks/arc056_a

方針

  • 場合分けを行う
  • 最後に、最小値を求める

    パターン

  1. 単品で買う
  2. セットで買う(みかんが余ってもOK)
  3. 端数が出ないようにセットを買い、残りは単品で買う

ポイント

セットでぴったり買い切れるケースをパターン3に含めると、実装が楽。
(単品で買う必要がある部分が0だった、と考える)

パターン1 単品で買う

これは簡単。

1
K * A

パターン2 セットで買う

整数除算を行い、1を加えたものにセット価格をかける。
これでは、セットでぴったり買い切れるケースを考慮できていないが、
それはパターン3に含める。

1
( K//L + 1 ) * B

パターン3 端数が出ないようにセットを買い、残りは単品で買う

先ほどの要領で、セットの小計を求め、

1
K //L * B

残りを単品で揃えれば良い。

1
(K % L) * A

コード

1
2
3
A, B, K, L = map(int, input().split())
ans = [K * A, ( K//L + 1 ) * B, K //L * B + (K % L) * A]
print (min(ans))