プログラミングとかブログ

Unity/C#/SRPGStudio/RPGツクールMVの情報とかその他気になったことを調べて書きます。

【C#】自分がリツイートしたツイートをリンク付きでHTML出力するアプリとコード

RTしたツイートだけ確認したいなぁと思ったら検索クエリにないので自作。
DLはこちら

使い方

1.ツイッターの全ツイート履歴をダウンロードしてください
Twitter、「全ツイート履歴」をダウンロードできる機能、日本でも提供開始 -INTERNET Watch Watch
(フォルダ内のtweets.csvを開けば大体確認できるけどダルい)

2.ダウンロードした中身を適当なフォルダにつっこんで、そのフォルダをアプリにD&Dしてください

3.RetweetData.htmlが吐き出されるので開くとリンク一覧が出ます。

f:id:shirakamisauto:20170828154700j:plain

一部の文が途切れてるのは元データの仕様です。

コード

using System;
using System.IO;
using System.Collections.Generic;
using Microsoft.VisualBasic.FileIO;

namespace TweetDataExtractor
{
    class Program
    {
        static void Main(string[] args)
        {
            var path = args[0] + @"\tweets.csv";

            using (var parser = new TextFieldParser(path))
            {
                parser.TextFieldType = FieldType.Delimited;
                parser.SetDelimiters(",");

                var urlList = new List<Tuple<string, string>>();

                //一行目読み飛ばし
                parser.ReadFields();

                while (!parser.EndOfData)
                {
                    var row = parser.ReadFields();
                    //リツイートならば
                    if (row[6] != string.Empty)
                    {
                        //本文の取得
                        var nameAndText = row[5].Replace("RT @", "");

                        //ツイートURLの生成
                        string userName = nameAndText.Split(':')[0];
                        var twId = row[0];
                        string twUrl = "https://twitter.com/" + userName + "/status/" + twId;

                        urlList.Add(Tuple.Create(nameAndText, twUrl));
                    }
                }

                //HTMLを作って吐く
                using (var sw = new StreamWriter(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + @"\RetweetData.html"))
                {
                    sw.WriteLine("<html lang=\"ja\">");
                    sw.WriteLine("<body>");

                    foreach (var data in urlList)
                        sw.WriteLine("<a href = \"" + data.Item2 + "\" >" + data.Item1 + "</a ></br>");

                    sw.WriteLine("</body>");
                    sw.WriteLine("</html>");
                }
            }
        }
    }
}

【C#】return式1行だけしかないメソッドの省略記法

1行しかない関数に{}使うのはなんかヤダ。

//掛け算
static int Multiply(int x, int y)
{
    return x * y;
}

expression-bodied関数を使おう。
C#6.0から導入されたらしい。
ufcpp.net

static int Multiply(int x, int y) => x * y;

こうなる。1行でスッキリ。

例:

class Sample
{
    //掛け算
    static int Multiply(int x, int y) => x * y;

    static void Main(string[] args)
    {
        int n = Multiply(2, 5);
    }    
}

f:id:shirakamisauto:20170826145126j:plain

【C#】怪盗paizaからの挑戦状の解答

paiza.jp
解答のせていいとのことなので。
最短経路じゃないです。
なんか有名なアルゴリズムとか使うのかな?
Tupleが使えて満足。

using System;
using System.Collections.Generic;
   class Program
    {
        static void Main(string[] args)
        {
            var line = Console.ReadLine();
            int N = int.Parse(line);

            var xyList = new List<Tuple<double, double>>();
            //座標リストの入力と生成
            for (int i = 0; i < N; i++)
            {
                var data = Console.ReadLine().Split(' ');
                double x = double.Parse(data[0]);
                double y = double.Parse(data[1]);
                xyList.Add(Tuple.Create(x, y));
            }
            

            var originPoint = Tuple.Create(0.0, 0.0);
            var minRoot = new List<Tuple<double, double>>();
            minRoot.Add(originPoint);
            var minPoint = originPoint;

            while (xyList.Count > 0)
            {
                double minDist2point = double.MaxValue;
                var tempMinPoint = Tuple.Create(0.0, 0.0);
                //現在の点からの最短距離点算出
                foreach (var point in xyList)
                {
                    var tempMinDist = TwoPointDistance(minPoint, point);
                    if (tempMinDist < minDist2point)
                    {
                        tempMinPoint = point;
                        minDist2point = tempMinDist;
                    }
                }
                //決定した最短距離ポイントを除外
                xyList.Remove(tempMinPoint);

                //現在の点更新
                minPoint = tempMinPoint;

                //ルート更新
                minRoot.Add(minPoint);
            }

            minRoot.Remove(originPoint);
            minRoot.ForEach(s => Console.WriteLine(s.Item1+" "+s.Item2));

        }
        //2点間の距離公式
        static double TwoPointDistance(Tuple<double, double> t1, Tuple<double, double> t2)
        {
            return Math.Sqrt(Math.Pow(t2.Item1 - t1.Item1, 2.0) + Math.Pow(t2.Item2 - t1.Item2, 2.0));
        }
        
    }

・結果
paiza.jp


・説明
始点Oからスタートして全ポイントの距離の中で距離が最短になるポイントPを選ぶ
→PからOとP以外の全ポイントの距離の中で距離が最短になるポイントP2を選ぶ
→以下繰り返し

一番近い地点を次々結んでいくだけなので、「遠回りっぽいけど全体としては近い」みたいなルートだと最短にならないと思われ。

NHKスペシャル「AIに聞いてみた」の問題点

www.nhk.or.jp
マツコデラックス司会のNHKスペシャル「AIに聞いてみた どうすんのよニッポン!?」の問題点についてまとめます。(多分誰かが書くとは思いますが→書いている方がいたので追記)
www.mm-lab.jp


大まかな問題点は3つ。*1
①そもそもAIなのか?
②解析データに偏りがあるのでは?
③相関関係と因果関係についての説明が不十分


目次

①そもそもAIなのか?

社会問題解決型AIと銘打っていますが、やっていることはビッグデータ解析のようです。
であれば番組のAIはAIと呼べないのではという疑問があります。
ただし、AIといっても2種類あるようです。
人工知能学会の説明によれば、人間の知能を再現する強いAIと、知能の一部を再現する弱いAIの2つです。
一般的に想像するAIは映画や漫画でおなじみの自律するAI(強いAI)でしょう。
今回のAIはそちらではなく、限定的な「弱いAI」と考えれば、AIと呼ぶことは正しいと言えます。
なお、囲碁や将棋で名人を負かしたのも「弱いAI」に該当します。
さらに言えば、データを学習させる際に、機械学習ディープラーニングなどAIに関する技術を使っていますから、「ビッグデータ解析用のAI」と言ったほうが正確かもしれません。

②結果に偏りがあるのでは?

使用した統計データやプログラムの仕様により、結果が偏ったものになっている可能性があります。

データの問題

番組ホームページによれば、学習させたデータは700万に及びます。*2
数が多いのはよいことですが、それとは別に問題があります。
学習させたデータを選定したのは人間です。
そのため、どうしてもそこに選んだ人間の意思が反映されてしまい、偏った結果になる可能性があります。
ただし今後データを追加する予定はあるそうなので、ある程度は改善されるかもしれません。

それともう一つ、これはどうしようもない問題ですが、統計を取ってないデータは入っていません。
もし、ある社会問題に未知のデータが関わっていた場合、正しい関連性を見逃す恐れはあります。

プログラムの問題

AIプログラムはあまり詳しくないのですが、人が作ったものである以上、データの処理方法に製作者の意思が入ります。
統計データが信頼できても、処理の際にバイアスが入ってしまえば正しい出力にならない可能性があります。
本当に公共政策に利用する場合、ソースコードを公開し、専門家に検証してもらうのも一考でしょう。

それとは別に、ディープラーニングなどの技術には、プログラム作成者にすら処理過程が分からなくなるブラックボックス性があります。
そうなると出力された結果が本当に正しいのか誰にも分かりません。
ただし、処理過程が分かるような処理を入れていれば、ある程度は検証できると思います。
ソースコードが公開されてないので何とも言えませんが。*3

③相関関係と因果関係についての説明が不十分

番組の最大の問題点はこれでしょう。
番組中でも番組ホームページでも、「このAIは因果関係を提示しない」と明言しています。
AIが示すのは相関関係であって、因果関係ではありません。
相関関係と因果関係は同じものではありません。

相関関係はある2つの物事に関係があることを示します。
例:殺人件数が減少した年に、高齢化率が上昇した
これだけ見ると、「殺人事件が減ったので、高齢化率が上昇した」と因果関係を考えがちです。
しかしこれは逆に「高齢化率が上昇したので、殺人事件が減った」とも考えられます。
また、互いの出来事は無関係で、「監視カメラが増えたので殺人事件が減った」と「少子化なので高齢化率が上昇した」が複合していただけかもしれません。
つまり、相関関係があるからと言って、因果関係があるとは限らないのです。

ところが、番組内ではそのあたりの説明が不十分だったように思えます。
相関関係とはどういうものか、ということを一度説明しておくべきではなかったでしょうか。
(ただし、合間合間に「他の要因があるかもしれない」などとは言っていましたし、ホームページでは、「明らかに相関のないものがつながることもあります。」と書いてはあります)
おそらく、相関関係についての説明がややこしいため避けたのでしょうが、この前のNHKEテレ「オイコノミア」では、ちゃんと説明してたことを考えると、納得できない面があります。

とはいえ、ホームページには

AIは、残念ながら因果関係は提示してくれません。このネットワーク構造を人間が読み解き議論することで、社会問題の背景を考え、解決の糸口を探ろうというのが番組の趣旨です。番組で紹介した"AIの提言"は、このような形で、AIが出してきた分析結果を人間が読み解き平易な言葉で表したものです。

とあります。
データ処理によって出力された関係性を議論・考察していこう、というのが趣旨のようですから、相関と因果の誤謬はとりあえず無視しているのかもしれません。
それでも教授陣には説明していただきたかったですが。

感想

現時点でいろいろな問題が指摘できますが、個人的には番組のアプローチは一定の意味があると思います。
社会問題は様々な要因が複雑に絡み合っており、視野の限られる人間では原因が何かを突き止めることが難しいです。
プログラムが総当たりすることによって、これまで想像できなかった関連性が見つかれば、新たな解決策が生まれるかもしれません。
もちろん、無関係な関連性に振り回されることもありますし、過信は禁物です。
しかし、人間が完璧でない以上、AIプログラムの無駄もある程度許容してもいいと思います。
暗中模索の中、打てる手は多いほうがいいでしょう。

*1:もう一つ、提言の見出しが釣りっぽいという問題はありますが、たぶん覚悟の上でやってると思うので指摘しません。

*2:一覧はホームページの一番下にあります

*3:仮に公開されてもたぶん読めないけど