より良いエンジニアを目指して

1日1つ。良くなる!上手くなる!

.gitignoreはGitHub上で作ってしまえ

Windows10では、これから.で始まるファイルがWindowsでも作成できるようになるようです。

forest.watch.impress.co.jp

.で始まるファイルといえば、gitに欠かせないファイルである.gitignoreです。

ですが、GitHubにはCsharpのテンプレが用意されてないようです。

f:id:rimever:20190228102202p:plain

毎回C#リポジトリを作るときに手間取ります。

なので、.gitignoreファイルをローカル上の他のリポジトリから.gitignoreをコピーするというのがよく取る手段でした。

が、考えてみると、GitHub上でもファイルの新規作成・編集は出来るので、リポジトリ作成当初ならば自分一人だけしか触らないですし、直接新規追加しまえばいいような気がします。

f:id:rimever:20190228101756p:plain

この後、クローンしてローカルで開発すればいいですね。

ちなみに私がC#で使う.gitignoreは下記です。

C# の.gitignoreが存在しないようなので自分専用のを作成 · GitHub

ワインの種類にベイズ分析とLDAを試す

機械学習にも流儀(?)や哲学(?)があるようです。

ベイズ分類、勉強しましょう!

と後輩に言われたので勉強することにしました。

www.sogensha.co.jp

上記の本を読んだのですが、ワインのデータセットが紹介されていたので実際に、チャレンジしてみることにしました。

オープンデータセット(Open Data Sets) - データサイエンス

import pandas as pd
df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data', header=None)

qiita.com

上記の記事を参考にさせていただきました。

f:id:rimever:20190225215823p:plain

ふむ、でも、精度に目が行ってしまいますね。

具体的な方法は思い出せなかったので上記の記事を参考に次元圧縮して二次元化して、華を添えたいと思います。

PCAもありますが、今回は書籍「ベイズ統計学」で紹介されていたLDAを試してみます。

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn import preprocessing, decomposition
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis as LDA
 
df_wine_all=pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/wine/wine.data', header=None)
X=df_wine_all.iloc[:,1:].values
Y=df_wine_all.iloc[:,0].values
 
sc=preprocessing.StandardScaler()
sc.fit(X)
X=sc.transform(X)
 
lda = LDA(n_components=2)

X_transformed = lda.fit_transform(X,y)

%matplotlib inline
 
plt.figure(figsize=(10,10))
plt.scatter(X_transformed[:,0],X_transformed[:,1], c=Y)
plt.xlabel('LD1')
plt.ylabel('LD2')

PCA 主成分分析(次元圧縮)【Pythonとscikit-learnで機械学習:第21回】をベースに実装させていただきました。

f:id:rimever:20190225231640p:plain

実行結果は、実行する度に異なるようです。

自分なりにITエンジニアとしての英語を勉強してみました

ITエンジニアとして英語の勉強を始めたので、その話をします。

Google翻訳でいいのでは

ずっと、そう思ってました。

学生時代、私は英語が苦手で、特にリスニングが苦手でした。

何で、みんなわかるんだ?というくらいに、他の人が普通にわかるようなことが私には分からないのでした。

ただ、Google翻訳による機械翻訳だとうまく翻訳されないこともありますし、機械学習の論文を読むにはGoogle翻訳だけでは限界も感じました。

技術者としてステップアップするには英語が読める必要があるかなあと思った次第です。

目的

とある英語の勉強法の記事を見たときに、どんな英語が勉強したいのか、ということです。

それで勉強することも違ってきます。

私としてはITエンジニアとして英語が読めればいいので、リーディングだけをターゲットにしました。

自分なりの勉強方法を見つける

色々、英語の勉強方法を探し回って、試してみました。

英語のスマホゲーム

英語のクイズを解くスマホゲームなんてのもあります。

cocorosekai.jp

私、テレビゲームは好きなのですが、スマホゲームの仕組みがどうも好きになれず、1日熱中した後、遊ばなくなってしまいました。

知ってる本を英語版で読む

paiza.hatenablog.com

上記の記事で紹介されていた方法です。

で、リーダブルコードの英語を買ってみました。

ですが、海外から発送されるため、いつまで経っても届かず(涙)

Kindleで買うことをお勧めします。

日本で読んだ技術記事を、英語で読み返すのであれば、POSTDというサイトがおすすめです。

postd.cc

英語の記事を、日本語に翻訳して紹介しているサイトです。

紹介されている記事の中で気に入ったものを、英語の記事を読み返すというのはいかがでしょうか。

リーディングの本を買う

毎日、隙間時間があるので、そのときに1ページ分程度の英文を読めるといいなということで本屋で、自分に合いそうな本を見繕って行きました。

publications.asahi.com

この本を今読んでいるのですが、いい感じです。

やっぱり、どんな勉強法がベストかではなく、その勉強法を続けられることが大事なんじゃないかなーと思ってます。

実践あるのみ!

あとは勉強するだけでなく、並行して肝心の英語の技術系記事や機械学習の論文にチャレンジしていくのも大事です。

ただ、勉強しただけではダメで、実践して、勉強法について見直していくことも必要だと思います。

結果は

まだ一ヶ月程度ですし、多少は良くなったんじゃないかなと、いう程度です。

特に英語に対して、読もうとするようにはなったとは思います。

英語は学校の必修科目ですし、全く読めない訳ではないです。

完全に理解できないし、時間もないし面倒だから放り出してしまう英語アレルギーを取り払うことも大事なのかなと思ったりします。

C#を手軽に書いて動かしたい時に.Net Fiddle

C#にはVisual StudioというIDEがあるとはいえ、試しにこんなコードを書いてみたいという場合にはプロジェクトを新規作成したりしなければならないなど、手間です。

PaizaでもC#には対応してますが、言語に最適化していないため物足りない。

StackBlitzとかScatieのように、C#専用でOnline上で動かせるエディタないの?

と探したら、見つけたのがこれ。

C# Online Compiler | .NET Fiddleです。

開いて、目を引くのはNuGet Packageでしょう。

f:id:rimever:20190223222807p:plain
NuGet Package

いいですね。.NET言語に特化したエディタならではでしょう。

CsvHelperを使って、下記のようなコードを書いてみることにしました。

using System;
using System.Net;
using CsvHelper;
using System.Collections.Generic;
using System.Text;
using System.IO;

public class Program
{
    public static void Main()
    {
        string url = "https://raw.githubusercontent.com/chainer/chainer/master/examples/glance/mushrooms.csv";
        WebClient client = new WebClient();
                 string html = client.DownloadString(url);
        using(var textReader = new StringReader(html)) {
            using(var reader = new CsvReader(textReader)) {
                while (reader.Read()) {
                                   var dictionary = reader.GetRecord<dynamic>() as IDictionary<string, object>;
                                           var stringBuilder = new StringBuilder();
                                           foreach (var pair in dictionary)
                      {
                        stringBuilder.Append(pair.Key + "->" + pair.Value + ",");
                      }
                                   Console.WriteLine(stringBuilder.ToString());
                }
            }
        }
    }
}
  1. 直接、Web上のcsvファイルにアクセス
  2. 取得した文字列をCsvHelperが引数に取れるStringReaderへ変換
  3. CsvHelperでマッピングなしの読み込み
  4. コンソール出力

というコードです。

書いていて気づいたのですが、.NET Framework v4.5であること。これは変更できないようです。

最新版のCsvHelperがバージョン依存により、動作しませんでした。

f:id:rimever:20190223231400p:plain

その他の機能

  • アカウント作成はTwitter/Facebook/Gmail
  • VB.NETのコードに変換が可能
  • F#も実は書ける
  • Fiddleとして保存可能
  • MVCなんてのも書くことができる。

機能は豊富ですし、良いのですが、WebClientクラスの名前空間なんて覚えてるわけないので、自動的に補完してくれないのがストレス。

それくらいであれば、Visual Studio使えよ、なのかも。

共通ライブラリは、自動的にサジェストして補完してくれるといいなーとは思いました。

JupyTextを試す

下記のJupyTextが紹介されている記事に出会ったので、試してみました。

qiita.com

JupyTextにするメリット

  • Jupyter Notebookで実装したファイルが.pyファイルにも変換されるため、いちいちpyファイルに変換する必要がない
  • Jupyter Notebookのipynbより.pyファイルの方が差分がチェックしやすい

JupyTextの導入

jupytextをインストールします。

pip install jupytext

その後、jupyter notebookを起動します。

jupyter notebook

MetadataをEditしてもいいとは思いますが、File-Jupytext-Pair Notebook with light Scriptにチェックを入れます。

f:id:rimever:20190221234634p:plain

すると、ipynbとペアとなるpyファイルが生成されるようになります。

f:id:rimever:20190221235040p:plain

他にもいくつかありますが、詳細は例によって公式ドキュメントを見るのがベストです。

Visual Studio CodeやPyCharmなどで動かせるようにするのであればpercentscriptです。

%%を使ってセルを区切られた形式で。

JupyTextの用途としては、Jupyter Notebookで試行錯誤した実装を、.pyファイルに変換して正式なプロダクション(製品)のコードに導入するために使うんじゃないかなーと思ってます。

と言っても、私は今も、この先も試す機会はなさそうなのですが(涙)

そんなチャンスをもらえたらいいのですが…。

その名は「Ring UI」JetBrainsのReactコンポーネントを試してみる

Ring UIはJetBrainsのReact Componentです。

以前Dataloreというのを本ブログで紹介させていただきましたが、JetBrainsもIDEだけではなく、色々なプロダクトを開発してますね。

YouTrackやTeamCityで見かけるあのJetBrainsのコンポーネントを使うことができます。

JavaScriptのReactフレームワークに載せる必要がありますが、あのコンポーネントをこの手で使うことが出来るというのであれば使ってみたくなるというものです。

Getting Started — Ring UI

導入

ダウンロードにはnpm経由で行います。

公式に書いてありますが、Node.js経由で実行します。

空のフォルダを用意して

npm install -g yo @jetbrains/generator-ring-ui

yo @jetbrains/ring-ui

するとテンプレートが生成されます。

何をしているのかよくわからなかったのですが、yeomonというWebアプリケーションのベースを生成するツールを使ってRingUIのテンプレートを生成しているようです。

ですので、空のフォルダで何も用意せずにはじめた方がいいです。中途半端にindex.htmlとか用意した状態でコマンドを叩いたら、わかりにくくなってしまいました。

※StackBlitzでも出来そうな気もしましたが、うまく行きませんでした。

その後、

npm start

で、作成されたテンプレートを確認します。

f:id:rimever:20190219071909p:plain

実践

公式サイトを真似て実装していきました。

はじめにやったのはReact TutorialをRingUIでデコってみました。

f:id:rimever:20190219075308p:plain

テーブル

Webサイトのライブラリとしてポイントは何かと考えました。

その中では、やはりテーブルかなあと思います。

Table — Ring UI

ソートなども出来そうですし、なかなか機能は揃ってます。

ただ、いざ使おうとするとハードル高そうです。

おまけ:npmのインストールについて

Macの場合はHomebrewを使うべきでした。出なければ下記の問題に悩まされます。

npmでpermission deniedになった時の対処法[mac] - Qiita

nodebrewを使う方法も案内されてますが、私はnode.jsのヘビーユーザーではないので普通に

brew install node

とコマンドを叩きました。

node.jsのバージョンを管理したくなったらnodebrewを入れようかと思います。

qiita.com

CsvHelperでマッピングなしでパースして読み書きしたい時

C#csvをパースする方法は、いくつかありますが特に制約が無いのであればCsvHelperがオススメです。

https://github.com/JoshClose/CsvHelper

VisualBasic.TextFieldParserより遥かに優れた読み込み速度を期待できます。GitHub - rimever/CsvParserBenchmarks: Csvのパーサーライブラリの比較検証のためのリポジトリです。

ただ、このCsvHelperはマッピングあり前提で作られているせいか、やや柔軟性に欠けます。

そこでマッピングなしで読み書きする方法を紹介します。

マッピングなしの読み込み

Dicitonary型に変換する方法

下記の記事で紹介されてますが、

stackoverflow.com

            using (var reader = new CsvReader(new StreamReader(csvFilePath, encoding)))
            {
                while (reader.Read())
                {
                    
                var dictionary = reader.GetRecord<dynamic>() as IDictionary<string, object>;
                var stringBuilder = new StringBuilder();
                foreach (var pair in dictionary)
                {
                    stringBuilder.Append($"{pair.Key}->{pair.Value},");
                }
                Console.WriteLine(stringBuilder.ToString());
                }
            }

とします。

ヘッダーなしの場合

CsvReaderにヘッダーなしの設定を渡せばOKです。

// ヘッダーなしを設定に渡す
using (var reader = new CsvReader(new StreamReader(csvFilePath, encoding))
            {
                Configuration = { HasHeaderRecord = false}
            })
            {
                while (reader.Read())
                {
                    
                var dictionary = reader.GetRecord<dynamic>() as IDictionary<string, object>;
                var stringBuilder = new StringBuilder();
                foreach (var pair in dictionary)
                {
                    stringBuilder.Append($"{pair.Key}->{pair.Value},");
                }
                Console.WriteLine(stringBuilder.ToString());
                }
            }

すると

Field1->p,Field2->x,Field3->s,Field4->n,Field5->t,Field6->p,Field7->f,Field8->c,Field9->n,Field10->k,Field11->e,Field12->e,Field13->s,Field14->s,Field15->w,Field16->w,Field17->p,Field18->w,Field19->o,Field20->p,Field21->k,Field22->s,Field23->u,

のような辞書型となります。

Context.Recordから取得する

これでいいとは思いますが、ヘッダーあり+辞書型で取得する場合は、カラム列の並び順に取得できない(カラム列の名前順になる)という問題点もあります。

もう一つの手段としては、CsvReaderのContext.Recordプロパティから取得するという方法です。

純粋に、string配列ですのでカラムの何番目という取得方法であればシンプルに扱えます。

            using (var reader = new CsvReader(new StreamReader(csvFilePath, encoding))
            {
                Configuration = { HasHeaderRecord = false}
            })
            {
                while (reader.Read())
                {
                    Console.WriteLine(string.Join(",", reader.Context.Record));
                }
            }

マッピングなしの書き込み

List<List<string>> lists = new List<List<string>>
            {
                new List<string>() {"a" + Environment.NewLine + "b", @"c""d", "e"}, new List<string>() {"e", "f", "g,h"}
            };
            using (var writer = new CsvWriter(new StreamWriter(path,false,Encoding.UTF8))
            {
                Configuration =
                {
                    ShouldQuote = (s, context) => true
                }
            })
            {
                foreach (var list in lists)
                {    
                    writer.WriteField(list.ToArray());
                    writer.NextRecord();
                }
            }

その他

職場で聞いた話では、CsvHelperは読み込みが厳しいので、緩い書き方だと失敗することがある。

修正履歴

  • (2/20)書き込みについても記載し、タイトルを修正しました。