質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

1回答

4807閲覧

c++での類似度計算について

veiler

総合スコア8

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2016/07/22 04:59

プログラミングc++言語での質問です。
類似度計算のプログラムなのですが、教えていただける方、よろしくお願いします。実装するのはsimilarity.cppの中の「記述」と書いてある部分です。

<内容>
similarity.cpp のmk_tfidf_list関数は、引数として指定した記事IDに含まれる名詞のTF・IDF値をリストにして返す関数です。→ 「TF・IDF計算」の課題(*)のプログラムを改良し、計算結果をリストにして返すようにして下さい。
単語ベクトルの生成で、記事に出現していない単語は0として生成となっていますが、実際の類似度計算においては、内積(分子)もノルム(分母)の計算においても「0」を考慮する必要はありません。

similarity.cpp
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string.h>
#include <math.h>

#define N 227

using namespace std;

struct cell
{
string key;
int value;
double tfidf;

struct cell *next;
};

using namespace std;

// 機能:引数として指定した記事IDに含まれる名詞のTF・IDF値をリストにして返す
// 備考:TF・IDF計算プログラムを関数にしたもの
struct cell *mk_tfidf_list(string input_id)
{
// TF・IDF計算プログラムを記述

return NULL;
}

int main(int argc, char *argv[])
{
string id1 = argv[1];
string id2 = argv[2];

// 指定した記事ID1のTF・IDFリスト
struct cell *tf_idf1;
tf_idf1 = mk_tfidf_list(id1);

// 指定した記事ID1のTF・IDFリスト
struct cell *tf_idf2;
tf_idf2 = mk_tfidf_list(id2);

double sim = 0;

// 類似度計算のコードを記述
cout << id1 << " - " << id2 << " : " << sim << endl;
}

(*)参考にするTF・IDF計算のプログラム
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <fstream>

#define N 227

using namespace std;

struct cell{ //tf
int num;
string data;
cell *next;
};

struct cell *make_cell(int num, string data){
struct cell *mk_cell;
mk_cell = new struct cell;
mk_cell->data = data;
mk_cell->num = num;
mk_cell->next = NULL;

return mk_cell;
}

struct cell *search_cell(string data,cell *head){
struct cell *buf;
buf= head;

while(buf != NULL){
if(buf->data == data){
return buf;
}
buf = buf->next;
}

return NULL;
}

void print_cell(cell *head){
cell *buf;
buf = head;

while(buf != NULL){
cout << buf->data << ":" << buf->num << endl;
buf = buf->next;
}
}

int main(int argc, char *argv[]){
int size = 0;

string input_id1 = argv[1]; // 指定したファイルIDを取得

ifstream f_data("posdata.txt"); // posdata.txt ファイルオープン

string line;

cell *head;
head = NULL;

// postdata.txtから1行ずつ読み込み
while(f_data >> line){
// 記事IDと名詞例(noun1, noun2,...)のデータに分割
int index = line.find(",");
string f_id = line.substr(0,index);
string w_str = line.substr(index+1);

if(f_id == input_id1){
// split 名詞列のデータから名詞を1つずつ取り出し
int n;
for(int i=0; i <= w_str.length(); i=n+1 ){
n = w_str.find_first_of(",", i);
if( n == string::npos ) {
n = w_str.length();
}

string word = w_str.substr(i, n-i ); //単語

if(search_cell(word,head) == NULL){ //単語がなかった場合
struct cell *tmp;
tmp = make_cell(1,word);
tmp->next = head;
head = tmp;
size++;
}else if (search_cell(word,head) != NULL){
cell *tmp2;
tmp2 = search_cell(word,head);
tmp2->num++;
}
}
}
}

ifstream fin("df.txt");
string line2;
cell *head2;
head2 = NULL;

while(fin >> line2){
int index = line2.find(",");
string f_id2 = line2.substr(0,index);
string w_str2 = line2.substr(index+1);

int num2 = atoi(w_str2.data());
cell *tmp2 = make_cell(num2,f_id2);
tmp2->next = head2;
head2 = tmp2;
}

cell *buf = head;
while(buf!=NULL){
double tfidf = 0;
double df = 0;
cell *buf2 = head2;
cell tmp = search_cell(buf->data,head2);
if(tmp != NULL){
tfidf = buf->num * log2(N
1.0/tmp->num);
cout << input_id1 << "->" << buf->data << ":" << tfidf << endl;
}
buf = buf->next;
}
f_data.close();

return 0;
}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

それだけ材料があって、なにがわからんのですか?

投稿2016/07/22 07:01

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問