PDA

View Full Version : درخواست راهنمایی جهت انجام سری داده ها در C++



forogh68
چهارشنبه 29 مهر 1394, 19:56 عصر
سلام دوستان. وقت بخیر.
دوستان در درس داده کاوی یک سری داده دارم که با نرم افزارهایی مثل وکا باید روی اون کار کنم!
خب این سری داده هایی که گذاشتم اسپم sms هست و من باید بتونم اسپم و غیر اسپم بودن این جملاتی که در این دادها هست رو بیرون بیارم! خودم تصمیم گرفتم با زبان C++‎‎‎‎‎‎‎‎‎‎‎‎ اون رو انجام بدم! حالا احتیاج به کمک دارم! میشه کمی راهنمایی بفرمایید:

این داده ها رو دانلود کنید و با نوت پد ++ یا وردپد یا نوت پد ویندوز اون رو باز کنید. هر سطر نشون دهنده یک پیام هست که ماباید بگیم این سطر اسپم هست یا خیر؟
http://s3.picofile.com/file/8218462000/smsSpamCollection.arff.html


استنباط من از موضوع به ان شکل هست که بازم اگر دوستان چیزی به نظرشون می رسه ممنون میشم کمک کنند:
1 - استخراج کلمات
ابتدا تک تک ایمیل ها رو در هر قالبی که هست(مثلا .txt) باید از ورودی بخونید و تک تک کلمات اون رو استخراج کنید.مثلا اگر داخل یکی از فایل ها جمله if you would prefer to stay in a hotel , we recommend the arcade hotel وجود داشت باید تک تک کلمات و تعداد دفعات تکرارش رو استخراج کنید که می تونید به هر صورتی(در داخل پایگاه داده، استفاده از ساختار درختی، آرایه یا ...) ذخیره کنید.یعنی داریم

http://s3.picofile.com/file/8218463350/%D9%84%DB%8C%D8%B3%D9%84%D8%B5%D9%8256.PNG

تا این مرحله هر ایمیل تبدیل به برداری از کلمات میشه(مجموعه train و test) که به عنوان ویژگی(feature) شناخته میشن

۳-۲-حذف stop-words
کلماتی که مربوط مفهوم ایمیل نیستن و در همه ایمیل ها تکرار میشن، باید حذف بشن. مثل if.

نمی دونم چقدر درست باشه این کارم! اگر کسی چیزی می تونه بهم کمک کنه!
با تشکر

forogh68
جمعه 01 آبان 1394, 22:51 عصر
سلام دوستان. بهتره سوالم رو اینطور مطرح کنم:

من 6 هزار خط جمله دارم و می خوام برنامه ای بنویسم که بیاد و هر خط رو بررسی کنه و تک تک کلمات اون رو استخراج کنه! بعد هم بگه هر کدوم از کلمات چند بار تکرار شده است! به نظرتون با سی ++ میشه اینکار رو کرد یا راه حل بهتری دارید؟

Ananas
شنبه 02 آبان 1394, 00:16 صبح
سلام. اگر فرض کنیم کلمات با space از هم جدا شده باشن به راحتی میتونید کلمه به کلمه بخونید و در لیستی اضافه کنید.
من یک کلاس Kalame براتون نوشتم که لیستی از این کلاس میتونید بسازید موقع خوندن.

class Kalame
{
public:
Kalame()
{
p_str = NULL;
count = 0;
};
bool CheckStr(const char * p_str)
{
if (__p_Str == NULL) return false;
int i = 0;
while (p_str[i] == __p_Str[i])
{
if (__p_Str[i] == (char)0)
{
__Count++;
return true;
};
i++;
};
return false;
};
char * __p_Str;
int __Count;
};

وقتی کلملت رو دارید میگردید پیدا کنید هر کلمه ای که پیدا کردید باید یک حلقه به تعداد طول لیست طی کنید و تابع CheckStr رو برای هر آیتم لیست فراخونی کنید و اگر تابع مقدار false رو برگردونه ملومه اون کلمه مساوی نیست و اگر در کل لیست وجود نداشت ، به لیست اضافه میکنید. تابع CheckStr اگر مقدار true رو برگردونه یک واحد به Count اون شی Kalame اضافه میکنه. از اون جا میتونید تعداد تکرار ها رو متوجه بشید. در حالت شروع Count برابر با 0 هست و مقدار p_Str رو هم باید دستی بهش بدید. و هر بار تکرار مقدار Count رو افزایش میده. میتونید در صورت نیاز این کلاس رو تغییر بدید و بهتر بنویسید.

Ananas
یک شنبه 03 آبان 1394, 02:36 صبح
#include <vector>
#include <iostream.h>
using namespace std;

typedef char MY_CHAR;

int MyStrLen(const MY_CHAR * p_str)
{
int i = 0;
while (p_str[i] != (MY_CHAR)0)
i++;
return i;
};

class Kalame
{
private:
MY_CHAR * __p_Str;
int __Count;
public:
Kalame(const MY_CHAR * p_str)
{
this->__p_Str = NULL;

size_t SizeOfData = sizeof(MY_CHAR) * (MyStrLen(p_str) + 1);
this->__p_Str = (MY_CHAR *)malloc(SizeOfData);
memcpy(
(void *)this->__p_Str,
(void *)p_str,
SizeOfData);
this->__Count = 0;
};
~Kalame()
{
free(this->__p_Str);
this->__p_Str = NULL;
};
bool CheckStr(const MY_CHAR * p_str)
{
if (__p_Str == NULL) return false;
int i = 0;
while (p_str[i] == __p_Str[i])
{
if (__p_Str[i] == (MY_CHAR)0)
{
__Count++;
return true;
};
i++;
};
return false;
};
const MY_CHAR * GetStr() { return this->__p_Str; };
int Count() { return this->__Count + 1; };
};

class MultiKalame
{
public:
vector< Kalame * > vec_kal;
~MultiKalame()
{
int count = (int)vec_kal.size();
for (int i = 0; i < count; i++)
{
if (vec_kal[i] != NULL)
{
delete vec_kal[i];
vec_kal[i] = NULL;
};
};
vec_kal.clear();
};
};

int GenerateKalame(const MY_CHAR * p_str, MultiKalame * p_mulkal)
{
int str_length = MyStrLen(p_str);
MY_CHAR * kalame_str = (MY_CHAR *)malloc(sizeof(MY_CHAR) * (str_length + 1));
int i = 0;
int j = 0;

while (i <= str_length)
{
if (
(p_str[i] == (MY_CHAR)32) ||
(p_str[i] == (MY_CHAR)13) ||
(p_str[i] == (MY_CHAR)10) ||
(p_str[i] == (MY_CHAR)0)
)
{
if (j > 0)
{

kalame_str[j] = (MY_CHAR)0;

int count = (int)p_mulkal->vec_kal.size();
int finded = false;
for (int k = 0; k < count; k++)
{
if (p_mulkal->vec_kal[k]->CheckStr(kalame_str))
{
finded = true;
break;
};
};
if (!finded)
{
Kalame * p_kal = new Kalame(kalame_str);
p_mulkal->vec_kal.push_back(p_kal);
};

j = 0;
};
}
else
{
kalame_str[j] = p_str[i];
j++;
};
i++;
};
free(kalame_str);
return (int)p_mulkal->vec_kal.size();
};


int main()
{
char * p_str = " mohammad qadiany m qadiany \n\n mohammad mohammadmohammad qadiany mohammad Qadiany 1394 test.";

MultiKalame * p_mulkal = new MultiKalame();

int count = GenerateKalame(p_str, p_mulkal);
//cout << "Word Count:" << count << endl;

for (int i = 0; i < count; i++)
{
Kalame * p_kal = p_mulkal->vec_kal[i];
cout << p_kal->Count() << " x "
<< p_kal->GetStr() << endl;
};

delete p_mulkal;

getchar();
getchar();
return 0;
}

این برنامه درست کار میکنه تست کردم. از این توابع و کلاس ها استفاده کنید. و به احتمال زیاد متن شما باید Unicode باشه (زبان غیر از انگلیسی هم توش باشه. مثل فارسی). اگر اینطوره تو متن برنامه ی اصلی باید typedef ای که در اول برنامه برای MY_CHAR نوشتم تغییر بدید. یعنی الان هست:
typedef char MY_CHAR;
شما char رو تغییر بدید به wchar_t. یعنی:
typedef wchar_t MY_CHAR;
اگر در حد معمولی C++‎‎‎ بدونید باید بتونید از این توابع استفاده کنید. اگر نتونستید اول برید سراغ آموزش زبان C++‎‎‎.