54日目 Pythonで機械学習できるかな？

[Pythonによるスクレイピング&機械学習 開発テクニック BeautifulSoup,scikit\-learn,TensorFlowを使ってみよう 単行本 – 2016/12/6 クジラ飛行机 \(著\)](https://www.amazon.co.jp/Python%E3%81%AB%E3%82%88%E3%82%8B%E3%82%B9%E3%82%AF%E3%83%AC%E3%82%A4%E3%83%94%E3%83%B3%E3%82%B0-%E9%96%8B%E7%99%BA%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF-BeautifulSoup-scikit-learn-TensorFlow%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86/dp/4802610793)

買ってきました！

１章２章がクローリングとスクレイピング。これは何とかなりそう。
３章からチャレンジしました。


#テキストデータとバイナリデータ

###テキストデータ
人間が読みやすい形

###バイナリデータ
機械が使うのに合理的な形

どう違うか見てみます。バイナリで出力するプログラムを作ります。

```test.py
filename=“binary.bin”
data=100
with open(filename, ”wb”) as f:
 f.write(bytearray[data])
```
ありゃ、うごかない！

```
 python test.py
  File "test.py", line 1
    filename=“binary.bin”
                   ^
SyntaxError: invalid character in identifier
```

このエラーはというと、
[invalid character in identifier　のエラー](https://teratail.com/questions/75641)

全角？半角？Pythonにわからない文字が入っているようです。
仕方ない、一行まるまる書き換えて・・・

```
$ python test.py
  File "test.py", line 3
    with open(filename, ”wb”) as f:
                           ^
SyntaxError: invalid character in identifier
```

また書き換えて
またエラー

```
$ python test.py
Traceback (most recent call last):
  File "test.py", line 4, in <module>
    f.write(bytearray[data])
TypeError: 'type' object is not subscriptable
```

リストのタイプが違う？？？
うーん、わからん。
ともかくもう一回書き換えて実行。

```test.py
filename='binary.bin'
data=100
with open(filename, ) as f:
	f.write(bytearray[data])
```

ようやくちゃんと実行できました。

```
$ ls
binary.bin

$ cat binary.bin
d

$ hexdump binary.bin
0000000 64                                             
0000001
```

おおー
なるほど！

ただし、1bitを削る時代ではないので、今時はテキストでよいそうです。

#文字コード
Shift_JIS(改行CR+LF)、UTF-8(改行 LF)→よく見る。
HTMLでは`<meta charaset=“文字セット名”>`で指定する。
HTML5はUTF-8が推奨。Excelで開くとこんがらかるやつだ！

#XML
タグで囲んでデータをタグ付けする仕様。
`<要素名 属性=“属性値”>`内容`</要素名>`

##練習）横浜市の防災データを読む。
###URLが変わっていた。横浜市、オープンデータ推進ページにまとまってて使いやすい。
https://www.city.yokohama.lg.jp/kurashi/bousai-kyukyu-bohan/bousai-saigai/bosai/data/data.html


###ダウンロードがZipファイルだったので解凍する
```
with zipfile.ZipFile('data/temp/new_comp.zip') as existing_zip:
    existing_zip.extractall('data/temp/ext')
```
（参考）[zipファイルの中身をすべて解凍（展開）](https://note.nkmk.me/python-zipfile/)

まずはお手本を見ながらざくざく書いてみる。

```xml-bonsai-z.py
from bs4 import Beautifulsoup
import urllib.request as req
import os.path

#XMLをダウンロード
url="https://www.city.yokohama.lg.jp/kurashi/bousai-kyukyu-bohan/bousai-saigai/bosai/data/data.files/0001_20180911.zip"

#Zipがなければダウンロード、あればパス
zipname="0001_20180911.zip"
savename="shelter.xml"
if not os.path.exists(zipname):
	req.urlretrieve(url, zipname)
	#Zipを解凍
	with zipfile.ZipFile('0001_20180911.zip') as existing_zip:
	    existing_zip.extractall()

#Beautifulsoupで解析
xml = open(savename, "r", encording="utf-8").read()
soup = Beautifulsoup(xml, 'html.parser')

#データを各区ごとに確認

##辞書infoを初期化
info={}

#shelterタグをiに入れて１つづつ見ていく
for i in soup.find_all("shelter"):
	name = i.find('name').string	#建物名
	ward = i.find('ward').string	#区
	addr = i.find('address').string	#住所
	note = i.find('notes').string	#メモ

	#辞書infoに収録されていないward(区)だったら区を追加する。
	if not (ward in info):
		info[ward] =[]

	#区ごとに項目を追加する
	info[ward].append(name)

#区ごとに防災拠点を表示
for ward in info.keys():
	print("+", ward)
	for name in info[ward]:
		print("| - ", name)
```

さて実行！

###１回目
大文字小文字が違ってた！
Beautifulsoup→Beautiful`S`oup

```
$ python xml-bousai-r.py 
Traceback (most recent call last):
  File "xml-bousai-r.py", line 1, in <module>
    from bs4 import Beautifulsoup
ImportError: cannot import name 'Beautifulsoup' from 'bs4' (/anaconda3/lib/python3.7/site-packages/bs4/__init__.py)
```

###２回目
zipfileをimportしてなかった！

```
$ python xml-bousai-r.py 
Traceback (most recent call last):
  File "xml-bousai-r.py", line 14, in <module>
    with zipfile.ZipFile('0001_20180911.zip') as existing_zip:
NameError: name 'zipfile' is not defined
```

###３回目
`encording`???
`encoding`でした！

```
$ python xml-bousai-r.py 
Traceback (most recent call last):
  File "xml-bousai-r.py", line 19, in <module>
    xml = open(savename, "r", encording="utf-8").read()
TypeError: 'encording' is an invalid keyword argument for open()
```

###４回目
ファイルがない？

```
$ python xml-bousai-r.py 
Traceback (most recent call last):
  File "xml-bousai-r.py", line 19, in <module>
    xml = open(savename, "r", encoding="utf-8").read()
FileNotFoundError: [Errno 2] No such file or directory: 'shelter.xml'
```

 どうやってもpythonでunzipできない、ギブアップ。

```
$ unzip 0001_20180911.zip 
Archive:  0001_20180911.zip
  inflating: shelter.xml 
```

###５回目
またしてもBeautiful`s`oup

```
$ python xml-bousai-r.py 
Traceback (most recent call last):
  File "xml-bousai-r.py", line 20, in <module>
    soup = Beautifulsoup(xml, 'html.parser')
NameError: name 'Beautifulsoup' is not defined
```

###６回目
```
$ python xml-bousai-r.py 
+ 鶴見区
| -  生麦小学校
| -  豊岡小学校
| -  鶴見小学校
| -  潮田小学校
| -  下野谷小学校
（以下略）
```

できました！
解析した結果は辞書{}に入れる、これは良い収穫でした。
###機械学習の道のりが遠い・・・


さて、気を取り直して。

###JSONとは
Javascript Objecct Notationの略。Javascriptのオブジェクトの表記法をベースにしている。単純で使いやすい。Pythonの標準モジュールで使える。

表記法の例）

```
数値　そのまま。30
文字列　“”でくくる。”str”
真偽型　true/false
配列　[n1,n2,n3,,,]
オブジェクト {“key”:value, “Key”:value,  …}
Null null
```

###PythonでJSONの解析

```hyakunin-random.py
import urllib.request as req
import os.path, random
import json

#JSONデータをダウンロード
#urlを指定
url = "http://api.aoikujira.com/hyakunin/get.php?fmt=json"
#ファイル名
savename ="hyakunin.json"
#もしダウンロード済みだったら実行しない
if not os.path.exists(url):
	#ファイルがなければ実行する。
	req.urlretrieve(url, savename)

#ファイルを読み込む
data=json.load(open(savename, "r", encoding="utf-8"))

#ランダムに一首表示
r=random.choice(data)
print(r['kami'], r['simo'])
```
おおっ一発でできた！

###JSON形式を書き出す

```json.py
import json

price = {
	"date": "2019/08/24",
	"price": {
		"Apple": 80,
		"Orange": 55,
		"Banana": 40
	}
}

s=json.dumps(price)
print(s)
```

簡単だからできると思ったらエラー。
どこをどうみても間違っていないはず・・・？？？

```
$ python json.py 
Traceback (most recent call last):
  File "json.py", line 1, in <module>
    import json
  File “…../json.py", line 12, in <module>
    s=json.dumps(price)
AttributeError: module 'json' has no attribute 'dumps'
```

`AttributeError`で調べたら、importしたいモジュールと同じファイル名だと、ファイルの方を読みに行ってこけるらしい。何ということでしょう。。。

[AtributeErrorが起きた場合の対処方法 このようなエラーが起きた場合に確認してほしいのがファイル名とimportの指定が同名であるか否か。 このような場合、importの指定と同じファイル名称にするとそちらを読み込んでしまうのがエラーの原因となります。](https://code-schools.com/python-attribute-error/)

ファイル名を変えるだけでいいの？

```
$ mv json.py test.py
$ python test.py
{"date": "2019/08/24", "price": {"Apple": 80, "Orange": 55, "Banana": 40}}
```

できました！

YAML、CSV、Excel SQLite、MySQLはやった事があるので省略。
Docerはどっかでやってみたい。TinyDB、MongoDBは便利そう。
１、２、３章ざっくり完了です。
（所要時間 ４時間）