Monthly Archives: 10月 2017

2017-10-11

コードレビューを怖がっていた新卒エンジニアが始めた対策

この記事の概要


  • 新卒エンジニアのY.Oの自己紹介
  • 入社後苦労した事
  • コードレビューとは何か
  • コードレビューの回数を減らすために行っている対策。

ご挨拶


こんにちは! TAXELチームに配属された新卒エンジニアのY.Oです!
今回は、私が入社してから味わったコーディングの苦労とその対策について、というテーマの記事です。
が、その前にちょっとだけ、私の自己紹介をさせてください。

私は現在、TAXELというレコメンドエンジンの開発を行っています。
レコメンドエンジンとは何か簡単に説明すると、
「この記事を見た人にはこの記事もオススメです」 といった機能を提供する仕組みです。
私はそんなTAXELの管理画面をRuby on Railsを使って改善するお仕事をしています。

今でこそ、会社に入ってエンジニアとしてお仕事をさせて頂いていますが、
入社まではあまり開発作業をした事はありませんでした。

大学時代にやった事と言えば…

  • プログラミングの授業の受講
  • 後輩へのプログラミング指導
  • 研究の一環としてのプラグインの開発
  • 長期休暇中のスマホアプリ開発(ダウンロード3桁レベルの小規模なもの)
  • アドパートナーズのインターンシップ(内定承諾後の半年程度)

といった内容で、プログラミングの授業でS評価は貰えるものの、
開発の経験が浅いことに加えて、集団開発の経験も無いため、
入社してからは苦労の連続でした。

入社して苦労した事


いざ入社してみると…

  • Gitむずかしい…リポジトリとかブランチとか何が何やら分からない…
  • Ruby on Railsってなんかスゴイけど勝手にやってくれ過ぎ?!
  • 「とにかく動いて自分が読めりゃいいんだよ!」なコーディングをしてきたツケが!
  • アドテクの講義、概要を追っていくので精一杯…
  • 設計内容をまとめた仕様書…他の人が読んで解るように書く…って言われても、
    一体どこまで書けばいいんだろう…?
  • プロダクトが複雑すぎて仕様や使い方が覚えきれない!
    影響範囲の検討なんてひたすらコードを読んで紐解かないと分からない!
  • サーバー関係触ったこと無いんだけれど…
    踏み台サーバーを経由してSSHでログインするって何のこと?
  • コードレビューこわい
  • etc…

とまぁ、当然の事ながら分からない/出来ない事だらけでした。
中でも特に怖かったのが、コードレビューという作業です。

コードレビューってなんぞや?


コードレビューとは、作ったコードを別の人に見てもらい、
おかしなところが無いか確認する作業の事です。
(学生の方は、論文査読のソースコード版、と考えると分かりやすいかもしれません)

個人での開発や学校の授業では意識する事は少ないかと思いますが、
仕事としてコーディングをする際は、可読性が高く安定して動くコードを書かなければなりません。
そこで、コードレビューを通じて、より良いコードがプロダクトに追加されていく仕組みにしている…とのことです。

このコードレビュー、独学でプログラミングをやってきた私にとっては鬼門で、
かなりの回数の指摘を受けてしまっています。

いまパッと思い出せるだけでも…

  • Returnの直前で条件式使ってBoolean返すなら、その条件式を返却した方がいいですよ!
  • ネストが深すぎますよ!
  • 関数の中身は直ってるけど、コメントが前のままだよね!
  • この仕様だと、~の処理の時に問題が起こるよ!
  • 関数名が処理内容を適切に表現してないよ!
  • etc…

などなど…シンプルなものだけを例として挙げましたが、
実際は他にも大量に指摘され何度も何度も再レビューをする事になってしまいました。

レビューをして頂ける事はとてもありがたい事なのですが、何度も繰り返していると、
次の失敗が怖くなったり、レビュアーへの申し訳無さでいっぱいになったり…
徐々にレビューへの苦手意識が芽生えるようになりました。

対策


とはいえ、苦手だからといって逃げる訳にも行きません。
先輩からのアドバイスや書籍/ネットで調べた情報を元に、徐々に対策をするようにしています。
同じような立場の人に少しでも役立てられたらと思い、私がやってきた対策を書いていこうと思います。

1. 指摘された点はちゃんとメモを取ろう!

エンジニアに限らず誰もがやる事だと思いますが、何より重要な事だと思います。
レビューの際どの箇所で指摘を受け、その理由が何だったかを記録する事で、
後で見返せるだけでなく、書くことで記憶にも残りやすくなります。

私の場合は、会社で扱っているWikiの自分のページの中に、
指摘された内容と、その時の修正前/修正後のコードをまとめ、
以降のレビュー前に確認する自分だけのチェックリストのようなものを作っています。

2. コーディングの参考になる本を読んで勉強しよう!

私は個人で開発を行う際、自分さえ分かれば大丈夫というコードを書いてきた為、
チームの誰にとっても理解しやすいコードを書く習慣が身に付いていませんでした。

そんな状態ではいくら自分の頭で考えたところで、良いコードを考えつく訳もありません。
そのため本を通して先人の方のやり方を参考にし、コーディングスキルやチーム開発における重要な考え方を学びました。

参考になった本をいくつか、ここで紹介させて頂きます。

リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック (Theory in practice)

(引用元:O’Reilly Japan「リーダブルコード――より良いコードを書くためのシンプルで実践的なテクニック」https://www.oreilly.co.jp/books/9784873115658/”)

読みやすいコードを書くためのテクニックを凝縮した本になります。
既にチーム開発を体験している方は当然の事ながら、
私のような独学でやってきたプログラマーにもオススメな書籍になっています。

理解しやすいコードとはどんなものなのか?といった内容から、
名前の付け方のコツやコメントに書くべき内容などの、
実際に理解しやすいコードを書くために必要な技術や知識が山ほど書いてあります。

言語に依らず、どんなエンジニアにとっても必要な考え方が学べますので、
エンジニアになってまず何を読めば良いか分からない、
という方はとりあえずコレを読んでおけば良いのではと思います。

プログラマが知るべき97のこと

テスト

(引用元:O’Reilly Japan「プログラマが知るべき97のこと」https://www.oreilly.co.jp/books/9784873114798/”)

こちらは、技術というよりもプログラマとしての考え方を学べる書籍となっています。

(実は こちら で全て無料で公開されています。)

まだまだ経験不足で理解できない内容もありましたが、
今でも必要性が理解できて、記憶に残るエッセイも数多くありました。

ネットから無料で読むことも出来るので、通勤時などに少しづつ読み進めています。

3. 静的コード解析ツールで、目視では見逃しがちなミスを捕まえよう!

自分ではとても気をつけているつもりでも、小さなミスを0にするのは中々難しいものでした。
最終的には正しい書き方を覚え、ミス無く書けるようにする…というのがベストだとは思うのですが、
慣れるまでの間、何度も何度もミスを重ねてしまうのは悲しいので、
静的コード解析ツールを導入しました。

静的コード解析ツールというのは、コードを実行せずにコード中の悪い点を見つけてくれるツールです。

例えば、下記のような規約違反だらけのコードがあったとすると、

このように問題点を指摘してくれるツールです。

静的コード解析ツール以外にも、規約に沿った形に自動整形してくれるプラグインや、
過去のGitのCommitと現在のコードを比較するプラグインなど、
業務の効率化が図れるツールは積極的に導入するようにしています。

4. コードにコメントを書き、自分もメンバーも分かりやすいコードに!

コメントが必要な全てのコードにコメントが書かれていれば良いのですが、必ずしもそうではありません。
TAXELのコードの中にも、名前やコードだけでは意図が掴みづらいにも関わらず、
コメントが書いていないコードが多々ありました。

その為、コードを読んだ後は理解した内容をコメントで残すようにしています。
当然の事ながらコメントを書くべきではない箇所もありますので、
その点は気を付けなければなりませんが、
自分やチームの助けになるだけでなく、コメントにまとめる事で理解が進むように感じています。

5. キレイなコードを読み、参考にしよう!

成長する為には、上手い人のやり方を真似するのが近道である場合が多いと思うので、
一度キレイなコードを読もうと考えました。

TAXELのコードも、私から見ればキレイなコードではありますが、
それ以上にキレイなコードを見てコーディングの参考にする為に、
オープンソースのコードを読んでみる事にしました。

先輩にオススメを聞いたところMastodonが良いと聞きコードを読んでみたのですが、
とてもシンプルで読みやすく書かれており、キレイなコードを書く上での勉強になりました。

まとめ


今回の記事では、私が入社後体験した苦労や、その中でも最も苦しかったコードレビューへの自分なりの対策を書かせて頂きました。
私なりの対策ですのでより良い方法もあるかと思いますが、ほんの少しでも参考になったら嬉しいです。

上記の対策をしても尚、まだまだレビューを通すのに時間が掛かる毎日ですが、
一日でも早く成長してコードレビューやその他業務をミス無くこなせるように頑張ります!

2017-10-04

続DirectX12で遊んでみた

お久しぶりですNKのS.Tです。ちょうど1年ぶりの投稿となります(その間に社名が2回変わったのは秘密)
前回は三角形の描画まででしたので今回はテクスチャーを追加してみます。

■環境

OS: Windows 10
IDE: Visual Studio 2017 Community
SDK: Windows 10 SDK (10.0.15063.468)

■初期設定

IDEをVisual Studio 2017に変更しましたが参照設定等は前回と同じです。
ビルドできない場合はSDKが足りないので、Visual Studio 2017のインストーラーからSDKをいろいろ入れてみてください(適当)

■コーディング

今回もわかりやすさ重視でクラス等は作成せず、main.cppのみで進めます。
インデックスバッファや定数バッファも作成しないので、おそらく最短のテクスチャー描画プログラムではないでしょうか。
以下、ソース変更点です。

テクスチャーのみを表示するので色データを削除してテクスチャーのUV座標を追加します。


一枚絵のビットマップを表示したいので三角形から四角形に変更します。


空のルートシグネチャを作成していた部分にテクスチャーとサンプラーを追加します。

 

テクスチャー用に用意したビットマップを読み込み初期化を行います。
簡易読み込みのためアルファ値には対応していません。

 

描画部分でテクスチャーをレジスタに設定します。

 

最後にHLSLの変更点です。
ここでも色データを削除してテクスチャー関連を追加しています。

 

実行するとウィンドウが表示され中央にビットマップが表示されているはずです。
前回と同様にD3D12CreateDeviceが失敗する場合はビデオカードがDirectX12に対応していないのでg_useWarpDeviceをtrueにしてみてください。
WARPデバイス(ソフトウェア)を使用するようになりますのでまず動くと思います。

ソースはこちらからダウンロード出来ます。

Windows10と同時に出てきたDirectX12は登場から2年経ちましたが、amazonで書籍を検索してみたところ英語版が1冊・日本語版は0冊でした…
一体誰に需要があるのか謎で本当に遊んでみた記事になってしまいましたが、また何かできたらいいなと思っています。

2017-10-02

機械学習の実践入門ーRandom Forestの要約

皆さん

こんにちは、GMOアドマーケティングのS.Rです。

今回はよく使われる機械学習のアルゴリズムRodomForestを皆さんへ紹介致します。

この記事を理解するには、中学レベルの数学とPythonの基本知識が必要です。

Random Forestは2001年にLeo BreimanさんからDecision Treeを発展して提案されたアルゴリズムです。それでは、Random Forestを理解していただくために、まずはDecision Treeについて紹介いたします。

1 Decision Tree(決定木)

機械学習の分野において、Decision Tree(決定木)は予測モデルです。ある事項に対する観察結果から、その事項の目標値に関する結論を導きます。内部節点は変数に対応し、子節点への枝はその変数の取り得る値を示します。 葉(端点)は、根(Root)からの経路によって表される変数値に対して、目的変数の予測値を表します。Decision Treeの学習は、元となる集合を属性値テストに基づいて部分集合に分割することにより行うことができます。 この処理は、すべての部分集合に対して再帰的に繰り返されます。 繰り返しは、分割が実行不可能となった場合、または、部分集合の個々の要素が各々1つずつの分類となった段階で終了します。決定木、2017年8月15日、ウィキペディア日本語版、https://ja.wikipedia.org/wiki/%E6%B1%BA%E5%AE%9A%E6%9C%A8

例えば、ある人(山田さん)はゴルフが好きで、時々ゴルフ場へ出かけます。以下の表に山田さんが過去一ヶ月間にゴルフ場へ行った履歴と天気、風、週末などの情報を合わせて集計しました。この情報でDecision Treeのモデルを訓練して今日山田さんゴルフ場へ行くかを予測します。

表1:山田さんのゴルフカレンダー

まずDecision Treeを学習します。最初はRoot Nodeに天気でデータを分割します(図1)。分割された結果みると天気が晴れのときに山田さんはゴルフへ行く確率は50%,雨の時は47%です。天気だけで考えると、山田さんがゴルフへ行くかどうかの判別は難しいです。

図1:天気でデータを分割

次に、分割されたデータをさらに「風」の情報で分割します。図2は分割された結果です。分割された結果からみると雨が降ってるかつ風が強い時に山田さんはゴルフへ行かず、晴れてるかつ風が弱い、雨かつ風が弱い時にゴルフへ行く可能性が高いことがわかります。ただし、風が強いかつ晴れの時に山田さんがゴルフへ行くかどうかはまだ判別が難しいです。

図2:風でデータを再分割

 最後に、週末かどうかを特徴として、もう一度教師データを分割します(図3)。分割された結果はDecision Treeの学習した結果です。分割された結果を見ると、晴れの週末に風が強ければ山田さんはゴルフ場へ行く可能性が高いことがわかります。また、晴れの平日に風が強ければ山田さんはゴルフ場へ行かない結果となりました。そこで、山田さんがゴルフ場へ行くかどうかを予測するDecision Treeを学習しました。このDecision Treeで天気、風、週末かどうかなどの情報を分ければ 山田さんがゴルフ場へ行く確率を予測できます(表2)。

図3:Decision Tree

表2:山田さんゴルフ場へ行く確率

2 Random Forest

Decision Treeはアルゴリズムとしてすごく理解しやすいですが大きな欠点があります。その欠点は「Over Fitting」(Overfitting,( 2017/08/24 16:08). In Wikipedia: The Free Encyclopedia. Retrieved from https://en.wikipedia.org/wiki/Overfitting)です。これは、Decision Treeのモデルを訓練する時に教師データのノイズに対する処理を考えてないことが原因です。そのため、Decision Treeのモデルを訓練する時に正解データだけではなくノイズも含めて学習してしまうため、この学習で得られたDecision TreeのモデルはBiasが高いです。つまり、学習したモデルは教師データに対しては高い精度を持つが、実際に運用する際には精度が悪くなるということです。

Random Forestはこの欠点を改良しました。 解決方法はモデルを学習する前に教師データに ランダム性を入れて教師データのSubsetを作り、各SubsetのノイズのBiasを差し引きます。全体で2つのステップがあります。

  1. 教師データを復元抽出し、N分の新しいデータセットを作成します。よく使われる抽出されたデータセットのサイズはもとのデータセットサイズの平方根です。
  2. 抽出された新しいデータセットでDecision TreeをN本訓練します。

図4:Random Forestの訓練

訓練されたRandom ForestのモデルにDecision TreeがN本あります。予測する時に一つのCaseに対してDecision Treeの予測結果をN個出せます。Random Forestの結果はこのN個結果から”Vote”して点数が高い方で決まります。

3 Merit・Demerit

Random ForestのMerit・Demeritは表3の通りです。

表3:Random ForestのMerit・Demerit

4  Scikit-learnで検証する

最後はPythonの機械学習ツールScikit-learnで、irisの分類問題に対してRandom Forestを試してみましょう。irisの分類問題についてはこちらをご参考下さい。

Scikit-learn、またはPythonをインストールしていない人はこちらを参考してインストールしてください。

Step 1: Library Import

まずScikit-learnのlibraryをimportします。

Step 2: Download Training Dataset

irisの教師データをダウンロードします。

irisの教師データをダウンロードされたデータを確認する為に最初の五つデータをprint outします。ダウンロードに成功すれば表4ような結果が得られます。

sepal length (cm) sepal width (cm) petal length (cm) petal width (cm) species
0 5.1 3.5 1.4 0.2 setosa
1 4.9 3.0 1.4 0.2 setosa
2 4.7 3.2 1.3 0.2 setosa
3 4.6 3.1 1.5 0.2 setosa
4 5.0 3.6 1.4 0.2 setosa

表4:Random Forestの教師データ

Step 2: Training と Test を分けます

irisの教師データからRandomに80%のデータを抽出しTraining Dataにします。残る部分はTest Dataにします。

Step 3: Random Forestのモデルを訓練します

Random Forestのモデルを訓練します。 n_estimatorsは木の数です。n_jobsは並列に実行するjob数です。

Step 4: モデルの精度を計算します。

Step 2に抽出されたTest Datasetでモデルの精度を計算します。計算に成功すれば表5ような結果が得られます。

Predicted Species setosa versicolor virginica
Actual Species
setosa 13 0 0
versicolor 0 5 2
virginica 0 0 12

表5:モデルの精度

5 Future Reading

今回はRandom Forestについて紹介しました。いかがだったでしょうか。

Random Forestの原理をさらに深く理解したい方は下記の論文とビデオをぜひ参考してください。

  1. Breiman,Leo. (2001). Random forests. Machine learning, 45(1), 5-32.
  2. Thales,Sehn Körting(2014).How Random Forest algorithm works,http://www.youtube.com/watch?v=Vja83KLQXZs.

Random Forestの実装については下記のブログをぜひ参考してください。

  1. The Apache Software Foundation.(2017), Random forest regression,spark.apache.org.
  2. Raja Iqbal.(2015/02/24).Tutorial: Creating a random forest regression model in R and using it for scoring,Data Science Dojo.