SQL(Oracle)で「NOT IN」が効かないときの対処方法

NOT INを使っても期待した結果が返ってこない

久々にSQL書いたら軽くはまったのでメモ。


COLUMN_NAME列には基本的にはnull、HOGEの2つしか入っていない。
HOGE」が入っていない行を取り出したいので以下のようにした。

SELECT *
FROM TABEL_NAME
WHERE COLUMN_NAME NOT IN 'HOGE'
SELECT *
FROM TABEL_NAME
WHERE COLUMN_NAME <> 'HOGE'

これを実行すると本来COLUMN_NAME 列に「HOGE」がない(nullが入っている)行が出てきてほしいが、どちらも何も出てこない。
どうやら「COLUMN_NAME 」にnullがある場合、これは機能しないらしい(上司談)。


ということで逆にNULLだけを取り出してみる。

SELECT *
FROM TABEL_NAME
WHERE COLUMN_NAME IS NULL

まぁ、これはうまくいく。


う~ん。基本的にはnullとHOGEしか入らないはずだけど今後何かしらの変更があったら…と思って変えてみた。

SELECT *
FROM TABEL_NAME
WHERE (COLUMN_NAME IS NULL OR COLUMN_NAME <> 'HOGE')

これだとFUGAとかが入っていても「COLUMN_NAME <> 'HOGE'」の方で引っかかるのかな?




ところで、OracleではNULLと空白は同じ扱いだそうだ。
SQLの観点から「Oracle Database」「PostgreSQL」「MySQL」の特徴を整理しよう! | アシスト

Pythonではじめる機械学習【2章(2.1-2.2)】

Chapter 日付
2-1 4/5
2-2 4/6

2.1 クラス分類と回帰

・教師あり機械学習は以下の2つに大別できる
  ・クラス分類(classification)
     ・2クラス分類(binary classification)    →メールのスパム判定
     ・多クラス分類(multiclass classification)  →1章のアイリスの品種判定
  ・回帰(regression)  →連続地の予測。学歴、年齢、住所から年収を予測
      回帰は「量」を予測する。

 2つの差は出力に対して連続性があるかどうか


2.2 汎化、過剰適合、適合不足

汎化(generalize)
モデルが未見のデータに対して正確に予測出来ている場合、訓練セットを用いてテストセットに対して汎化できている、という。
訓練、テストセットに共通した性質を持っていても汎化できていない場合がある
→モデルが複雑すぎる場合、訓練データに大してはいくらでも正確な予測が出来るようになってしまう!(具体例は参考書で)


過剰適合(overfitting)
 持っている情報の量に比べて過度に複雑なモデルを作ってしまうこと。
 訓練セットの小尾kの特徴にモデルを手企業しすぎると発生する。汎化できないモデルになるので注意!
適合不足(underfitting)
 逆に単純すぎるモデルを作ってしまうこと。


適切なモデルの複雑さであるスイートスポットを見つけよう!


・モデルの複雑さは、訓練データセットのバリエーションに左右される。
・バリエーション豊富だと過剰適合を起こさずに複雑なモデルを作成出来る。
・単純にデータポイントが増えればバリエーションも増えるので、より複雑なモデルが出来るが似ているものを集めてもダメ。
・教師あり学習では、より多くのデータを用い、適度に複雑なモデルを用いると驚くほどにうまくいく場合があるので、場合によってはモデルをどうにかするよか、データを増やすことが大切だったりもする。

Win10のPowershellでstatsmodelsをpip installしようとしてエラー

朝、Jupyterといちゃついているとき、Powershellで以下のようにしてもうまくいかない。

> pip install statsmodels

...

Please install Cython or download a source release of statsmodels.


とりあえず言われたとおりに。

> pip install cython
> pip install statsmodels

う~ん、結果変わらず。

じゃ、

> pip install git+https://github.com/statsmodels/statsmodels.git

...

error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visualstudio.com/visual-cpp-build-tools


...


え~もうめんどくさい…。。



別に仕事には関係無いこと書いてるし、コードだけ書いて自宅のMacで実行することにしたのであった。



おしまい。

【固定記事】まとめのまとめ

本気ではじめるiPhoneアプリ作り〜黒帯エンジニアがしっかり伝える基本テクニック〜

本気ではじめるiPhoneアプリ作り〜黒帯エンジニアがしっかり伝える基本テクニック〜


Pythonによるクローラースクレイピング入門 設計・開発から収集データの解析まで

Pythonによるクローラー&スクレイピング入門

言語処理100本ノック with Python【第2章】

No 日付 学んだこと
10 4/9 with open()、wcコマンド、encoding="utf-8_sig"
11 4/9 -
12 4/9 -
13 4/9 -
14 4/10 -
15 4/10 readlines
16 4/11 -
17 4/12 set()
18 4/12 sort()
19 4/12 pprint、setdefault()

第2章: UNIXコマンドの基礎

研究やデータ分析において便利なUNIXツールを体験します.これらの再実装を通じて,プログラミング能力を高めつつ,既存のツールのエコシステムを体感します.

10. 行数のカウント

行数をカウントせよ.確認にはwcコマンドを用いよ.

素人の言語処理100本ノック:10 - Qiita
Man page of WC

参考にしているQiita記事を見てmanコマンドを打ってみたがPowershellでは出なかった。家のMacが恋しい。。。
まぁぐぐればいいんだけど。

解法1

fname = 'hightemp.txt'
count = 0

with open(fname, encoding="utf-8_sig") as hightemp:
    for line in hightemp:
        count += 1

print(count)
# 24

リストとかでfor回してるとenumerateとかでループカウント(インデックス)を取得できるけど…。
すごく単純だし1行でかっこよく書きたいけどなさげ。。
pythonの内包表記について - Qiita

解法2

後から追加した解法

fname = 'hightemp.txt'
with open(fname, encoding="utf-8_sig") as hightemp:
    lines = hightemp.readlines()

print(len(lines))
open
open(filename, mode) 

open()はfileオブジェクトを返す。

mode
r 読み込み専用
w 書き込み専用(同名の既存のファイルがあれば消去される)
a ファイルを追記用に開く。書き込まれた内容は自動的にファイルの終端に追加される。
r+ 読み書き両用

mode 引数は省略可能で、デフォルトは 'r'。
withブロックを用いることでclose()を書かなくても済む。こっちが推奨されている。
7. 入力と出力 — Python 3.6.5 ドキュメント


エンコード

以下のようなエラーが出るので、エンコード(バイナリデータをテキストに変換)してあげなくちゃいけない。

UnicodeDecodeError: 'cp932' codec can't decode byte 0x8c in position 8: illegal multibyte sequence

WindowsでCP932(Shift-JIS)エンコード以外のファイルを開くのに苦労した話 - Qiita

UNIXコマンド版

wc --line hightemp.txt

11. タブをスペースに置換

タブ1文字につきスペース1文字に置換せよ.確認にはsedコマンド,trコマンド,もしくはexpandコマンドを用いよ.

素人の言語処理100本ノック:11 - Qiita

解法

fname = 'hightemp.txt'

with open(fname, encoding="utf-8_sig") as hightemp:
    for line in hightemp:
        print(line.replace('\t', ' '), end='')

12. 1列目をcol1.txtに,2列目をcol2.txtに保存

各行の1列目だけを抜き出したものをcol1.txtに,2列目だけを抜き出したものをcol2.txtとしてファイルに保存せよ.確認にはcutコマンドを用いよ.

素人の言語処理100本ノック:12 - Qiita

解法

fname = 'hightemp.txt'

with open(fname, encoding="utf-8_sig") as hightemp, \
     open('col1.txt', mode='w', encoding="utf-8_sig") as col1, \
     open('col2.txt', mode='w', encoding="utf-8_sig") as col2:
    for line in hightemp:
        cols = line.split('\t')
        col1.write(cols[0] + '\n')
        col2.write(cols[1] + '\n')

Jupyter上で開くと一番上に赤ぽちあるのなんでだろ。
最初エンコードするの忘れてたらメモ帳では開けたけど、Jupyterでは開けなかった。
f:id:saneeeatsu:20180409165128p:plain



13. col1.txtとcol2.txtをマージ

12で作ったcol1.txtとcol2.txtを結合し,元のファイルの1列目と2列目をタブ区切りで並べたテキストファイルを作成せよ.確認にはpasteコマンドを用いよ.

素人の言語処理100本ノック:13 - Qiita
Pythonにおける「空白文字」についてまとめてくださってる。ありがたひ。

解法

with open('col1.txt', encoding="utf-8_sig") as col1, \
     open('col2.txt', encoding="utf-8_sig") as col2, \
     open('merge.txt', mode='w', encoding="utf-8_sig") as output:

    for col1, col2 in zip(col1, col2):
        output.write(col1.rstrip() + '\t' + col2.rstrip() + '\n')






100本ノック…疲れてきた!!!





14. 先頭からN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち先頭のN行だけを表示せよ.確認にはheadコマンドを用いよ.

素人の言語処理100本ノック:14 - Qiita

解法

fname = 'hightemp.txt'

n = int(input('>>> N : '))

with open(fname, encoding="utf-8_sig") as hightemp:
    for i, line in enumerate(hightemp):
        if i >= n:
            break
        print(line.rstrip())

Jupyteで標準入力初めて使った。便利~。



あれ...??
これUNIXコマンドを学ぶ章なのに全然UNIXコマンド書いてないのでは。
まぁ、また今度書こう(書かない)。



15. 末尾のN行を出力

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.

素人の言語処理100本ノック:15 - Qiita

fname = 'hightemp.txt'

n = int(input('>>> N : '))

with open(fname, encoding="utf-8_sig") as hightemp:
    lines = hightemp.readlines() # 全データ
    
    for line in lines[-n::1]:
        print(line.rstrip())

最初は、最後までの行数を持ってきて~とか考えていたけど、全データもってこれるよねそうですよね。
readlinesを調べているときにあった面白い記事。
ファイルを読み込む時のreadlines関数について - SELECT * FROM life;



このファイル見て思ったけど、地球温暖化っていう割りに歴代最高気温は最近のものが多いわけではないのね。
1930、1940年代のものがあるのは意外。



16. ファイルをN分割する

自然数Nをコマンドライン引数などの手段で受け取り,入力のうち末尾のN行だけを表示せよ.確認にはtailコマンドを用いよ.

素人の言語処理100本ノック:16 - Qiita

解法

import math

fname = 'hightemp.txt'
n = int(input('>>> N : '))

with open(fname, encoding="utf-8_sig") as hightemp:
    lines = hightemp.readlines()

count = len(lines)
unit = math.ceil(count / n)  # 1ファイル当たりの行数

for i, offset in enumerate(range(0, count, unit), 1):
    with open('output_{:02d}.txt'.format(i), mode='w', encoding="utf-8_sig") as output:
        for line in lines[offset:offset + unit]:
            output.write(line)

17. 1列目の文字列の異なり

1列目の文字列の種類(異なる文字列の集合)を求めよ.確認にはsort, uniqコマンドを用いよ.

素人の言語処理100本ノック:17 - Qiita

解法

fname = 'hightemp.txt'

with open(fname, encoding="utf-8_sig") as hightemp:
    column = [line.split('\t')[0] for line in hightemp]

print(set(column)) # 重複の削除

# {'和歌山県', '埼玉県', '山梨県', '静岡県', '山形県', '大阪府', '愛知県', '千葉県', '岐阜県', '愛媛県', '高知県', '群馬県'}

最初fnameの下でcolumnを初期化してたけど、なくても大丈夫だった。

18. 各行を3コラム目の数値の降順にソート

各行を3コラム目の数値の逆順で整列せよ(注意: 各行の内容は変更せずに並び替えよ).確認にはsortコマンドを用いよ(この問題はコマンドで実行した時の結果と合わなくてもよい).

素人の言語処理100本ノック:18 - Qiita
つまり、気温で降順ソートすればいい。

解法

fname = 'hightemp.txt'

# lines = open(fname).readlines()
with open(fname, encoding="utf-8_sig") as hightemp:
    lines = hightemp.readlines()

lines.sort(key=lambda line: float(line.split('\t')[2]), reverse=True)

for line in lines:
    print(line, end='')

# 高知県	江川崎	41	2013-08-12
# 埼玉県	熊谷	40.9	2007-08-16
# 岐阜県	多治見	40.9	2007-08-16
# 山形県	山形	40.8	1933-07-25
# 山梨県	甲府	40.7	2013-08-10
# 和歌山県	かつらぎ	40.6	1994-08-08
# 静岡県	天竜	40.6	1994-08-04
# 山梨県	勝沼	40.5	2013-08-10
# 埼玉県	越谷	40.4	2007-08-16
# 群馬県	館林	40.3	2007-08-16
# 群馬県	上里見	40.3	1998-07-04
# 愛知県	愛西	40.3	1994-08-05
# 千葉県	牛久	40.2	2004-07-20
# 静岡県	佐久間	40.2	2001-07-24
# 愛媛県	宇和島	40.2	1927-07-22
# 山形県	酒田	40.1	1978-08-03
# 岐阜県	美濃	40	2007-08-16
# 群馬県	前橋	40	2001-07-24
# 千葉県	茂原	39.9	2013-08-11
# 埼玉県	鳩山	39.9	1997-07-05
# 大阪府	豊中	39.9	1994-08-08
# 山梨県	大月	39.9	1990-07-19
# 山形県	鶴岡	39.9	1978-08-03
# 愛知県	名古屋	39.9	1942-08-02

最初for文で書いたけど参考先のQiitaの記事ではlambdaで書かれていてそっちのが断然きれいだったので消したorz
参考サイトでは、コメントアウトにしてるopenのやり方でcloseしてないけどいいのかな?

float
sort

19. 各行の1コラム目の文字列の出現頻度を求め,出現頻度の高い順に並べる

各行の1列目の文字列の出現頻度を求め,その高い順に並べて表示せよ.確認にはcut, uniq, sortコマンドを用いよ.

素人の言語処理100本ノック:19 - Qiita

解法

from pprint import pprint

fname = 'hightemp.txt'
count = {}

with open(fname, encoding="utf-8_sig") as hightemp:
    prefectures = [row.split('\t')[0] for row in hightemp]

for prefecture in prefectures:
    count.setdefault(prefecture, 0)
    count[prefecture] += 1

count = sorted(count.items(), key=lambda x: x[1], reverse=True)

pprint(count)

# [('埼玉県', 3),
#  ('山形県', 3),
#  ('山梨県', 3),
#  ('群馬県', 3),
#  ('岐阜県', 2),
#  ('静岡県', 2),
#  ('愛知県', 2),
#  ('千葉県', 2),
#  ('高知県', 1),
#  ('和歌山県', 1),
#  ('愛媛県', 1),
#  ('大阪府', 1)]
pprint

pretty printerの略で、データ構造によって綺麗なフォーマットで出力してくれる。
pprint – データ構造を見やすい形で出力する - Python Module of the Week

setdefault

辞書.setdefault(キー, 値)
辞書にキーが存在しないときにのみキーと値のペアを新規追加する
if文しなくていい!クール!便利!

辞書について色々まとめられていたので貼っておく。
Pythonの辞書 初心者向けガイド - Qiita

【React】package.json、yarn.lock、とかwebpackとか

package.jsonとyarn

Reactを使う際に最初に色々インストールして設定ファイルが作られてるけど何やってんのかわかってない。

yarn(ヤーン)はパッケージマネージャー。以下コマンドでインストール。

$ brew install yarn
$ yarn --version

yarnではpackage.jsonに必要なファイルを記述してそこから色々インストールする。 では、まず以下のコマンドでpackage.jsonのテンプレートを作成する nameとversionはまずはEnterを押してスキップ。

$ yarn init 

パッケージは直接このファイルに書いていくのではなくて、以下のコマンドを使うと追加と、jsonへの記述を同時に行ってくれる。

$ yarn add webpack webpack-dev-server babel-core babel-loader babel-preset-react babel-preset-es2015
コマンド 役割
webpack webpack-dev-server ローカルでdevサーバーを動かすために使う
babel-core、babel-loader、babel-preset-es2015 ES2015をコンパイルするバベル関連のパッケージ
babel-preset-react Reactをコンパイルする

package.jsonにdependenciesという項目、yarn.lockというファイルが追加されている。 yarn.lockにはパッケージ情報が書いてある(メジャーバージョン.マイナーバージョン.パッチバージョン)。 頭の「^」はそのメジャーバージョンの最新という意味 「"babel-core": "^6.25.0",」の場合6系の最新がインストールされている。 package.jsonだとインストールの環境や、時期によって入るバージョンが変わってしまう。 そこでyarn.lock。 これでバージョンを完全にしていしているので環境や時期によるバージョンの違いはなくなる。

そしてnode_modulesディレクトリに実際のライブラリが入っている。 やたら多いのは、それぞれに依存しているものも入っているので。 ここは通常.gitignoreさせる。

まとめ

  1. yarn addでライブラリをダウンロード。
  2. 同時にpackage.jsonにバージョンを記述。
  3. 同時にyarn.lockを作成することでバージョンを固定する(環境、時期によるバージョンの違いをなくす)。
  4. インストールされたものはnode_modulesディレクトリに格納されている。

yarn.lockが作成されるまで

  1. yarn addでライブラリをダウンロード。
  2. 同時にpackage.jsonにバージョンを記述。
  3. 同時にyarn.lockを作成することでバージョンを固定する(環境、時期によるバージョンの違いをなくす)。
  4. インストールされたものはnode_modulesディレクトリに格納されている。

webpack.config.jsの中身について

ついでにconfigの中身をメモっとく。

var publidDir = __dirname + '/public';
module.exports = {
  // コンパイル対象のファイル
  entry: [
    './src/index.js'
  ],
  // コンパイルしたものの吐き出し先
  output: {
    path: publidDir,
    publicPath: '/',
    filename: 'bundle.js'
  },
  // どのライブラリを使ってコンパイルするか
  module: {
    loaders: [{
      exclude: /node_modules/,
      loader: 'babel-loader',
      query: {
        presets: ['react', 'es2015']
      }
    }]
  },
  // entryからインポートされたライブラリを検索する拡張子を指定
  resolve: {
    extensions: ['.js', '.jsx']
  },
  // webpack-dev-serverの設定
  devServer: {
    historyApiFallback: true,
    contentBase: publidDir // ドキュメントルート
  }
};

devserverを起動

public/index.html作成

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="/bundle.css">
  </head>
  <body>
    <h1>Hello</h1>
  </body>
  <script src="/bundle.js" charset="utf-8"></script>
</html>

実際にはシムリンクになっている

$ ls ./node_modules/.bin/webpack-dev-server
./node_modules/.bin/webpack-dev-server -> ../webpack-dev-server/bin/webpack-dev-server.js*

実際にはjsファイルを参照している。 以下ファイルで実行。

$ ./node_modules/.bin/webpack-dev-server

このコマンドは長いので、スクリプトとしてpackage.jsonに登録する。

"scripts": {
    "start": "./node_modules/.bin/webpack-dev-server"
  },

これによって以下のコマンドで立ち上げが可能になる。

$ yarn run start

まとめ

  1. devserverでローカルにサーバー立ち上げ
  2. public/index.htmlがロードされる
  3. index.htmlのbundle.jsはwebpack.configのoutputのpuclicPathを参照している。この下のfilename(bundle。js)にアクセスがあれば、entry(src/index.js)をコンパイルした結果を返す。

実際にoutputを見るにはsrc/index.jsを以下コマンドでコンパイルする。

$ ./node_modules/.bin/webpack

そうするとpublicフォルダにbundle.jsが生成される。 これもgitignoreしとく。

部屋の綺麗さを保つと生活に締まりが出る、ような気がする

先月末、約3か月間の大連(中国)出張から帰国した友人の誕生日会がうちで行われた。
人が来るときは洗面台の鏡とか、ベッドの下とか割とどうでも良さそうなところまで掃除するんだけど、約1週間ほどその綺麗さを保っている。


今までは洗い物をするのもあとで3日分まとめてしたり、脱いだものは脱ぎっぱなしだったり、洗濯物を取り込んだらどっかにためておいて上からとっておくスタイルだったのに...!
どうも部屋を綺麗にしていると生活スタイルがきちんとする「気がする」。


具体的に言うと、部屋が綺麗だから洗い物も貯めないでおこうとかいう気持ちが少し芽生えるし、
その綺麗な部屋にだらけた自分が合わないと思っているのか、メリハリが出て、今から勉強しよう!と気持ちの切り替えがうまくなったような「気がする」。


あと、基本ずっとデスクトップのiMacつけてるけど、時報機能をONにしておくと「あ~もう1時間たったか~。」となってだらける時間が減る。


あと、ブログを書き始めたのも勉強するときに集中出来るようになった要因の一つな気がする。


部屋もブログも、いつまで続くかなぁ。