Introduction to AI Technologies-2nd(handout)_Mar_10_Ebata
江端智一のホームページ
あが
の方法が上手く動かない。
$ tree
.
├── Agent
│ ├── cert.pem
│ ├── go.mod
│ ├── go.sum
│ ├── key.pem
│ └── main.go
├── join
│ ├── cert.pem
│ ├── join.exe
│ ├── join.go
│ └── key.pem
└── ldarp
└── libdarp.go
のAgent/main.go と、join/join.goの中で、ldap/libdarp.goを使いたいんだけど、
import (
"m/ldarp"
)
を、
import (
"m/../ldarp"
)
とか
import (
"m/./../ldarp"
)
とか試したみたんだけど、ダメ。
エラーコードに記載されているように、大人しく、
join.go:13:2: package m/ldarp is not in GOROOT (c:\go\src\m\ldarp)
のところに作れば動くんだろうけど、『負けたような気がする』ので、Agent/main.go と、join/join.goの中に、ldap/libdarp.goを埋めこむことで対応した。
ライブラリの二重管理になるけど、まあいいかな、と。
使う度に調べるので、メモしておきます。
1. 40歳から44歳の人の人数を数えろ
=COUNTIFS($B$1:$B$498, ">=45",$B$1:$B$498, "<50" )
2.55歳から59歳の人の不満値の平均値を求めよ
=AVERAGEIFS($J$1:$J$498, $B$1:$B$498, ">=55",$B$1:$B$498, "<60" )
Keywords: COUNTIF, COUNTIFS, AVERAGEIFS
官能の人工知能 ~深層学習を最も分かりやすく説明するパラダイムOver the AI ―― AIの向こう側に(22)
で使ったソースコード(cpp)が見つからなかったので、添付しておきます。
I could not find the source code (cpp) used in the following, so I am attaching it.
ついでに、破壊実験の方も
Code for destructive experiments
口に出せない介護問題の真実 ~「働き方改革」の問題点とは何なのか
The Truth About Unspoken Nursing Care Issues - What is the Problem with "Workplace Reform"?
This program is based on the following page
https://qiita.com/ufoo68/items/9e4ca04578ba0f5fa5ff
This program solves the XOR problem using MLP with one hidden layer.
#include <stdio.h>
#include <math.h>
#include <time.h>
#include <stdlib.h>
//num of units
#define NUM_INPUT 2
//#define NUM_HIDDEN 20
#define NUM_HIDDEN 2
double sigmoid(double x) {
return 1/(1+exp(-x));
}
//derivative of sigmoid function
double d_sigmoid(double x) {
double a = 0.1;
return a*x*(1-x);
}
int main(void) {
srand((unsigned)time(NULL));
//train data
double train_x[4][NUM_INPUT+1] = {{0, 0, -1},{0, 1, -1},{1, 0, -1},{1, 1, -1}};
double d[4] = {0, 1, 1, 0};
//net
double w[NUM_HIDDEN+1][NUM_INPUT+1];
double v[NUM_HIDDEN+1];
double y[4][NUM_HIDDEN+1];
double z[4];
double eta = 0.1;
int epoch = 1000000;
//other
int i, j, k, l;
double tmp = 0;
//update weights using rand()
for(l=0; l<NUM_HIDDEN+1; l++) {
for(i=0; i<NUM_INPUT+1; i++) {
w[l][i] = ((double)rand() / ((double)RAND_MAX + 1));
}
}
for(i=0; i<NUM_HIDDEN+1; i++) {
v[i] = ((double)rand() / ((double)RAND_MAX + 1));
}
//tain
for(k=0; k<epoch; k++) {
//feedforward
for(j=0; j<4; j++) {
//hidden
for(l=0; l<NUM_HIDDEN; l++) {
for(i=0; i<NUM_INPUT+1; i++) {
tmp += train_x[j][i] * w[l][i];
}
y[j][l] = sigmoid(tmp);
tmp = 0;
}
y[j][NUM_HIDDEN] = -1;
//output
for(i=0; i<NUM_HIDDEN+1; i++) {
tmp += y[j][i] * v[i];
}
z[j] = sigmoid(tmp);
tmp = 0;
//backward
//output
for(i=0; i<NUM_HIDDEN+1; i++) {
v[i] = v[i] - eta * y[j][i] * d_sigmoid(z[j]) * (z[j] - d[j]);
}
//hidden
for(l=0; l<NUM_INPUT+1; l++) {
for(i=0; i<NUM_HIDDEN+1; i++) {
w[i][l] = w[i][l] - eta * train_x[j][l] * d_sigmoid(y[j][i]) * d_sigmoid(z[j]) * (z[j] - d[j]) * v[i];
}
}
}
/*
//print detail
printf("z=");
for(i=0; i<4; i++) {
printf("%f ", z[i]);
}
printf("epoch:%d\n",k);
*/
}
//predict
for(j=0; j<4; j++) {
//hidden
for(l=0; l<NUM_HIDDEN; l++) {
for(i=0; i<NUM_INPUT+1; i++) {
tmp += train_x[j][i] * w[l][i];
}
y[j][l] = sigmoid(tmp);
tmp = 0;
}
y[j][NUM_HIDDEN] = -1;
//output
for(i=0; i<NUM_HIDDEN+1; i++) {
tmp += y[j][i] * v[i];
}
z[j] = sigmoid(tmp);
tmp = 0;
}
//print result
printf("z=");
for(i=0; i<4; i++) {
printf("%f ", z[i]);
}
printf("epoch:%d\n",k);
for(i=0; i<NUM_INPUT+1; i++) {
for(l=0; l<NUM_HIDDEN+1; l++) {
printf("w[%d][%d]:%f\n", i, l, w[i][l]);
}
}
for(i=0; i<NUM_HIDDEN+1; i++) {
printf("v[%d]:%f\n",i, v[i]);
}
return 0;
}
Save this program as a name "mlp.c", compile ">gcc mlp.c" and execute ">./a.exe"
Golang 文字列を数値に変換する方法で、文字列→実数なら、これが一番てっとり早そう
dest_lat, err := strconv.ParseFloat(row[2], 64)
strconv.ParseIntとstrconv.ParseUnitは、文字列を解析して整数型を返す関数
それぞれ符号付き整数型と符号なし整数型に対応している。
ODデータ(csv):20220518weekday
領域データ(csv):yamaguchi_area
出力データ(csv):new_20220518weekday
その他: 年齢を乱数を使って適当に作成しているコードも入っている
// ~/yamaguchi/src_try1/others/main61.go
// Usage: go run main61.go 20220518weekday.csv new_20220518weekday.csv
package main
import (
"database/sql"
"encoding/csv"
"fmt"
"log"
"math/rand"
"os"
"strconv"
_ "github.com/lib/pq"
)
func main() {
file, err := os.Open("yamaguchi_area.csv")
if err != nil {
log.Fatal(err)
}
defer file.Close()
r := csv.NewReader(file)
rows, err := r.ReadAll() // csvを一度に全て読み込む
if err != nil {
log.Fatal(err)
}
str := "SELECT ST_Covers(st_geomfromtext('POLYGON(("
// 行ごとに
for i, row := range rows {
if i == 0 {
continue // CSVのヘッダー行を無視
}
str += row[1] + " " + row[2] + ", " // rowのままで取り出せば、文字列になっている
}
str1 := str[:len(str)-2] + "))'),st_geomfromtext('LINESTRING(" // 上記の最後の", "を削除して、文字列を追加
dbMap, err := sql.Open("postgres",
"user=postgres password=password host=192.168.0.23 port=15432 dbname=yama_db sslmode=disable")
log.Println("------------------ map db open ------------------")
if err != nil {
log.Fatal("OpenError: ", err)
}
defer dbMap.Close()
///////////////////////////////////////
//file2, err2 := os.Open("20220518weekday.csv")
file2, err2 := os.Open(os.Args[1]) // 第1パラメータ
if err2 != nil {
log.Fatal(err2)
}
defer file2.Close()
r2 := csv.NewReader(file2)
rows2, err2 := r2.ReadAll() // csvを一度に全て読み込む
if err != nil {
log.Fatal(err2)
}
file3, err3 := os.Create(os.Args[2]) // 第2パラメータ
if err3 != nil {
panic(err)
}
w := csv.NewWriter(file3)
var id int
for _, row := range rows2 {
//if i == 0 {
// continue // CSVのヘッダー行を無視
//}
str2 := str1 + row[0] + " " + row[1] + ", " + row[2] + " " + row[3]
str2 += ")'))"
fmt.Println(str2)
rows1, err := dbMap.Query(str2)
if err != nil {
log.Fatal(err)
}
defer rows1.Close()
//var dt string
var dt bool
for rows1.Next() {
if err := rows1.Scan(&dt); err != nil {
fmt.Println(err)
}
// fmt.Println(dt)
if dt {
//if err := rows.Scan(&id, &age, &type1, &departure_name, &departure_number, &departure_lat, &departure_lng, &arrival_name, &arrival_number, &arrival_lat, &arrival_lng); err != nil {
// fmt.Println(err)
// 上記のSQLのフォームと同じ形でcsvファイルを作る
var age int
fmt.Println("row[4]:", row[4])
// id_str := strconv.Itoa(id) // idを文字列に
if row[4] == "10-15" {
age = 10 + rand.Intn(5)
} else if row[4] == "15-29" {
age = 15 + rand.Intn(5)
} else if row[4] == "20-24" {
age = 20 + rand.Intn(5)
} else if row[4] == "25-29" {
age = 25 + rand.Intn(5)
} else if row[4] == "30-34" {
age = 30 + rand.Intn(5)
} else if row[4] == "35-39" {
age = 35 + rand.Intn(5)
} else if row[4] == "40-44" {
age = 40 + rand.Intn(5)
} else if row[4] == "44-49" {
age = 45 + rand.Intn(5)
} else if row[4] == "50-54" {
age = 50 + rand.Intn(5)
} else if row[4] == "55-59" {
age = 55 + rand.Intn(5)
} else if row[4] == "60-64" {
age = 60 + rand.Intn(5)
} else if row[4] == "65-69" {
age = 65 + rand.Intn(5)
} else if row[4] == "70-74" {
age = 70 + rand.Intn(5)
} else if row[4] == "75-80" {
age = 75 + rand.Intn(5)
} else if row[4] == "80-84" {
age = 80 + rand.Intn(5)
} else if row[4] == "85-89" {
age = 85 + rand.Intn(5)
} else if row[4] == "90-94" {
age = 90 + rand.Intn(5)
} else if row[4] == "95-99" {
age = 95 + rand.Intn(5)
} else {
age = 15 + rand.Intn(65) // 15箸キ79までの乱数
}
type1 := "resident"
departure_name := ""
_row1, _ := strconv.ParseFloat(row[1], 64)
_row0, _ := strconv.ParseFloat(row[0], 64)
departure_number, departure_lng, departure_lat := fixPosition(dbMap, _row1, _row0) // row[1], row[0]の順番に注意
arrival_name := ""
_row3, _ := strconv.ParseFloat(row[3], 64)
_row2, _ := strconv.ParseFloat(row[2], 64)
arrival_number, arrival_lng, arrival_lat := fixPosition(dbMap, _row3, _row2) // row[3], row[2]の順番に注意
output := []string{fmt.Sprint(id), fmt.Sprint(age), type1, departure_name, fmt.Sprint(departure_number), fmt.Sprint(departure_lat), fmt.Sprint(departure_lng), arrival_name, fmt.Sprint(arrival_number), fmt.Sprint(arrival_lat), fmt.Sprint(arrival_lng)}
//output := []string{row[0], row[1], row[2], row[3], row[4]}
fmt.Println("output:", output)
if err = w.Write(output); err != nil {
log.Fatal(err)
}
id++ // idの加算
}
}
err = rows1.Err()
if err != nil {
panic(err)
}
defer w.Flush()
if err := w.Error(); err != nil {
log.Fatal(err)
}
}
}
// 指定した座標に近いDB上の座標を取得
func fixPosition(db *sql.DB, _x1, _y1 float64) (int, float64, float64) {
// Scan用の仮変数
var source int
var longitude float64
var latitude float64
var dist float64
upperLimitMeter := 1500.0 // 近傍ノードの上限を1500 mに設定
str := fmt.Sprintf(
// 修正前: ways (道) の中から最近傍を取得
// "SELECT source, x1 AS longitude, y1 AS latitude, ST_Distance('SRID=4326;POINT(%v %v)'::GEOGRAPHY, the_geom) AS dist FROM ways WHERE ST_DWithin(the_geom, ST_GeographyFromText('SRID=4326;POINT(%v %v)'), %.1f) ORDER BY dist LIMIT 1",
// 修正後: ways_vertices_pgr (点座標) の中から最近傍を取得
"SELECT id AS source, lon AS longitude, lat AS latitude, ST_Distance('SRID=4326;POINT(%v %v)'::GEOGRAPHY, the_geom) AS dist FROM ways_vertices_pgr WHERE ST_DWithin(the_geom, ST_GeographyFromText('SRID=4326;POINT(%v %v)'), %.1f) ORDER BY dist LIMIT 1",
_x1, _y1, _x1, _y1, upperLimitMeter,
)
//fmt.Println(str)
rows, err := db.Query(str)
if err != nil {
log.Fatal(err)
}
defer rows.Close()
foundGoodMapNode := false
for rows.Next() {
foundGoodMapNode = true
if err := rows.Scan(&source, &longitude, &latitude, &dist); err != nil {
fmt.Println(err)
}
//fmt.Println(source, longitude, latitude, dist)
}
if !foundGoodMapNode {
log.Println("Warning: in func fixPosition: Good Map Node not found for query point (",
_x1, ",", _y1, ")")
}
return source, longitude, latitude
}
A社 CSVファイルパース用テストコード (用事が終わったら消すこと)
package main
import (
"encoding/csv"
"fmt"
"log"
"os"
"regexp"
"strings"
)
func main() {
file, err := os.Open("tracking_data.csv")
if err != nil {
log.Fatal(err)
}
defer file.Close()
r := csv.NewReader(file)
rows, err := r.ReadAll() // csvを一度に全て読み込む
if err != nil {
log.Fatal(err)
}
lat := [10000]string{}
lng := [10000]string{}
speed := [10000]string{}
// [][]stringなのでループする
for j, v := range rows {
if j == 0 {
continue // CSVのヘッダー行を無視
}
//fmt.Println(v[3])
// v[3]をバラバラに分解する
// v3 := regexp.MustCompile("[() ,]").Split(v[3], -1)
v3 := regexp.MustCompile("}, {").Split(v[3], -1)
for i, s := range v3 { // i: 数
//fmt.Printf("%s\n", s)
v31 := strings.Replace(s, "\"lat\": ", "", -1)
v32 := strings.Replace(v31, "\"lng\": ", "", -1)
v33 := strings.Replace(v32, "[{", "", -1)
v34 := strings.Replace(v33, "}]", "", -1)
v35 := regexp.MustCompile(",").Split(v34, -1)
for k, s5 := range v35 {
//f64, _ := strconv.ParseFloat(s5, 64)
//fmt.Println("string", i, s5)
if k == 0 {
lat[i] = s5
} else {
lng[i] = s5
}
}
}
//fmt.Println(lat[0], lng[0], lat[19], lng[19])
//fmt.Println()
// v[4]をバラバラに分解する
v41 := strings.Replace(v[4], "[", "", -1)
v42 := strings.Replace(v41, "]", "", -1)
v43 := regexp.MustCompile(",").Split(v42, -1)
for k4, s4 := range v43 {
speed[k4] = s4
fmt.Println(k4, ",", lat[k4], ",", lng[k4], ",", speed[k4])
}
}
}
I hope you could understand the min-max method of Fuzzy reasoning, using the following Go programming list.
package main
import (
"fmt"
"os"
)
func max_2(a, b float64) float64 {
if a > b {
return a
} else {
return b
}
}
func min_2(a, b float64) float64 {
if a > b {
return b
} else {
return a
}
}
type condition_MF3 struct { // Base class for condition_MF3
center float64
width float64
express string
}
func new_condition_MF3(_center, _width float64, _express string) *condition_MF3 {
c3 := new(condition_MF3)
c3.center = _center
c3.width = _width
c3.express = _express
return c3
}
// Class for the membership function (3 mountains) of the former case
func (c3 *condition_MF3) func_X(_x float64) float64 {
// x,y denote coordinates on the membership function
x := _x
y := 0.0 // The value of y is always greater than or equal to 0 and less than or equal to 1
if c3.express == "LESS" {
if x <= c3.center-c3.width {
y = 1.0
} else if x <= c3.center {
y = -1.0 / c3.width * (x - c3.center)
} else {
y = 0.0
}
} else if c3.express == "COMMON" {
if x <= c3.center-c3.width {
y = 0.0
} else if x <= c3.center {
y = 1.0/c3.width*(x-c3.center) + 1.0
} else if x <= c3.center+c3.width {
y = -1.0/c3.width*(x-c3.center) + 1.0
} else {
y = 0.0
}
} else if c3.express == "MORE" {
if x <= c3.center {
y = 0.0
} else if x <= c3.center+c3.width {
y = 1.0 / c3.width * (x - c3.center)
} else {
y = 1.0
}
} else {
fmt.Println("MF3: wrong expression")
os.Exit(1)
}
return y
}
type condition_MF5 struct { // Base class for condition_MF5
center float64
width float64
express string
}
func new_condition_MF5(_center, _width float64, _express string) *condition_MF5 {
c5 := new(condition_MF5)
c5.center = _center
c5.width = _width
c5.express = _express
return c5
}
func (c5 *condition_MF5) func_X(_x float64) float64 {
// Class for the former membership function (5 mountains)
// x,y are the coordinates on the membership function
x := _x
y := 0.0 // The value of y is always greater than or equal to 0 and less than or equal to 1
if c5.express == "LESSLESS" {
if x <= c5.center-2.0*c5.width {
y = 1.0
} else if x <= c5.center-c5.width {
y = -1.0/c5.width*(x-(c5.center-2.0*c5.width)) + 1.0
} else {
y = 0.0
}
} else if c5.express == "LESS" {
if x <= c5.center-2.0*c5.width {
y = 0.0
} else if x <= c5.center-c5.width {
y = 1.0/c5.width*(x-(c5.center-c5.width)) + 1.0
} else if x <= c5.center {
y = -1.0/c5.width*(x-(c5.center-c5.width)) + 1.0
} else {
y = 0.0
}
} else if c5.express == "COMMON" {
if x <= c5.center-c5.width {
y = 0.0
} else if x <= c5.center {
y = 1.0/c5.width*(x-c5.center) + 1.0
} else if x <= c5.center+c5.width {
y = -1.0/c5.width*(x-c5.center) + 1.0
} else {
y = 0.0
}
} else if c5.express == "MORE" {
if x <= c5.center {
y = 0.0
} else if x <= c5.center+c5.width {
y = 1.0/c5.width*(x-(c5.center+c5.width)) + 1.0
} else if x <= c5.center+2.0*c5.width {
y = -1.0/c5.width*(x-(c5.center+c5.width)) + 1.0
} else {
y = 0.0
}
} else if c5.express == "MOREMORE" {
if x <= c5.center+c5.width {
y = 0.0
} else if x <= c5.center+2.0*c5.width {
y = 1.0/c5.width*(x-(c5.center+2.0*c5.width)) + 1.0
} else {
y = 1.0
}
} else {
fmt.Println("MF5 func_X(): wrong expression")
os.Exit(1)
}
return y
}
/////////////////////////////
type action_MF5 struct { // Base class for action_MF5
center float64
width float64
express string
x float64
y float64
}
type action_MF3 struct { // Base class for action_MF3
center float64
width float64
express string
x float64
y float64
}
func new_action_MF5(_center, _width float64, _express string) *action_MF5 {
a5 := new(action_MF5)
a5.center = _center
a5.width = _width
a5.express = _express
if a5.express == "LESSLESS" {
a5.x = a5.center - 2.0*a5.width
} else if a5.express == "LESS" {
a5.x = a5.center - a5.width
} else if a5.express == "COMMON" {
a5.x = a5.center
} else if a5.express == "MORE" {
a5.x = a5.center + a5.width
} else if a5.express == "MOREMORE" {
a5.x = a5.center + 2.0*a5.width
} else {
fmt.Println("new_action_MF5: wrong scale expression")
os.Exit(-1)
}
a5.y = 0.0
return a5
}
func new_action_MF3(_center, _width float64, _express string) *action_MF3 {
a3 := new(action_MF3)
a3.center = _center
a3.width = _width
a3.express = _express
if a3.express == "LESS" {
a3.x = a3.center - a3.width
} else if a3.express == "COMMON" {
a3.x = a3.center
} else if a3.express == "MORE" {
a3.x = a3.center + a3.width
} else {
fmt.Println("new_action_MF3: wrong scale expression")
os.Exit(-1)
}
a3.y = 0.0
return a3
}
// The latter membership function (5 mountains) class
func (a5 *action_MF5) func_Y() float64 {
return a5.y
}
// The latter membership function (3 mountains) class
func (a3 *action_MF3) func_Y() float64 {
return a3.y
}
func (a5 *action_MF5) func_Max(b float64) {
a5.y = max_2(b, a5.y)
}
func (a3 *action_MF3) func_Max(b float64) {
a3.y = max_2(b, a3.y)
}
func (a5 *action_MF5) func_X() float64 {
return a5.x
}
func (a3 *action_MF3) func_X() float64 {
return a3.x
}
func fuzzy_reasoning(temp, humi float64) float64 {
// Temperature(former)
Temp_Less := new_condition_MF3(20, 10, "LESS")
Temp_Common := new_condition_MF3(20, 10, "COMMON")
Temp_More := new_condition_MF3(20, 10, "MORE")
// Humidity(former)
Humi_Less := new_condition_MF3(50, 20, "LESS")
Humi_Common := new_condition_MF3(50, 20, "COMMON")
Humi_More := new_condition_MF3(50, 20, "MORE")
// Switch(前件部)
Switch_Less := new_action_MF3(0,1,"LESS")
Switch_Common := new_action_MF3(0,1,"COMMON")
Switch_More := new_action_MF3(0,1,"MORE")
// [Rule 01]
Rule01 := min_2(Temp_More.func_X(temp), Humi_More.func_X(humi))
Switch_Less.func_Max(Rule01) // the latters values are overwritten if the value is large enough.
fmt.Println("Rule01", Rule01)
// [Rule 02]
Rule02 := min_2(Temp_Common.func_X(temp), Humi_More.func_X(humi))
Switch_Common.func_Max(Rule02) // the latters values are overwritten if the value is large enough.
fmt.Println("Rule02", Rule02)
// [Rule 03]
Rule03 := min_2(Temp_More.func_X(temp), Humi_Common.func_X(humi))
Switch_Less.func_Max(Rule03) // the latters values are overwritten if the value is large enough.
fmt.Println("Rule03", Rule03)
// [Rule 04]
Rule04 := min_2(Temp_Less.func_X(temp), Humi_Less.func_X(humi))
Switch_More.func_Max(Rule04) // the latters values are overwritten if the value is large enough.
fmt.Println("Rule04", Rule04)
// Reasoning calculations
numerator :=
Switch_Less.func_X()*Switch_Less.func_Y() +
Switch_Common.func_X()*Switch_Common.func_Y() +
Switch_More.func_X()*Switch_More.func_Y()
denominator :=
Switch_Less.func_Y() +
Switch_Common.func_Y() +
Switch_More.func_Y()
reasoning := numerator / denominator
return reasoning
}
func main(){
fmt.Println(fuzzy_reasoning(27.0, 67.0))
}