tjtjtjのメモ

自分のためのメモです

回帰ってなに

雰囲気もなにもわからず ML Study Jams を続けるのは辛い。せめて雰囲気だけでも捉えたい。

回帰 regression

線形回帰 linear regression

このラボでは、BigQuery の一般公開データセットに含まれる数百万件に及ぶニューヨーク市内のタクシー賃走データを探索します。その後、機械学習モデルを BigQuery 内に作成し、モデル入力に基づいてタクシー運賃を予測します。最後に、モデルの性能を評価し、予測を行います。

ロジスティック回帰 Logistic regression

  • ベルヌーイ分布に従う変数の統計的回帰モデルの一種である。連結関数としてロジットを使用する一般化線形モデル (GLM) の一種でもある
  • 社会科学分野での典型的な応用として、企業の過去のデータをもとに信用リスクを推定するという用法がある。
  • 線形モデルの一種であることは分かった https://ja.wikipedia.org/wiki/%E3%83%AD%E3%82%B8%E3%82%B9%E3%83%86%E3%82%A3%E3%83%83%E3%82%AF%E5%9B%9E%E5%B8%B0
  • 線形回帰と似ているが、目的変数が2値のときに利用する。 例えば、この人は商品を購入するか否か、棒に当たるか否か、引っ越すか否か、転職するか否かなどなど。 https://qiita.com/yshi12/items/3dbd336bd9ff7a426ce9
  • 「BQML で分類モデルを使用して訪問者の購入を予測する」はロジスティック回帰。買う/買わないを予測

このラボでは、このデータを使用して一般的なクエリを実行し、企業が知りたい顧客の購買習慣に関する情報を取得します。

参考

qiita.com

qiita.com

www.randpy.tokyo

qiita.com

qiita.com

BQML で分類モデルを使用して訪問者の購入を予測する

GW 明けても ML Study Jams 受け付けていたのでやってみた。

やったこと

  • ラボアカウントでログイン
  • クーポン入力
  • BigQuery の使い方練習
    • 「従来の UI に移動」が見つからない
    • 迷っているうちに、従来のUIっぽいのが表示された
    • https://bigquery.cloud.google.com/ から行くのがいいっぽい?
  • e コマース データセット の確認
    • e コマース利用者の多くは閲覧するもののすぐ購入しない
  • e コマースデータを探索する
    • sql のコピペ
  • モデル1 作成と評価
    • いくつかモデルタイプがあるらしい
      • linear_reg 数値
      • logistic_reg 0 または 1
      • 今回は 将来購入する/しない ので後者
    • モデル作成
      • create table/insert/select っぽい構文
    • モデル評価
      • 0.7 decent
  • モデル2 作成と評価
    • モデル作成
      • モデル1 より詳細な特徴を評価?
      • insert select っぽい構文
    • モデル評価
      • 0.9 good
  • 予測クエリ
    • 時間がなくコピペのみ

感想

  • 古いBigQueryUIをさがしたり、ラボアカウントでなくなってしまったり、手間取りが多かった
  • 取り組むまえにコースの目的を理解しておかないとBigQueryUIを使うだけになってしまう
  • クエリコピペするだけでは理解できない
  • モデル作成に5-10分かかった
  • 1時間15分で理解できるわけなかった
  • 今度はクエリこねくり回してどんな結果が得られるのか試したい

テキストを読み直す

  • BigQuery とは
  • e コマース利用者の多くは、初見で購入しない
    • これは学習せず既存データのselect から得られた
  • どういったユーザーが購入するか予測してみる
    • 特徴
      • totals.bounces 合計直帰数
      • totals.timeOnSite セッションの合計時間
    • モデル1 作成
    • 評価: 0.7 decent
  • モデルの改善
    • 特徴
      • 初回訪問時に訪問者は購入手続きをどこまで進めていたか 等
    • モデル2 作成
    • 評価: 0.9 good

ということらしい。 学習モデルを作るにしても適切な特徴を使わないとだめだよねってことか。 しかし、モデルを適切に評価しているのか今回だけではわからない。 分析に必要なテーブルをデータ付きで生成しているように思えるが、あれが学習なのか?

参考

support.google.com

qiita.com

やる前にこれ知りたかったorz

kafka quickstart

https://kafka.apache.org/quickstart

Step 1: Download the code

> wget http://ftp.tsukuba.wide.ad.jp/software/apache/kafka/2.2.0/kafka_2.12-2.2.0.tgz
> tar -xzf kafka_2.12-2.2.0.tgz
> cd kafka_2.12-2.2.0

Step 2: Start the server

zookeeper を起動

$ bin/zookeeper-server-start.sh config/zookeeper.properties

kafka を起動

$ bin/kafka-server-start.sh config/server.properties

Step 3: Create a topic

トピックを作成前の確認。なにもない。

$ bin/kafka-topics.sh --list --bootstrap-server localhost:9092

トピック:test を作成と確認

$ bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 1 --partitions 1 --topic test
$ bin/kafka-topics.sh --list --bootstrap-server localhost:9092
test

Step 4: Send some messages

プロデューサーでテキトーなメッセージを入力

$ bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
> msg1
> msg2

Step 5: Start a consumer

コンシューマにテキトーがメッセージが表示される

$ bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
msg1
msg2

コンシューマーを停止->起動するともう一度メッセージが表示された。これは --from-beginning がついているためか

$ bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
msg1
msg2

--from-beginning なしコンシューマーを起動し、プロデューサーでテキトーなメッセージを入力すると、続きが表示された。

$ bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test
msg3
msg4

トピックtest の詳細を確認

$ bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test
Topic:test      PartitionCount:1        ReplicationFactor:1     Configs:
        Topic: test     Partition: 0    Leader: 0       Replicas: 0     Isr: 0

Step 6: Setting up a multi-broker cluster

プロパティファイルを複製して

$ cp config/server.properties config/server-1.properties
$ cp config/server.properties config/server-2.properties

編集。1vm上に3コkafkaを立ち上げるため、バッティングしないように調整。

config/server-1.properties:
    broker.id=1
    listeners=PLAINTEXT://:9093
    log.dirs=/tmp/kafka-logs-1
 
config/server-2.properties:
    broker.id=2
    listeners=PLAINTEXT://:9094
    log.dirs=/tmp/kafka-logs-2

zookeeperと1コ目のkafkaを起動したまま、2コ目,3コ目の kafka を起動。

$ bin/kafka-server-start.sh config/server-1.properties
$ bin/kafka-server-start.sh config/server-2.properties

トピック:my-replicated-topic を作成。レプリケーションパーティションを指定している。

$ bin/kafka-topics.sh --create --bootstrap-server localhost:9092 --replication-factor 3 --partitions 1 --topic my-replicated-topic

トピックの確認。「__consumer_offsets」とは?

$ bin/kafka-topics.sh --list --bootstrap-server localhost:9092
__consumer_offsets
test

トピック:my-replicated-topic を確認。リーダーがnode2になってるみたい。

「リーダー」は、指定されたパーティションのすべての読み取りおよび書き込みを担当するノードです。各ノードは、パーティションのランダムに選択された部分のリーダーになります。 「レプリカ」は、それらがリーダーであるかどうかにかかわらず、このパーティションのログを複製するノードのリストです。 「isr」は「同期」レプリカのセットです。これは現在生きているリーダーのリストに追いついているレプリカリストのサブセットです。

$ bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic my-replicated-topic
Topic:my-replicated-topic       PartitionCount:1        ReplicationFactor:3     Configs:segment.bytes=1073741824
        Topic: my-replicated-topic      Partition: 0    Leader: 2       Replicas: 2,1,0 Isr: 2,1,0

$ bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic test
Topic:test      PartitionCount:1        ReplicationFactor:1     Configs:segment.bytes=1073741824
        Topic: test     Partition: 0    Leader: 0       Replicas: 0     Isr: 0

zookeeper にも聞いてみた

$ bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic
Topic:my-replicated-topic       PartitionCount:1        ReplicationFactor:3     Configs:
        Topic: my-replicated-topic      Partition: 0    Leader: 2       Replicas: 2,1,0 Isr: 2,1,0

node:0 のトピック一覧

# bin/kafka-topics.sh --list --bootstrap-server localhost:9092
__consumer_offsets
my-replicated-topic
test

node:1 のトピック一覧

# bin/kafka-topics.sh --list --bootstrap-server localhost:9093
__consumer_offsets
my-replicated-topic
test

node:2 のトピック一覧。すべてにtestがいるということは、これはノード毎のトピック一覧ではない?kafkaのコンセプトを理解するとわかるかもしれない。__consumer_offsets についても。

# bin/kafka-topics.sh --list --bootstrap-server localhost:9094
__consumer_offsets
my-replicated-topic
test

いよいよクラスタにメッセージ登録

$ bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-replicated-topic
>meeeeeeeeeeeeeeeeeeeeeeesg1
>meeeeeeeeeeeeeeeeeeeeeeesg2

コンシューム

$ bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
meeeeeeeeeeeeeeeeeeeeeeesg1
meeeeeeeeeeeeeeeeeeeeeeesg2

リーダーnode:2 をkill して、トピック確認。node:1がリーダーになっている。

$ bin/kafka-topics.sh --describe --bootstrap-server localhost:9092 --topic my-replicated-topic
Topic:my-replicated-topic       PartitionCount:1        ReplicationFactor:3    Configs:segment.bytes=1073741824
        Topic: my-replicated-topic      Partition: 0    Leader: 1       Replicas: 2,1,0 Isr: 1,0

続けてメッセージ登録すると、コンシュームしている。

# bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
meeeeeeeeeeeeeeeeeeeeeeesg1
meeeeeeeeeeeeeeeeeeeeeeesg2
[2019-05-08 20:44:24,061] WARN [Consumer clientId=consumer-1, groupId=console-consumer-11148] Connection to node 2 (sw1-01/163.43.114.218:9094) could not be established. Broker may not be available. (org.apache.kafka.clients.NetworkClient)
meeeeeeeeeeeeeeeeeeeeeeesg3

とりあえず kafka

kafka in docker

何も知らない状態からkafka in dockerを試す ↑のエントリ見て楽そうだったのでとりあえずやってみたが、失敗した。

Kafka in Docker この2年更新されていないので、大丈夫だよな。。。

docker run

# docker run -p 2181:2181 -p 9092:9092 --env ADVERTISED_HOST=`docker-machine ip \`docker-machine active\`` --env ADVERTISED_PORT=9092 --name test_kafka spotify/kafka
# docker ps
CONTAINER ID        IMAGE                     COMMAND                  CREATED             STATUS              PORTS                                            NAMES
7ff7f4bcedc4        spotify/kafka             "supervisord -n"         13 seconds ago      Up 12 seconds       0.0.0.0:2181->2181/tcp, 0.0.0.0:9092->9092/tcp   test_kafka

コンテナの kafka ディレクトリに入る。ここにスクリプトがまとまっている。

# docker exec -it test_kafka bash
# ls /opt
kafka ディレクトリ 確認
# cd /opt/kafka_2.11-0.10.1.0
# ls bin
connect-distributed.sh               kafka-replica-verification.sh
connect-standalone.sh                kafka-run-class.sh
kafka-acls.sh                        kafka-server-start.sh
kafka-configs.sh                     kafka-server-stop.sh
kafka-console-consumer.sh            kafka-simple-consumer-shell.sh
kafka-console-producer.sh            kafka-streams-application-reset.sh
kafka-consumer-groups.sh             kafka-topics.sh
kafka-consumer-offset-checker.sh     kafka-verifiable-consumer.sh
kafka-consumer-perf-test.sh          kafka-verifiable-producer.sh
kafka-mirror-maker.sh                windows
kafka-preferred-replica-election.sh  zookeeper-security-migration.sh
kafka-producer-perf-test.sh          zookeeper-server-start.sh
kafka-reassign-partitions.sh         zookeeper-server-stop.sh
kafka-replay-log-producer.sh         zookeeper-shell.sh

Step 3: Create a topic

ここから quickstart を参照。 --bootstrap-server でやってたがうまくいかないので、zookeeper でやっている。

トピック確認。まだない。

# bin/kafka-topics.sh --list --zookeeper localhost:2181

トピック作成

# bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
Created topic "test".

トピック確認

# bin/kafka-topics.sh --list --zookeeper localhost:2181
test

トピック describe

# bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test
Topic:test      PartitionCount:1        ReplicationFactor:1     Configs:
        Topic: test     Partition: 0    Leader: 0       Replicas: 0     Isr: 0

Step 4: Send some messages

ここからなんだかうまくいかない。こんどはdocker でないところで試す。

bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test

kubernetes 学習 hostnetwork 続き

今回は hostnetwork:true の pod がどんな状態になるのか調べてみた。

pod のマニフェスト

hello-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: hello-pod
spec:
  hostNetwork: false
  containers:
  - name: hello
    image: dockercloud/hello-world
    ports:
    - containerPort: 80

hello-hostnetwork-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: hello-hostnetwork-pod
spec:
  hostNetwork: true
  containers:
  - name: hello
    image: dockercloud/hello-world
    ports:
    - containerPort: 80

apply したあと get。hostnetwork:true のipがnodeのものになっている。

$ kubectl get pod -o wide
NAME                    READY   STATUS    RESTARTS   AGE   IP              NODE   NOMINATED NODE   READINESS GATES
hello-hostnetwork-pod   1/1     Running   0          31m   192.168.0.103   kb3    <none>           <none>
hello-pod               1/1     Running   0          31m   10.244.1.7      kb2    <none>           <none>

hello-pod

ip a/etc/hosts を確認

$ kubectl exec -it hello-pod sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
2: tunl0@NONE: <NOARP> mtu 1480 qdisc noop state DOWN qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
4: eth0@if10: <BROADCAST,MULTICAST,UP,LOWER_UP,M-DOWN> mtu 1440 qdisc noqueue state UP
    link/ether 1a:4c:fe:1b:a9:9c brd ff:ff:ff:ff:ff:ff
    inet 10.244.1.7/32 scope global eth0
       valid_lft forever preferred_lft forever
/ # cat /etc/hosts
# Kubernetes-managed hosts file.
127.0.0.1       localhost
::1     localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
fe00::0 ip6-mcastprefix
fe00::1 ip6-allnodes
fe00::2 ip6-allrouters
10.244.1.7      hello-pod

当然 node からの curl はいけない。

$ curl --connect-timeout 3 10.244.1.7
curl: (28) Connection timed out after 3001 milliseconds

hello-hostnetwork-pod

hostnetwork:true も ip a/etc/hosts を確認

$ kubectl exec -it hello-hostnetwork-pod sh
/ # ip a
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
    link/ether 9c:a3:ba:31:75:80 brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.103/24 brd 192.168.0.255 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::9ea3:baff:fe31:7580/64 scope link
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN
    link/ether 02:42:96:40:f8:e7 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
4: tunl0@NONE: <NOARP,UP,LOWER_UP> mtu 1440 qdisc noqueue state UNKNOWN qlen 1000
    link/ipip 0.0.0.0 brd 0.0.0.0
    inet 10.244.2.1/32 brd 10.244.2.1 scope global tunl0
       valid_lft forever preferred_lft forever
/ # cat /etc/hosts
# Kubernetes-managed hosts file (host network).
# /etc/hosts: Local Host Database
#
# This file describes a number of aliases-to-address mappings for the for
# local hosts that share this file.
#
# The format of lines in this file is:
#
# IP_ADDRESS    canonical_hostname      [aliases...]
#
#The fields can be separated by any number of spaces or tabs.
#
# In the presence of the domain name service or NIS, this file may not be
# consulted at all; see /etc/host.conf for the resolution order.
#

# IPv4 and IPv6 localhost aliases
127.0.0.1       localhost
::1             localhost

#
# Imaginary network.
#10.0.0.2               myname
#10.0.0.3               myfriend
#
# According to RFC 1918, you can use the following IP networks for private
# nets which will never be connected to the Internet:
#
#       10.0.0.0        -   10.255.255.255
#       172.16.0.0      -   172.31.255.255
#       192.168.0.0     -   192.168.255.255
#
# In case you want to be able to connect directly to the Internet (i.e. not
# behind a NAT, ADSL router, etc...), you need real official assigned
# numbers.  Do not try to invent your own network numbers but instead get one
# from your network provider (if any) or from your regional registry (ARIN,
# APNIC, LACNIC, RIPE NCC, or AfriNIC.)
#

node からの curl もいける。

$ curl 192.168.0.103
<html>
<head>
        <title>Hello world!</title>
:

hostnetwork:true は pod がnodeのネットワークにアクセスできるが、逆に晒されてしまう。calico tutorial で試したネットワーク分離はできないんじゃないか? hostnetworkを利用すればクラスタ外からpodにアクセス可能だが、pod がどのnodeで実行するのか特定しない限り都度ipアドレスが変わってしまうので向かない。

kubernetes 学習 hostnetwork

k8sクラスタクラスタの外にdbサーバがあるとする。クラスタとdbは同一ネットワーク上にある。k8sクラスタからdbを参照したい。

192.168.0.1    db
192.168.0.101  master
192.168.0.102  worker
192.168.0.103  worker

クラスタ外の 192.168.0.1 を参照できないことを確認

hello-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: hello-pod
spec:
  containers:
  - name: hello
    image: dockercloud/hello-world
    ports:
    - containerPort: 80

pod 作成

$ kubectl apply -f hello-pod.yaml
pod/hello-pod created

podから192.168.0.1 上のサービスを参照。タイムアウトする。

$ kubectl exec -it hello-pod sh
/ # wget -T 5 192.168.0.1
Connecting to 192.168.0.1 (192.168.0.1:80)
wget: download timed out

クラスタ外 192.168.0.1 を参照する

hostNetwork:true にする

hello-pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: hello-pod
spec:
  hostNetwork: true  # <--- here
  containers:
  - name: hello
    image: dockercloud/hello-world
    ports:
    - containerPort: 80

apply 失敗。いったん削除が必要だった

$ kubectl apply -f pod-with-host-network.yaml
The Pod "hello-pod" is invalid: spec: Forbidden: pod updates may not change fields other than `spec.co ntainers[*].image`, `spec.initContainers[*].image`, `spec.activeDeadlineSeconds` or `spec.tolerations`  (only additions to existing tolerations)
:

pod削除->作成。

$ kubectl delete pod hello-pod
pod "hello-pod" deleted
$ kubectl apply -f hello-pod.yaml
pod/hello-pod created

podからクラスタ外192.168.0.1 上のサービスを参照。参照に成功。

$ kubectl exec -it hello-pod sh
/ # wget -T 5 192.168.0.1 -O -
Connecting to 192.168.0.1 (192.168.0.1:80)
<html>
<head>
        <title>Hello world!</title>
:

kubernetes 学習 calico simple policy tutorial その3

また続き。ネットワークポリシーはない状態。

access-nginx -> default-deny

ポリシーの作成順に関係があるのか。

core@kb1 ~ $ kubectl create -f - <<EOF
> kind: NetworkPolicy
> apiVersion: networking.k8s.io/v1
> metadata:
>   name: access-nginx
>   namespace: policy-demo
> spec:
>   podSelector:
>     matchLabels:
>       run: nginx
>   ingress:
>     - from:
>       - podSelector:
>           matchLabels:
>             run: access
> EOF
networkpolicy.networking.k8s.io/access-nginx created
core@kb1 ~ $ kubectl create -f - <<EOF
> kind: NetworkPolicy
> apiVersion: networking.k8s.io/v1
> metadata:
>   name: default-deny
>   namespace: policy-demo
> spec:
>   podSelector:
>     matchLabels: {}
> EOF
networkpolicy.networking.k8s.io/default-deny created

pod:access

/ # echo $HOSTNAME
access-7c5df8f4c-b8p5b
/ # wget -q --timeout=5 nginx -O -
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>

pod:cant-access で。いけない。

/ # echo $HOSTNAME
cant-access-7587658dc7-h5b7f
/ # wget -q --timeout=5 nginx -O -
wget: download timed out

いっこでもポリシーがあるとdefault-denyで適用順序に関係なく許可優先とか?あとで確認しよう。

お掃除

$ kubectl delete ns policy-demo
namespace "policy-demo" deleted
$ kubectl get all --namespace=policy-demo
No resources found.